diff options
author | Johannes Doerfert <doerfert@cs.uni-saarland.de> | 2016-05-10 12:42:26 +0000 |
---|---|---|
committer | Johannes Doerfert <doerfert@cs.uni-saarland.de> | 2016-05-10 12:42:26 +0000 |
commit | 14b1cf35b5a9991a584e14025e353af152c2227c (patch) | |
tree | d0872491daf4ac50825878efeccbb7e51bf678f3 | |
parent | adf4b739eac40feee28bd6fcd89ebafa0f2247e1 (diff) | |
download | llvm-14b1cf35b5a9991a584e14025e353af152c2227c.zip llvm-14b1cf35b5a9991a584e14025e353af152c2227c.tar.gz llvm-14b1cf35b5a9991a584e14025e353af152c2227c.tar.bz2 |
[FIX] Create error-restrictions late
Before this patch we generated error-restrictions only for
error-blocks, thus blocks (or regions) containing a not represented
function call. However, the same reasoning is needed if the invalid
domain of a statement subsumes its actual domain. To this end we move
the generation of error-restrictions after the propagation of the
invalid domains. Consequently, error-statements are now defined more
general as statements that are assumed to be not executed.
Additionally, we do not record an empty domain for such statements but
a nullptr instead. This allows to distinguish between error-statements
and dead-statements.
llvm-svn: 269053
-rw-r--r-- | polly/lib/Analysis/ScopInfo.cpp | 24 | ||||
-rw-r--r-- | polly/test/ScopInfo/parameter_in_dead_statement.ll | 41 | ||||
-rw-r--r-- | polly/test/ScopInfo/restriction_in_dead_block.ll | 55 |
3 files changed, 108 insertions, 12 deletions
diff --git a/polly/lib/Analysis/ScopInfo.cpp b/polly/lib/Analysis/ScopInfo.cpp index cb192f8..f02a807 100644 --- a/polly/lib/Analysis/ScopInfo.cpp +++ b/polly/lib/Analysis/ScopInfo.cpp @@ -2383,8 +2383,10 @@ void Scop::propagateInvalidStmtDomains(Region *R, ScopDetection &SD, } else { isl_set_free(InvalidDomain); InvalidDomain = Domain; - auto *EmptyDom = isl_set_empty(isl_set_get_space(InvalidDomain)); - Domain = EmptyDom; + isl_set *DomPar = isl_set_params(isl_set_copy(Domain)); + recordAssumption(ERRORBLOCK, DomPar, BB->getTerminator()->getDebugLoc(), + AS_RESTRICTION); + Domain = nullptr; } if (isl_set_is_empty(InvalidDomain)) { @@ -2706,14 +2708,6 @@ void Scop::propagateDomainConstraints(Region *R, ScopDetection &SD, Loop *BBLoop = getRegionNodeLoop(RN, LI); if (BBLoop && BBLoop->getHeader() == BB && getRegion().contains(BBLoop)) addLoopBoundsToHeaderDomain(BBLoop, LI); - - // Add assumptions for error blocks. - if (containsErrorBlock(RN, getRegion(), LI, DT)) { - IsOptimized = true; - isl_set *DomPar = isl_set_params(isl_set_copy(Domain)); - recordAssumption(ERRORBLOCK, DomPar, BB->getTerminator()->getDebugLoc(), - AS_RESTRICTION); - } } } @@ -3180,7 +3174,7 @@ void Scop::simplifySCoP(bool AfterHoisting, DominatorTree &DT, LoopInfo &LI) { bool RemoveStmt = Stmt.isEmpty(); if (!RemoveStmt) - RemoveStmt = isl_set_is_empty(DomainMap[Stmt.getEntryBlock()]); + RemoveStmt = !DomainMap[Stmt.getEntryBlock()]; // Remove read only statements only after invariant loop hoisting. if (!RemoveStmt && AfterHoisting) { @@ -3647,6 +3641,13 @@ void Scop::addRecordedAssumptions() { continue; } + // If the domain was deleted the assumptions are void. + isl_set *Dom = getDomainConditions(AS.BB); + if (!Dom) { + isl_set_free(AS.Set); + continue; + } + // If a basic block was given use its domain to simplify the assumption. // In case of restrictions we know they only have to hold on the domain, // thus we can intersect them with the domain of the block. However, for @@ -3657,7 +3658,6 @@ void Scop::addRecordedAssumptions() { // To avoid the complement we will register A - B as a restricton not an // assumption. isl_set *S = AS.Set; - isl_set *Dom = getDomainConditions(AS.BB); if (AS.Sign == AS_RESTRICTION) S = isl_set_params(isl_set_intersect(S, Dom)); else /* (AS.Sign == AS_ASSUMPTION) */ diff --git a/polly/test/ScopInfo/parameter_in_dead_statement.ll b/polly/test/ScopInfo/parameter_in_dead_statement.ll new file mode 100644 index 0000000..6d0b0be --- /dev/null +++ b/polly/test/ScopInfo/parameter_in_dead_statement.ll @@ -0,0 +1,41 @@ +; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s +; RUN: opt %loadPolly -polly-codegen -S < %s | FileCheck %s --check-prefix=IR +; +; Verify we do not create assumptions based on the parameter p_1 which is the +; load %0 and due to error-assumptions not "part of the SCoP". +; +; CHECK: Invalid Context: +; CHECK-NEXT: [releaseCount, p_1] -> { : releaseCount > 0 } +; +; IR: polly.start +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +; Function Attrs: uwtable +define void @_ZN8NWindows16NSynchronization14CSemaphoreWFMO7ReleaseEi(i32 %releaseCount) { +entry: + br label %entry.split + +entry.split: ; preds = %entry + %cmp = icmp slt i32 %releaseCount, 1 + br i1 %cmp, label %return, label %if.end + +if.end: ; preds = %entry.split + tail call void @_ZN8NWindows16NSynchronization8CSynchro5EnterEv() + %0 = load i32, i32* null, align 8 + %add = add nsw i32 %0, %releaseCount + %cmp2 = icmp sgt i32 %add, 0 + br i1 %cmp2, label %if.then3, label %if.end5 + +if.then3: ; preds = %if.end + br label %return + +if.end5: ; preds = %if.end + br label %return + +return: ; preds = %if.end5, %if.then3, %entry.split + %retval.1 = phi i32 [ 1, %entry.split ], [ 1, %if.then3 ], [ 0, %if.end5 ] + ret void +} + +; Function Attrs: nounwind uwtable +declare void @_ZN8NWindows16NSynchronization8CSynchro5EnterEv() diff --git a/polly/test/ScopInfo/restriction_in_dead_block.ll b/polly/test/ScopInfo/restriction_in_dead_block.ll new file mode 100644 index 0000000..c06cd7c --- /dev/null +++ b/polly/test/ScopInfo/restriction_in_dead_block.ll @@ -0,0 +1,55 @@ +; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s +; +; Verify we do not generate an empty invalid context only because the wrap +; in the second conditional will always happen if the block is executed. +; +; CHECK: Invalid Context: +; CHECK-NEXT: [N] -> { : N > 0 } +; +; void f(char *A, char N) { +; for (char i = 0; i < 10; i++) { +; if (N > 0) +; if (1 + 127 * N > 0) +; A[i] = 1; +; A[i] = 0; +; } +; } +; +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +define void @f(i8* %A, i8 signext %N) { +entry: + br label %for.cond + +for.cond: ; preds = %for.inc, %entry + %indvars.iv = phi i8 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] + %exitcond = icmp ne i8 %indvars.iv, 10 + br i1 %exitcond, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %cmp3 = icmp sgt i8 %N, 0 + br i1 %cmp3, label %if.then, label %if.end10 + +if.then: ; preds = %for.body + %mul = mul i8 %N, 127 + %add = add i8 1, %mul + %cmp7 = icmp sgt i8 %add, 0 + br i1 %cmp7, label %if.then9, label %if.end10 + +if.then9: ; preds = %if.end + %arrayidx = getelementptr inbounds i8, i8* %A, i8 %indvars.iv + store i8 1, i8* %arrayidx, align 1 + br label %if.end10 + +if.end10: ; preds = %if.then9, %if.end + %arrayidx12 = getelementptr inbounds i8, i8* %A, i8 %indvars.iv + store i8 0, i8* %arrayidx12, align 1 + br label %for.inc + +for.inc: ; preds = %if.end10, %if.then + %indvars.iv.next = add nuw nsw i8 %indvars.iv, 1 + br label %for.cond + +for.end: ; preds = %for.cond + ret void +} |