diff options
Diffstat (limited to 'polly/lib')
| -rw-r--r-- | polly/lib/Analysis/ScopDetection.cpp | 5 | ||||
| -rw-r--r-- | polly/lib/Analysis/ScopInfo.cpp | 13 | ||||
| -rw-r--r-- | polly/lib/Support/ScopHelper.cpp | 37 |
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; } |

