diff options
| author | Tobias Grosser <tobias@grosser.es> | 2016-03-23 06:40:15 +0000 |
|---|---|---|
| committer | Tobias Grosser <tobias@grosser.es> | 2016-03-23 06:40:15 +0000 |
| commit | 898a6362106a0eae64a30e429ddc0492ebc94951 (patch) | |
| tree | 665e0ce1feabbe39a17fca7b51a522cc33edcb29 | |
| parent | 46c8e3a6143c33f32585ce685311f32224b76ed9 (diff) | |
| download | bcm5719-llvm-898a6362106a0eae64a30e429ddc0492ebc94951.tar.gz bcm5719-llvm-898a6362106a0eae64a30e429ddc0492ebc94951.zip | |
Add option to disallow modref function calls in scops.
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
9 files changed, 71 insertions, 45 deletions
diff --git a/polly/lib/Analysis/ScopDetection.cpp b/polly/lib/Analysis/ScopDetection.cpp index 548b8747c20..024f87e6aa6 100644 --- a/polly/lib/Analysis/ScopDetection.cpp +++ b/polly/lib/Analysis/ScopDetection.cpp @@ -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; diff --git a/polly/test/ScopDetect/mod_ref_read_pointer.ll b/polly/test/ScopDetect/mod_ref_read_pointer.ll index 62121db4cc6..bdb38ea8e18 100644 --- a/polly/test/ScopDetect/mod_ref_read_pointer.ll +++ b/polly/test/ScopDetect/mod_ref_read_pointer.ll @@ -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); diff --git a/polly/test/ScopInfo/mod_ref_access_pointee_arguments.ll b/polly/test/ScopInfo/mod_ref_access_pointee_arguments.ll index de206fb286a..927c4e53323 100644 --- a/polly/test/ScopInfo/mod_ref_access_pointee_arguments.ll +++ b/polly/test/ScopInfo/mod_ref_access_pointee_arguments.ll @@ -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. diff --git a/polly/test/ScopInfo/mod_ref_read_pointee_arguments.ll b/polly/test/ScopInfo/mod_ref_read_pointee_arguments.ll index a5da01e6a52..c153846ca2c 100644 --- a/polly/test/ScopInfo/mod_ref_read_pointee_arguments.ll +++ b/polly/test/ScopInfo/mod_ref_read_pointee_arguments.ll @@ -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. diff --git a/polly/test/ScopInfo/mod_ref_read_pointer.ll b/polly/test/ScopInfo/mod_ref_read_pointer.ll index fd52c9d3e11..deb5c7c100c 100644 --- a/polly/test/ScopInfo/mod_ref_read_pointer.ll +++ b/polly/test/ScopInfo/mod_ref_read_pointer.ll @@ -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. ; diff --git a/polly/test/ScopInfo/mod_ref_read_pointers.ll b/polly/test/ScopInfo/mod_ref_read_pointers.ll index a06123c9d23..2039c75b87f 100644 --- a/polly/test/ScopInfo/mod_ref_read_pointers.ll +++ b/polly/test/ScopInfo/mod_ref_read_pointers.ll @@ -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. diff --git a/polly/test/ScopInfo/multidim_2d_with_modref_call.ll b/polly/test/ScopInfo/multidim_2d_with_modref_call.ll index 56a2c255c06..d8b720da060 100644 --- a/polly/test/ScopInfo/multidim_2d_with_modref_call.ll +++ b/polly/test/ScopInfo/multidim_2d_with_modref_call.ll @@ -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. diff --git a/polly/test/ScopInfo/multidim_2d_with_modref_call_2.ll b/polly/test/ScopInfo/multidim_2d_with_modref_call_2.ll index 911ae16c9f0..133de691628 100644 --- a/polly/test/ScopInfo/multidim_2d_with_modref_call_2.ll +++ b/polly/test/ScopInfo/multidim_2d_with_modref_call_2.ll @@ -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. diff --git a/polly/test/ScopInfo/multidim_fortran_2d_with_modref_call.ll b/polly/test/ScopInfo/multidim_fortran_2d_with_modref_call.ll index ab1c5865794..7e87427b1b4 100644 --- a/polly/test/ScopInfo/multidim_fortran_2d_with_modref_call.ll +++ b/polly/test/ScopInfo/multidim_fortran_2d_with_modref_call.ll @@ -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. |

