[llvm] r274197 - [CFLAA] Add support for ModRef queries.

George Burgess IV via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 29 19:11:27 PDT 2016


Author: gbiv
Date: Wed Jun 29 21:11:26 2016
New Revision: 274197

URL: http://llvm.org/viewvc/llvm-project?rev=274197&view=rev
Log:
[CFLAA] Add support for ModRef queries.

This patch makes CFLAA answer some ModRef queries. Because we don't
distinguish between reading/writing when making StratifiedSets, we're
unable to offer any of the readonly-related answers.

Patch by Jia Chen.

Differential Revision: http://reviews.llvm.org/D21858

Modified:
    llvm/trunk/include/llvm/Analysis/CFLAliasAnalysis.h
    llvm/trunk/lib/Analysis/CFLAliasAnalysis.cpp
    llvm/trunk/test/Analysis/CFLAliasAnalysis/interproc-ret-arg.ll

Modified: llvm/trunk/include/llvm/Analysis/CFLAliasAnalysis.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/CFLAliasAnalysis.h?rev=274197&r1=274196&r2=274197&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/CFLAliasAnalysis.h (original)
+++ llvm/trunk/include/llvm/Analysis/CFLAliasAnalysis.h Wed Jun 29 21:11:26 2016
@@ -73,6 +73,16 @@ public:
     return QueryResult;
   }
 
+  /// Get the location associated with a pointer argument of a callsite.
+  ModRefInfo getArgModRefInfo(ImmutableCallSite CS, unsigned ArgIdx);
+
+  /// Returns the behavior when calling the given call site.
+  FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS);
+
+  /// Returns the behavior when calling the given function. For use when the
+  /// call site is not known.
+  FunctionModRefBehavior getModRefBehavior(const Function *F);
+
 private:
   struct FunctionHandle final : public CallbackVH {
     FunctionHandle(Function *Fn, CFLAAResult *Result)

Modified: llvm/trunk/lib/Analysis/CFLAliasAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/CFLAliasAnalysis.cpp?rev=274197&r1=274196&r2=274197&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/CFLAliasAnalysis.cpp (original)
+++ llvm/trunk/lib/Analysis/CFLAliasAnalysis.cpp Wed Jun 29 21:11:26 2016
@@ -1047,6 +1047,77 @@ AliasResult CFLAAResult::query(const Mem
   return NoAlias;
 }
 
+ModRefInfo CFLAAResult::getArgModRefInfo(ImmutableCallSite CS,
+                                         unsigned ArgIdx) {
+  if (auto CalledFunc = CS.getCalledFunction()) {
+    auto &MaybeInfo = ensureCached(const_cast<Function *>(CalledFunc));
+    if (!MaybeInfo.hasValue())
+      return MRI_ModRef;
+    auto &RetParamAttributes = MaybeInfo->getRetParamAttributes();
+    auto &RetParamRelations = MaybeInfo->getRetParamRelations();
+
+    bool ArgAttributeIsWritten =
+        std::any_of(RetParamAttributes.begin(), RetParamAttributes.end(),
+                    [ArgIdx](const ExternalAttribute &ExtAttr) {
+                      return ExtAttr.IValue.Index == ArgIdx + 1;
+                    });
+    bool ArgIsAccessed =
+        std::any_of(RetParamRelations.begin(), RetParamRelations.end(),
+                    [ArgIdx](const ExternalRelation &ExtRelation) {
+                      return ExtRelation.To.Index == ArgIdx + 1 ||
+                             ExtRelation.From.Index == ArgIdx + 1;
+                    });
+
+    return (!ArgIsAccessed && !ArgAttributeIsWritten) ? MRI_NoModRef
+                                                      : MRI_ModRef;
+  }
+
+  return MRI_ModRef;
+}
+
+FunctionModRefBehavior CFLAAResult::getModRefBehavior(ImmutableCallSite CS) {
+  // If we know the callee, try analyzing it
+  if (auto CalledFunc = CS.getCalledFunction())
+    return getModRefBehavior(CalledFunc);
+
+  // Otherwise, be conservative
+  return FMRB_UnknownModRefBehavior;
+}
+
+FunctionModRefBehavior CFLAAResult::getModRefBehavior(const Function *F) {
+  assert(F != nullptr);
+
+  // TODO: Remove the const_cast
+  auto &MaybeInfo = ensureCached(const_cast<Function *>(F));
+  if (!MaybeInfo.hasValue())
+    return FMRB_UnknownModRefBehavior;
+  auto &RetParamAttributes = MaybeInfo->getRetParamAttributes();
+  auto &RetParamRelations = MaybeInfo->getRetParamRelations();
+
+  // First, if any argument is marked Escpaed, Unknown or Global, anything may
+  // happen to them and thus we can't draw any conclusion.
+  if (!RetParamAttributes.empty())
+    return FMRB_UnknownModRefBehavior;
+
+  // Currently we don't (and can't) distinguish reads from writes in
+  // RetParamRelations. All we can say is whether there may be memory access or
+  // not.
+  if (RetParamRelations.empty())
+    return FMRB_DoesNotAccessMemory;
+
+  // Check if something beyond argmem gets touched.
+  bool AccessArgMemoryOnly =
+      std::all_of(RetParamRelations.begin(), RetParamRelations.end(),
+                  [](const ExternalRelation &ExtRelation) {
+                    // Both DerefLevels has to be 0, since we don't know which
+                    // one is a read and which is a write.
+                    return ExtRelation.From.DerefLevel == 0 &&
+                           ExtRelation.To.DerefLevel == 0;
+                  });
+  return AccessArgMemoryOnly ? FMRB_OnlyAccessesArgumentPointees
+                             : FMRB_UnknownModRefBehavior;
+}
+
 char CFLAA::PassID;
 
 CFLAAResult CFLAA::run(Function &F, AnalysisManager<Function> &AM) {

Modified: llvm/trunk/test/Analysis/CFLAliasAnalysis/interproc-ret-arg.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/CFLAliasAnalysis/interproc-ret-arg.ll?rev=274197&r1=274196&r2=274197&view=diff
==============================================================================
--- llvm/trunk/test/Analysis/CFLAliasAnalysis/interproc-ret-arg.ll (original)
+++ llvm/trunk/test/Analysis/CFLAliasAnalysis/interproc-ret-arg.ll Wed Jun 29 21:11:26 2016
@@ -11,6 +11,8 @@ define i32* @return_arg_callee(i32* %arg
 ; CHECK: NoAlias: i32* %a, i32* %b
 ; CHECK: MayAlias: i32* %a, i32* %c
 ; CHECK: NoAlias: i32* %b, i32* %c
+
+; CHECK: NoModRef: Ptr: i32* %b <-> %c = call i32* @return_arg_callee(i32* %a, i32* %b)
 define void @test_return_arg() {
   %a = alloca i32, align 4
   %b = alloca i32, align 4




More information about the llvm-commits mailing list