[polly] r201593 - Check scops a second time before working on them
Tobias Grosser
tobias at grosser.es
Tue Feb 18 10:49:50 PST 2014
Author: grosser
Date: Tue Feb 18 12:49:49 2014
New Revision: 201593
URL: http://llvm.org/viewvc/llvm-project?rev=201593&view=rev
Log:
Check scops a second time before working on them
In rare cases the modification of one scop can effect the validity of other
scops, as code generation of an earlier scop may make the scalar evolution
functions derived for later scops less precise. The example that triggered this
patch was a scop that contained an 'or' expression as follows:
%add13710 = or i32 %j.19, 1
--> {(1 + (4 * %l)),+,2}<nsw><%for.body81>
Scev could only analyze the 'or' as it knew %j.19 is a multiple of 2. This
information was not available after the first scop was code generated (or
independent-blocks was run on it) and SCEV could not derive a precise SCEV
expression any more. This means we could not any more code generate this SCoP.
My current understanding is that there is always the risk that an earlier code
generation change invalidates later scops. As the example we have seen here is
difficult to avoid, we use this occasion to guard us against all such
invalidations.
This patch "solves" this issue by verifying right before we start working on
a detected scop, if this scop is in fact still valid. This adds a certain
overhead. However the verification we run is anyways very fast and secondly
it is only run on detected scops. So the overhead should not be very large. As
a later optimization we could detect scops only on demand, such that we need
to run scop-detections always only a single time.
This should fix the single last failure in the LLVM test-suite for the new
scev-based code generation.
Added:
polly/trunk/test/ScopInfo/multi-scop.ll
Modified:
polly/trunk/include/polly/ScopDetection.h (contents, props changed)
polly/trunk/lib/Analysis/ScopDetection.cpp
polly/trunk/lib/Analysis/TempScopInfo.cpp
Modified: polly/trunk/include/polly/ScopDetection.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/ScopDetection.h?rev=201593&r1=201592&r2=201593&view=diff
==============================================================================
--- polly/trunk/include/polly/ScopDetection.h (original)
+++ polly/trunk/include/polly/ScopDetection.h Tue Feb 18 12:49:49 2014
@@ -245,9 +245,11 @@ public:
/// @brief Is the region is the maximum region of a Scop?
///
/// @param R The Region to test if it is maximum.
+ /// @param Verify Rerun the scop detection to verify SCoP was not invalidated
+ /// meanwhile.
///
/// @return Return true if R is the maximum Region in a Scop, false otherwise.
- bool isMaxRegionInScop(const Region &R) const;
+ bool isMaxRegionInScop(const Region &R, bool Verify = true) const;
/// @brief Get a message why a region is invalid
///
Propchange: polly/trunk/include/polly/ScopDetection.h
------------------------------------------------------------------------------
--- svn:executable (original)
+++ svn:executable (removed)
@@ -1 +0,0 @@
-*
Modified: polly/trunk/lib/Analysis/ScopDetection.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/ScopDetection.cpp?rev=201593&r1=201592&r2=201593&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/ScopDetection.cpp (original)
+++ polly/trunk/lib/Analysis/ScopDetection.cpp Tue Feb 18 12:49:49 2014
@@ -112,6 +112,11 @@ TrackFailures("polly-detect-track-failur
cl::location(PollyTrackFailures), cl::Hidden, cl::init(false),
cl::cat(PollyCategory));
+static cl::opt<bool>
+VerifyScops("polly-detect-verify",
+ cl::desc("Verify the detected SCoPs after each transformation"),
+ cl::Hidden, cl::init(false), cl::cat(PollyCategory));
+
bool polly::PollyTrackFailures = false;
//===----------------------------------------------------------------------===//
@@ -204,9 +209,14 @@ void DiagnosticScopFound::print(Diagnost
//===----------------------------------------------------------------------===//
// ScopDetection.
-bool ScopDetection::isMaxRegionInScop(const Region &R) const {
- // The Region is valid only if it could be found in the set.
- return ValidRegions.count(&R);
+bool ScopDetection::isMaxRegionInScop(const Region &R, bool Verify) const {
+ if (!ValidRegions.count(&R))
+ return false;
+
+ if (Verify)
+ return isValidRegion(const_cast<Region &>(R));
+
+ return true;
}
std::string ScopDetection::regionIsInvalidBecause(const Region *R) const {
@@ -837,6 +847,9 @@ void polly::ScopDetection::verifyRegion(
}
void polly::ScopDetection::verifyAnalysis() const {
+ if (!VerifyScops)
+ return;
+
for (RegionSet::const_iterator I = ValidRegions.begin(),
E = ValidRegions.end();
I != E; ++I)
Modified: polly/trunk/lib/Analysis/TempScopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/TempScopInfo.cpp?rev=201593&r1=201592&r2=201593&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/TempScopInfo.cpp (original)
+++ polly/trunk/lib/Analysis/TempScopInfo.cpp Tue Feb 18 12:49:49 2014
@@ -341,6 +341,8 @@ bool TempScopInfo::runOnFunction(Functio
ZeroOffset = SE->getConstant(TD->getIntPtrType(F.getContext()), 0);
for (ScopDetection::iterator I = SD->begin(), E = SD->end(); I != E; ++I) {
+ if (!SD->isMaxRegionInScop(**I))
+ continue;
Region *R = const_cast<Region *>(*I);
TempScops.insert(std::make_pair(R, buildTempScop(*R)));
}
Added: polly/trunk/test/ScopInfo/multi-scop.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/multi-scop.ll?rev=201593&view=auto
==============================================================================
--- polly/trunk/test/ScopInfo/multi-scop.ll (added)
+++ polly/trunk/test/ScopInfo/multi-scop.ll Tue Feb 18 12:49:49 2014
@@ -0,0 +1,38 @@
+; RUN: opt %loadPolly -polly-detect -analyze -polly-codegen-scev < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-scops -analyze -polly-codegen-scev < %s
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; This test case contains two scops.
+define void @test(i32 %l, double* %a) {
+entry:
+ br label %entry.split
+
+entry.split: ; preds = %entry
+ %shl = shl i32 %l, 2
+ br i1 false, label %for.body, label %for.end
+
+for.body: ; preds = %for.body, %entry.split
+ %j.011 = phi i32 [ 0, %entry.split ], [ %add76, %for.body ]
+ %add76 = add nsw i32 %j.011, 2
+ br i1 false, label %for.body, label %for.end
+
+for.end: ; preds = %for.body, %entry.split
+ br i1 undef, label %for.body81, label %for.end170
+
+for.body81: ; preds = %for.body81, %for.end
+ %j.19 = phi i32 [ %shl, %for.end ], [ %add169, %for.body81 ]
+ %add13710 = or i32 %j.19, 1
+ %idxprom138 = sext i32 %add13710 to i64
+ %arrayidx139 = getelementptr inbounds double* %a, i64 %idxprom138
+ store double undef, double* %arrayidx139, align 8
+ %add169 = add nsw i32 %j.19, 2
+ br i1 false, label %for.body81, label %for.end170
+
+for.end170: ; preds = %for.body81
+ ret void
+}
+
+; CHECK: Valid Region for Scop: for.body81 => for.end170
+; CHECK: Valid Region for Scop: entry.split => for.end
+
More information about the llvm-commits
mailing list