diff options
author | Johannes Doerfert <doerfert@cs.uni-saarland.de> | 2015-10-07 20:32:43 +0000 |
---|---|---|
committer | Johannes Doerfert <doerfert@cs.uni-saarland.de> | 2015-10-07 20:32:43 +0000 |
commit | 08d90a3ceeca64bc232666ea342405ab4fcb45e4 (patch) | |
tree | 29da319f20c034339ec6049e75fd6ed27c5d330d /polly/lib/Support/ScopHelper.cpp | |
parent | 284093033f0654cb70e71df0958480d4c1e24dd6 (diff) | |
download | bcm5719-llvm-08d90a3ceeca64bc232666ea342405ab4fcb45e4.tar.gz bcm5719-llvm-08d90a3ceeca64bc232666ea342405ab4fcb45e4.zip |
Treat conditionally executed non-pure calls as errors
This replaces the support for user defined error functions by a
heuristic that tries to determine if a call to a non-pure function
should be considered "an error". If so the block is assumed not to be
executed at runtime. While treating all non-pure function calls as
errors will allow a lot more regions to be analyzed, it will also
cause us to dismiss a lot again due to an infeasible runtime context.
This patch tries to limit that effect. A non-pure function call is
considered an error if it is executed only in conditionally with
regards to a cheap but simple heuristic.
llvm-svn: 249611
Diffstat (limited to 'polly/lib/Support/ScopHelper.cpp')
-rw-r--r-- | polly/lib/Support/ScopHelper.cpp | 37 |
1 files changed, 23 insertions, 14 deletions
diff --git a/polly/lib/Support/ScopHelper.cpp b/polly/lib/Support/ScopHelper.cpp index d2123bd69eb..022f427ecc8 100644 --- a/polly/lib/Support/ScopHelper.cpp +++ b/polly/lib/Support/ScopHelper.cpp @@ -28,11 +28,6 @@ using namespace polly; #define DEBUG_TYPE "polly-scop-helper" -static cl::list<std::string> - ErrorFunctions("polly-error-functions", - cl::desc("A list of error functions"), cl::Hidden, - cl::ZeroOrMore, cl::CommaSeparated, cl::cat(PollyCategory)); - Value *polly::getPointerOperand(Instruction &Inst) { if (LoadInst *load = dyn_cast<LoadInst>(&Inst)) return load->getPointerOperand(); @@ -346,22 +341,36 @@ Value *polly::expandCodeFor(Scop &S, ScalarEvolution &SE, const DataLayout &DL, return Expander.expandCodeFor(E, Ty, IP); } -bool polly::isErrorBlock(BasicBlock &BB) { +bool polly::isErrorBlock(BasicBlock &BB, const Region &R, LoopInfo &LI, + const DominatorTree &DT) { if (isa<UnreachableInst>(BB.getTerminator())) return true; - if (ErrorFunctions.empty()) + if (LI.isLoopHeader(&BB)) + return false; + + if (DT.dominates(&BB, R.getExit())) + return false; + + // FIXME: This is a simple heuristic to determine if the load is executed + // in a conditional. However, we actually would need the control + // condition, i.e., the post dominance frontier. Alternatively we + // could walk up the dominance tree until we find a block that is + // not post dominated by the load and check if it is a conditional + // or a loop header. + auto *DTNode = DT.getNode(&BB); + auto *IDomBB = DTNode->getIDom()->getBlock(); + if (LI.isLoopHeader(IDomBB)) return false; for (Instruction &Inst : BB) - if (CallInst *CI = dyn_cast<CallInst>(&Inst)) - if (Function *F = CI->getCalledFunction()) { - const auto &FnName = F->getName(); - for (const auto &ErrorFn : ErrorFunctions) - if (FnName.equals(ErrorFn)) - return true; - } + if (CallInst *CI = dyn_cast<CallInst>(&Inst)) { + if (!CI->doesNotAccessMemory()) + return true; + if (CI->doesNotReturn()) + return true; + } return false; } |