Add option to disallow modref function calls in scops.
authorTobias Grosser <tobias@grosser.es>
Wed, 23 Mar 2016 06:40:15 +0000 (06:40 +0000)
committerTobias Grosser <tobias@grosser.es>
Wed, 23 Mar 2016 06:40:15 +0000 (06:40 +0000)
This might be useful to evaluate the benefit of us handling modref funciton
calls. Also, a new bug that was triggered by modref function calls was
recently reported http://llvm.org/PR27035. To ensure the same issue does not
cause troubles for other people, we temporarily disable this until the bug
is resolved.

llvm-svn: 264140

polly/lib/Analysis/ScopDetection.cpp
polly/test/ScopDetect/mod_ref_read_pointer.ll
polly/test/ScopInfo/mod_ref_access_pointee_arguments.ll
polly/test/ScopInfo/mod_ref_read_pointee_arguments.ll
polly/test/ScopInfo/mod_ref_read_pointer.ll
polly/test/ScopInfo/mod_ref_read_pointers.ll
polly/test/ScopInfo/multidim_2d_with_modref_call.ll
polly/test/ScopInfo/multidim_2d_with_modref_call_2.ll
polly/test/ScopInfo/multidim_fortran_2d_with_modref_call.ll

index 548b874..024f87e 100644 (file)
@@ -132,6 +132,12 @@ static cl::opt<bool>
                    cl::Hidden, cl::init(false), cl::ZeroOrMore,
                    cl::cat(PollyCategory));
 
+static cl::opt<bool>
+    AllowModrefCall("polly-allow-modref-calls",
+                    cl::desc("Allow functions with known modref behavior"),
+                    cl::Hidden, cl::init(false), cl::ZeroOrMore,
+                    cl::cat(PollyCategory));
+
 static cl::opt<bool> AllowNonAffineSubRegions(
     "polly-allow-nonaffine-branches",
     cl::desc("Allow non affine conditions for branches"), cl::Hidden,
@@ -470,39 +476,41 @@ bool ScopDetection::isValidCallInst(CallInst &CI,
   if (CalledFunction == 0)
     return false;
 
-  switch (AA->getModRefBehavior(CalledFunction)) {
-  case llvm::FMRB_UnknownModRefBehavior:
-    return false;
-  case llvm::FMRB_DoesNotAccessMemory:
-  case llvm::FMRB_OnlyReadsMemory:
-    // Implicitly disable delinearization since we have an unknown
-    // accesses with an unknown access function.
-    Context.HasUnknownAccess = true;
-    Context.AST.add(&CI);
-    return true;
-  case llvm::FMRB_OnlyReadsArgumentPointees:
-  case llvm::FMRB_OnlyAccessesArgumentPointees:
-    for (const auto &Arg : CI.arg_operands()) {
-      if (!Arg->getType()->isPointerTy())
-        continue;
-
-      // Bail if a pointer argument has a base address not known to
-      // ScalarEvolution. Note that a zero pointer is acceptable.
-      auto *ArgSCEV = SE->getSCEVAtScope(Arg, LI->getLoopFor(CI.getParent()));
-      if (ArgSCEV->isZero())
-        continue;
-
-      auto *BP = dyn_cast<SCEVUnknown>(SE->getPointerBase(ArgSCEV));
-      if (!BP)
-        return false;
-
+  if (AllowModrefCall) {
+    switch (AA->getModRefBehavior(CalledFunction)) {
+    case llvm::FMRB_UnknownModRefBehavior:
+      return false;
+    case llvm::FMRB_DoesNotAccessMemory:
+    case llvm::FMRB_OnlyReadsMemory:
       // Implicitly disable delinearization since we have an unknown
       // accesses with an unknown access function.
       Context.HasUnknownAccess = true;
-    }
+      Context.AST.add(&CI);
+      return true;
+    case llvm::FMRB_OnlyReadsArgumentPointees:
+    case llvm::FMRB_OnlyAccessesArgumentPointees:
+      for (const auto &Arg : CI.arg_operands()) {
+        if (!Arg->getType()->isPointerTy())
+          continue;
+
+        // Bail if a pointer argument has a base address not known to
+        // ScalarEvolution. Note that a zero pointer is acceptable.
+        auto *ArgSCEV = SE->getSCEVAtScope(Arg, LI->getLoopFor(CI.getParent()));
+        if (ArgSCEV->isZero())
+          continue;
+
+        auto *BP = dyn_cast<SCEVUnknown>(SE->getPointerBase(ArgSCEV));
+        if (!BP)
+          return false;
 
-    Context.AST.add(&CI);
-    return true;
+        // Implicitly disable delinearization since we have an unknown
+        // accesses with an unknown access function.
+        Context.HasUnknownAccess = true;
+      }
+
+      Context.AST.add(&CI);
+      return true;
+    }
   }
 
   return false;
index 62121db..bdb38ea 100644 (file)
@@ -1,6 +1,10 @@
-; RUN: opt %loadPolly -basicaa -polly-detect -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -basicaa -polly-detect -analyze \
+; RUN:  -polly-allow-modref-calls < %s | FileCheck %s -check-prefix=MODREF
+; RUN: opt %loadPolly -basicaa -polly-detect -analyze \
+; RUN:  < %s | FileCheck %s
 ;
-; CHECK: Valid Region for Scop: for.cond => for.end
+; CHECK-NOT: Valid Region for Scop: for.cond => for.end
+; MODREF: Valid Region for Scop: for.cond => for.end
 ;
 ;    #pragma readonly
 ;    int func(int *A);
index de206fb..927c4e5 100644 (file)
@@ -1,5 +1,7 @@
-; RUN: opt %loadPolly -basicaa -polly-scops -analyze < %s | FileCheck %s
-; RUN: opt %loadPolly -basicaa -polly-codegen -disable-output < %s
+; RUN: opt %loadPolly -basicaa -polly-scops -analyze -polly-allow-modref-calls \
+; RUN:  < %s | FileCheck %s
+; RUN: opt %loadPolly -basicaa -polly-codegen -polly-allow-modref-calls \
+; RUN: -disable-output < %s
 ;
 ; Verify that we model the may-write access of the prefetch intrinsic
 ; correctly, thus that A is accessed by it but B is not.
index a5da01e..c153846 100644 (file)
@@ -1,5 +1,7 @@
-; RUN: opt %loadPolly -basicaa -polly-scops -analyze < %s | FileCheck %s
-; RUN: opt %loadPolly -basicaa -polly-codegen -disable-output < %s
+; RUN: opt %loadPolly -basicaa -polly-scops -analyze -polly-allow-modref-calls \
+; RUN: < %s | FileCheck %s
+; RUN: opt %loadPolly -basicaa -polly-codegen -disable-output \
+; RUN: -polly-allow-modref-calls < %s
 ;
 ; Verify that we model the read access of the gcread intrinsic
 ; correctly, thus that A is read by it but B is not.
index fd52c9d..deb5c7c 100644 (file)
@@ -1,5 +1,7 @@
-; RUN: opt %loadPolly -basicaa -polly-scops -analyze < %s | FileCheck %s
-; RUN: opt %loadPolly -basicaa -polly-codegen -disable-output < %s
+; RUN: opt %loadPolly -basicaa -polly-scops -analyze -polly-allow-modref-calls \
+; RUN:  < %s | FileCheck %s
+; RUN: opt %loadPolly -basicaa -polly-codegen -disable-output \
+; RUN: -polly-allow-modref-calls < %s
 ;
 ; Check that we assume the call to func has a read on the whole A array.
 ;
index a06123c..2039c75 100644 (file)
@@ -1,5 +1,7 @@
-; RUN: opt %loadPolly -basicaa -polly-scops -analyze < %s | FileCheck %s
-; RUN: opt %loadPolly -basicaa -polly-codegen -disable-output < %s
+; RUN: opt %loadPolly -basicaa -polly-scops -analyze -polly-allow-modref-calls \
+; RUN: < %s | FileCheck %s
+; RUN: opt %loadPolly -basicaa -polly-codegen -disable-output \
+; RUN: -polly-allow-modref-calls < %s
 ;
 ; Check that the call to func will "read" not only the A array but also the
 ; B array. The reason is the readonly annotation of func.
index 56a2c25..d8b720d 100644 (file)
@@ -1,5 +1,7 @@
-; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s
-; RUN: opt %loadPolly -polly-scops -polly-allow-nonaffine -analyze < %s | FileCheck %s --check-prefix=NONAFFINE
+; RUN: opt %loadPolly -polly-scops -analyze -polly-allow-modref-calls \
+; RUN: < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-scops -polly-allow-nonaffine -analyze \
+; RUN: -polly-allow-modref-calls < %s | FileCheck %s --check-prefix=NONAFFINE
 
 ;  TODO: We should delinearize the accesses despite the use in a call to a
 ;        readonly function. For now we verify we do not delinearize them though.
index 911ae16..133de69 100644 (file)
@@ -1,5 +1,7 @@
-; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s
-; RUN: opt %loadPolly -polly-scops -polly-allow-nonaffine -analyze < %s | FileCheck %s --check-prefix=NONAFFINE
+; RUN: opt %loadPolly -polly-scops -analyze -polly-allow-modref-calls \
+; RUN: < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-scops -polly-allow-nonaffine \
+; RUN: -polly-allow-modref-calls -analyze < %s | FileCheck %s --check-prefix=NONAFFINE
 
 ;  TODO: We should delinearize the accesses despite the use in a call to a
 ;        readonly function. For now we verify we do not delinearize them though.
index ab1c586..7e87427 100644 (file)
@@ -1,5 +1,7 @@
-; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s
-; RUN: opt %loadPolly -polly-scops -polly-allow-nonaffine -analyze < %s | FileCheck %s --check-prefix=NONAFFINE
+; RUN: opt %loadPolly -polly-scops -analyze -polly-allow-modref-calls \
+; RUN:  < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-scops -polly-allow-nonaffine -analyze \
+; RUN: -polly-allow-modref-calls < %s | FileCheck %s --check-prefix=NONAFFINE
 
 ;  TODO: We should delinearize the accesses despite the use in a call to a
 ;        readonly function. For now we verify we do not delinearize them though.