diff options
Diffstat (limited to 'llvm/lib/Analysis/BasicAliasAnalysis.cpp')
-rw-r--r-- | llvm/lib/Analysis/BasicAliasAnalysis.cpp | 53 |
1 files changed, 19 insertions, 34 deletions
diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp index 0641342..bb5a23b 100644 --- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp +++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp @@ -747,29 +747,31 @@ static bool isIntrinsicCall(const CallBase *Call, Intrinsic::ID IID) { return II && II->getIntrinsicID() == IID; } -/// Returns the behavior when calling the given call site. -FunctionModRefBehavior BasicAAResult::getModRefBehavior(const CallBase *Call) { - if (Call->doesNotAccessMemory()) - // Can't do better than this. +static FunctionModRefBehavior getModRefBehaviorFromAttrs(AttributeSet Attrs) { + if (Attrs.hasAttribute(Attribute::ReadNone)) return FunctionModRefBehavior::none(); - // If the callsite knows it only reads memory, don't return worse - // than that. ModRefInfo MR = ModRefInfo::ModRef; - if (Call->onlyReadsMemory()) + if (Attrs.hasAttribute(Attribute::ReadOnly)) MR = ModRefInfo::Ref; - else if (Call->onlyWritesMemory()) + else if (Attrs.hasAttribute(Attribute::WriteOnly)) MR = ModRefInfo::Mod; - FunctionModRefBehavior Min(MR); - if (Call->onlyAccessesArgMemory()) - Min = FunctionModRefBehavior::argMemOnly(MR); - else if (Call->onlyAccessesInaccessibleMemory()) - Min = FunctionModRefBehavior::inaccessibleMemOnly(MR); - else if (Call->onlyAccessesInaccessibleMemOrArgMem()) - Min = FunctionModRefBehavior::inaccessibleOrArgMemOnly(MR); + if (Attrs.hasAttribute(Attribute::ArgMemOnly)) + return FunctionModRefBehavior::argMemOnly(MR); + if (Attrs.hasAttribute(Attribute::InaccessibleMemOnly)) + return FunctionModRefBehavior::inaccessibleMemOnly(MR); + if (Attrs.hasAttribute(Attribute::InaccessibleMemOrArgMemOnly)) + return FunctionModRefBehavior::inaccessibleOrArgMemOnly(MR); + return FunctionModRefBehavior(MR); +} + +/// Returns the behavior when calling the given call site. +FunctionModRefBehavior BasicAAResult::getModRefBehavior(const CallBase *Call) { + FunctionModRefBehavior Min = + getModRefBehaviorFromAttrs(Call->getAttributes().getFnAttrs()); - if (const Function *F = Call->getCalledFunction()) { + if (const Function *F = dyn_cast<Function>(Call->getCalledOperand())) { FunctionModRefBehavior FMRB = getBestAAResults().getModRefBehavior(F); // Operand bundles on the call may also read or write memory, in addition // to the behavior of the called function. @@ -786,10 +788,6 @@ FunctionModRefBehavior BasicAAResult::getModRefBehavior(const CallBase *Call) { /// Returns the behavior when calling the given function. For use when the call /// site is not known. FunctionModRefBehavior BasicAAResult::getModRefBehavior(const Function *F) { - // If the function declares it doesn't access memory, we can't do better. - if (F->doesNotAccessMemory()) - return FunctionModRefBehavior::none(); - switch (F->getIntrinsicID()) { case Intrinsic::experimental_guard: case Intrinsic::experimental_deoptimize: @@ -799,20 +797,7 @@ FunctionModRefBehavior BasicAAResult::getModRefBehavior(const Function *F) { FunctionModRefBehavior::inaccessibleMemOnly(ModRefInfo::ModRef); } - // If the function declares it only reads memory, go with that. - ModRefInfo MR = ModRefInfo::ModRef; - if (F->onlyReadsMemory()) - MR = ModRefInfo::Ref; - else if (F->onlyWritesMemory()) - MR = ModRefInfo::Mod; - - if (F->onlyAccessesArgMemory()) - return FunctionModRefBehavior::argMemOnly(MR); - if (F->onlyAccessesInaccessibleMemory()) - return FunctionModRefBehavior::inaccessibleMemOnly(MR); - if (F->onlyAccessesInaccessibleMemOrArgMem()) - return FunctionModRefBehavior::inaccessibleOrArgMemOnly(MR); - return FunctionModRefBehavior(MR); + return getModRefBehaviorFromAttrs(F->getAttributes().getFnAttrs()); } /// Returns true if this is a writeonly (i.e Mod only) parameter. |