[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:
parent
adf4b739ea
commit
14b1cf35b5
|
@ -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) */
|
||||
|
|
|
@ -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()
|
|
@ -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
|
||||
}
|
Loading…
Reference in New Issue