ScopDetection: Support keep-going

Support a 'keep-going' mode for the ScopDetection. In this mode, we just keep
on detecting, even if we encounter an error.

This is useful for diagnosing SCoP candidates. Sometimes you want all the
errors. Invalid SCoPs will still be refused in the end, we just refuse to
abort on the first error.

llvm-svn: 209574
This commit is contained in:
Andreas Simbuerger 2014-05-24 09:25:10 +00:00
parent 8a00c9bb0f
commit 0447240ee9
2 changed files with 20 additions and 5 deletions

View File

@ -73,6 +73,7 @@ public:
iterator begin() { return ErrorReports.begin(); } iterator begin() { return ErrorReports.begin(); }
iterator end() { return ErrorReports.end(); } iterator end() { return ErrorReports.end(); }
size_t size() { return ErrorReports.size(); }
const Region *region() const { return R; } const Region *region() const { return R; }
void report(RejectReasonPtr Reject) { ErrorReports.push_back(Reject); } void report(RejectReasonPtr Reject) { ErrorReports.push_back(Reject); }

View File

@ -117,6 +117,11 @@ TrackFailures("polly-detect-track-failures",
cl::location(PollyTrackFailures), cl::Hidden, cl::ZeroOrMore, cl::location(PollyTrackFailures), cl::Hidden, cl::ZeroOrMore,
cl::init(false), cl::cat(PollyCategory)); cl::init(false), cl::cat(PollyCategory));
static cl::opt<bool> KeepGoing("polly-detect-keep-going",
cl::desc("Do not fail on the first error."),
cl::Hidden, cl::ZeroOrMore, cl::init(false),
cl::cat(PollyCategory));
static cl::opt<bool, true> static cl::opt<bool, true>
PollyDelinearizeX("polly-delinearize", PollyDelinearizeX("polly-delinearize",
cl::desc("Delinearize array access functions"), cl::desc("Delinearize array access functions"),
@ -589,7 +594,10 @@ void ScopDetection::findScops(Region &R) {
if (!DetectRegionsWithoutLoops && regionWithoutLoops(R, LI)) if (!DetectRegionsWithoutLoops && regionWithoutLoops(R, LI))
return; return;
if (isValidRegion(R)) { bool IsValidRegion = isValidRegion(R);
bool HasErrors = RejectLogs.count(&R) > 0;
if (IsValidRegion && !HasErrors) {
++ValidRegion; ++ValidRegion;
ValidRegions.insert(&R); ValidRegions.insert(&R);
return; return;
@ -598,6 +606,10 @@ void ScopDetection::findScops(Region &R) {
for (auto &SubRegion : R) for (auto &SubRegion : R)
findScops(*SubRegion); findScops(*SubRegion);
// Do not expand when we had errors. Bad things may happen.
if (IsValidRegion && HasErrors)
return;
// Try to expand regions. // Try to expand regions.
// //
// As the region tree normally only contains canonical regions, non canonical // As the region tree normally only contains canonical regions, non canonical
@ -635,17 +647,17 @@ bool ScopDetection::allBlocksValid(DetectionContext &Context) const {
for (const BasicBlock *BB : R.blocks()) { for (const BasicBlock *BB : R.blocks()) {
Loop *L = LI->getLoopFor(BB); Loop *L = LI->getLoopFor(BB);
if (L && L->getHeader() == BB && !isValidLoop(L, Context)) if (L && L->getHeader() == BB && (!isValidLoop(L, Context) && !KeepGoing))
return false; return false;
} }
for (BasicBlock *BB : R.blocks()) for (BasicBlock *BB : R.blocks())
if (!isValidCFG(*BB, Context)) if (!isValidCFG(*BB, Context) && !KeepGoing)
return false; return false;
for (BasicBlock *BB : R.blocks()) for (BasicBlock *BB : R.blocks())
for (BasicBlock::iterator I = BB->begin(), E = --BB->end(); I != E; ++I) for (BasicBlock::iterator I = BB->begin(), E = --BB->end(); I != E; ++I)
if (!isValidInstruction(*I, Context)) if (!isValidInstruction(*I, Context) && !KeepGoing)
return false; return false;
if (!hasAffineMemoryAccesses(Context)) if (!hasAffineMemoryAccesses(Context))
@ -671,7 +683,9 @@ bool ScopDetection::isValidRegion(Region &R) const {
DetectionContext Context(R, *AA, false /*verifying*/); DetectionContext Context(R, *AA, false /*verifying*/);
bool RegionIsValid = isValidRegion(Context); bool RegionIsValid = isValidRegion(Context);
if (PollyTrackFailures && !RegionIsValid) { bool HasErrors = !RegionIsValid || Context.Log.size() > 0;
if (PollyTrackFailures && HasErrors) {
// std::map::insert does not replace. // std::map::insert does not replace.
std::pair<reject_iterator, bool> InsertedValue = std::pair<reject_iterator, bool> InsertedValue =
RejectLogs.insert(std::make_pair(&R, Context.Log)); RejectLogs.insert(std::make_pair(&R, Context.Log));