diff options
-rw-r--r-- | llvm/include/llvm/Transforms/IPO/Attributor.h | 9 | ||||
-rw-r--r-- | llvm/lib/Transforms/IPO/Attributor.cpp | 26 |
2 files changed, 26 insertions, 9 deletions
diff --git a/llvm/include/llvm/Transforms/IPO/Attributor.h b/llvm/include/llvm/Transforms/IPO/Attributor.h index 2cc9b5fedf2..2b7a4a04b08 100644 --- a/llvm/include/llvm/Transforms/IPO/Attributor.h +++ b/llvm/include/llvm/Transforms/IPO/Attributor.h @@ -899,6 +899,15 @@ struct Attributor { const DataLayout &getDataLayout() const { return InfoCache.DL; } private: + /// Check \p Pred on all call sites of \p Fn. + /// + /// This method will evaluate \p Pred on call sites and return + /// true if \p Pred holds in every call sites. However, this is only possible + /// all call sites are known, hence the function has internal linkage. + bool checkForAllCallSites(const function_ref<bool(AbstractCallSite)> &Pred, + const Function &Fn, bool RequireAllCallSites, + const AbstractAttribute *QueryingAA); + /// The private version of getAAFor that allows to omit a querying abstract /// attribute. See also the public getAAFor method. template <typename AAType> diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp index ef6c82c00c8..043780377fc 100644 --- a/llvm/lib/Transforms/IPO/Attributor.cpp +++ b/llvm/lib/Transforms/IPO/Attributor.cpp @@ -4167,19 +4167,26 @@ bool Attributor::checkForAllCallSites( return false; } - if (RequireAllCallSites && !AssociatedFunction->hasLocalLinkage()) { + return checkForAllCallSites(Pred, *AssociatedFunction, RequireAllCallSites, + &QueryingAA); +} + +bool Attributor::checkForAllCallSites( + const function_ref<bool(AbstractCallSite)> &Pred, const Function &Fn, + bool RequireAllCallSites, const AbstractAttribute *QueryingAA) { + if (RequireAllCallSites && !Fn.hasLocalLinkage()) { LLVM_DEBUG( dbgs() - << "[Attributor] Function " << AssociatedFunction->getName() + << "[Attributor] Function " << Fn.getName() << " has no internal linkage, hence not all call sites are known\n"); return false; } - for (const Use &U : AssociatedFunction->uses()) { + for (const Use &U : Fn.uses()) { AbstractCallSite ACS(&U); if (!ACS) { LLVM_DEBUG(dbgs() << "[Attributor] Function " - << AssociatedFunction->getName() + << Fn.getName() << " has non call site use " << *U.get() << " in " << *U.getUser() << "\n"); return false; @@ -4188,15 +4195,16 @@ bool Attributor::checkForAllCallSites( Instruction *I = ACS.getInstruction(); Function *Caller = I->getFunction(); - const auto &LivenessAA = - getAAFor<AAIsDead>(QueryingAA, IRPosition::function(*Caller), + const auto *LivenessAA = + lookupAAFor<AAIsDead>(IRPosition::function(*Caller), QueryingAA, /* TrackDependence */ false); // Skip dead calls. - if (LivenessAA.isAssumedDead(I)) { + if (LivenessAA && LivenessAA->isAssumedDead(I)) { // We actually used liveness information so we have to record a // dependence. - recordDependence(LivenessAA, QueryingAA); + if (QueryingAA) + recordDependence(*LivenessAA, *QueryingAA); continue; } @@ -4207,7 +4215,7 @@ bool Attributor::checkForAllCallSites( continue; LLVM_DEBUG(dbgs() << "[Attributor] User " << EffectiveUse->getUser() << " is an invalid use of " - << AssociatedFunction->getName() << "\n"); + << Fn.getName() << "\n"); return false; } |