summaryrefslogtreecommitdiffstats
path: root/polly/lib/Support/ScopHelper.cpp
diff options
context:
space:
mode:
authorJohannes Doerfert <doerfert@cs.uni-saarland.de>2015-10-07 20:32:43 +0000
committerJohannes Doerfert <doerfert@cs.uni-saarland.de>2015-10-07 20:32:43 +0000
commit08d90a3ceeca64bc232666ea342405ab4fcb45e4 (patch)
tree29da319f20c034339ec6049e75fd6ed27c5d330d /polly/lib/Support/ScopHelper.cpp
parent284093033f0654cb70e71df0958480d4c1e24dd6 (diff)
downloadbcm5719-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.cpp37
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;
}
OpenPOWER on IntegriCloud