summaryrefslogtreecommitdiffstats
path: root/polly/lib
diff options
context:
space:
mode:
Diffstat (limited to 'polly/lib')
-rw-r--r--polly/lib/Analysis/ScopDetection.cpp5
-rw-r--r--polly/lib/Analysis/ScopInfo.cpp13
-rw-r--r--polly/lib/Support/ScopHelper.cpp37
3 files changed, 34 insertions, 21 deletions
diff --git a/polly/lib/Analysis/ScopDetection.cpp b/polly/lib/Analysis/ScopDetection.cpp
index fefdf67e51b..6371a2ec15b 100644
--- a/polly/lib/Analysis/ScopDetection.cpp
+++ b/polly/lib/Analysis/ScopDetection.cpp
@@ -973,7 +973,7 @@ bool ScopDetection::allBlocksValid(DetectionContext &Context) const {
for (BasicBlock *BB : CurRegion.blocks()) {
// Do not check exception blocks as we will never include them in the SCoP.
- if (isErrorBlock(*BB))
+ if (isErrorBlock(*BB, CurRegion, *LI, *DT))
continue;
if (!isValidCFG(*BB, false, Context) && !KeepGoing)
@@ -1096,6 +1096,7 @@ bool ScopDetection::runOnFunction(llvm::Function &F) {
AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
+ DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
Region *TopRegion = RI->getTopLevelRegion();
releaseMemory();
@@ -1171,6 +1172,7 @@ void polly::ScopDetection::verifyAnalysis() const {
void ScopDetection::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<LoopInfoWrapperPass>();
AU.addRequired<ScalarEvolutionWrapperPass>();
+ AU.addRequired<DominatorTreeWrapperPass>();
// We also need AA and RegionInfo when we are verifying analysis.
AU.addRequiredTransitive<AAResultsWrapperPass>();
AU.addRequiredTransitive<RegionInfoPass>();
@@ -1205,6 +1207,7 @@ INITIALIZE_PASS_BEGIN(ScopDetection, "polly-detect",
INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass);
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass);
INITIALIZE_PASS_DEPENDENCY(RegionInfoPass);
+INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass);
INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass);
INITIALIZE_PASS_END(ScopDetection, "polly-detect",
"Polly - Detect static control parts (SCoPs)", false, false)
diff --git a/polly/lib/Analysis/ScopInfo.cpp b/polly/lib/Analysis/ScopInfo.cpp
index 05a5213a9f1..315ef714b3a 100644
--- a/polly/lib/Analysis/ScopInfo.cpp
+++ b/polly/lib/Analysis/ScopInfo.cpp
@@ -1698,11 +1698,12 @@ static inline unsigned getNumBlocksInRegionNode(RegionNode *RN) {
return NumBlocks;
}
-static bool containsErrorBlock(RegionNode *RN) {
+static bool containsErrorBlock(RegionNode *RN, const Region &R, LoopInfo &LI,
+ const DominatorTree &DT) {
if (!RN->isSubRegion())
- return isErrorBlock(*RN->getNodeAs<BasicBlock>());
+ return isErrorBlock(*RN->getNodeAs<BasicBlock>(), R, LI, DT);
for (BasicBlock *BB : RN->getNodeAs<Region>()->blocks())
- if (isErrorBlock(*BB))
+ if (isErrorBlock(*BB, R, LI, DT))
return true;
return false;
}
@@ -1785,7 +1786,7 @@ void Scop::buildDomainsWithBranchConstraints(Region *R) {
// the predecessors and can therefor look at the domain of a error block.
// That allows us to generate the assumptions needed for them not to be
// executed at runtime.
- if (containsErrorBlock(RN))
+ if (containsErrorBlock(RN, getRegion(), LI, DT))
continue;
BasicBlock *BB = getRegionNodeBasicBlock(RN);
@@ -1993,7 +1994,7 @@ void Scop::propagateDomainConstraints(Region *R) {
addLoopBoundsToHeaderDomain(BBLoop);
// Add assumptions for error blocks.
- if (containsErrorBlock(RN)) {
+ if (containsErrorBlock(RN, getRegion(), LI, DT)) {
IsOptimized = true;
isl_set *DomPar = isl_set_params(isl_set_copy(Domain));
addAssumption(isl_set_complement(DomPar));
@@ -2888,7 +2889,7 @@ bool Scop::isIgnored(RegionNode *RN) {
return true;
// Check if error blocks are contained.
- if (containsErrorBlock(RN))
+ if (containsErrorBlock(RN, getRegion(), LI, DT))
return true;
return false;
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