[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
This commit is contained in:
Johannes Doerfert 2016-05-10 12:42:26 +00:00
parent adf4b739ea
commit 14b1cf35b5
3 changed files with 108 additions and 12 deletions

View File

@ -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) */

View File

@ -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()

View File

@ -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
}