[llvm] 6c6b484 - [BasicAA] Clean up calculation of FMRB from attributes

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 23 03:05:48 PDT 2022


Author: Nikita Popov
Date: 2022-09-23T12:05:35+02:00
New Revision: 6c6b48434ed85841f147c789a96a309e1fff16ae

URL: https://github.com/llvm/llvm-project/commit/6c6b48434ed85841f147c789a96a309e1fff16ae
DIFF: https://github.com/llvm/llvm-project/commit/6c6b48434ed85841f147c789a96a309e1fff16ae.diff

LOG: [BasicAA] Clean up calculation of FMRB from attributes

The current implementation for call sites is pretty convoluted
when you take the underlying implementation of the used APIs
into account. We will query the call site attributes, and then
fall back to the function attributes while taking into account
operand bundles. However, getModRefBehavior() already has it's
own (more accurate) logic for combining call-site FMRB with
function FMRB.

Clean this up by extracting a function that only fetches FMRB
from attributes, which can be directly used in getModRefBehavior()
for functions, and needs to be combined with an operand-bundle
respecting fallback in the call site case.

One caveat (that makes this non-NFC) is that CallBase function
attribute lookups allow using attributes from functions with
mismatching signature. To ensure we don't regress quality, do
the same for the function FMRB fallback.

Added: 
    

Modified: 
    llvm/lib/Analysis/BasicAliasAnalysis.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
index 0641342b1945..bb5a23b8fc6b 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.


        


More information about the llvm-commits mailing list