[polly] r249611 - Treat conditionally executed non-pure calls as errors
Johannes Doerfert via llvm-commits
llvm-commits at lists.llvm.org
Wed Oct 7 13:32:43 PDT 2015
Author: jdoerfert
Date: Wed Oct 7 15:32:43 2015
New Revision: 249611
URL: http://llvm.org/viewvc/llvm-project?rev=249611&view=rev
Log:
Treat conditionally executed non-pure calls as errors
This replaces the support for user defined error functions by a
heuristic that tries to determine if a call to a non-pure function
should be considered "an error". If so the block is assumed not to be
executed at runtime. While treating all non-pure function calls as
errors will allow a lot more regions to be analyzed, it will also
cause us to dismiss a lot again due to an infeasible runtime context.
This patch tries to limit that effect. A non-pure function call is
considered an error if it is executed only in conditionally with
regards to a cheap but simple heuristic.
Added:
polly/trunk/test/ScopInfo/non-pure-function-call.ll
polly/trunk/test/ScopInfo/non-pure-function-calls-causes-dead-blocks.ll
polly/trunk/test/ScopInfo/non-pure-function-calls.ll
Removed:
polly/trunk/test/ScopInfo/user-defined-error-causes-dead-blocks.ll
polly/trunk/test/ScopInfo/user-defined-error-functions.ll
Modified:
polly/trunk/include/polly/ScopDetection.h
polly/trunk/include/polly/Support/ScopHelper.h
polly/trunk/lib/Analysis/ScopDetection.cpp
polly/trunk/lib/Analysis/ScopInfo.cpp
polly/trunk/lib/Support/ScopHelper.cpp
Modified: polly/trunk/include/polly/ScopDetection.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/ScopDetection.h?rev=249611&r1=249610&r2=249611&view=diff
==============================================================================
--- polly/trunk/include/polly/ScopDetection.h (original)
+++ polly/trunk/include/polly/ScopDetection.h Wed Oct 7 15:32:43 2015
@@ -131,6 +131,7 @@ private:
/// @brief Analysis passes used.
//@{
+ const DominatorTree *DT;
ScalarEvolution *SE;
LoopInfo *LI;
RegionInfo *RI;
Modified: polly/trunk/include/polly/Support/ScopHelper.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/Support/ScopHelper.h?rev=249611&r1=249610&r2=249611&view=diff
==============================================================================
--- polly/trunk/include/polly/Support/ScopHelper.h (original)
+++ polly/trunk/include/polly/Support/ScopHelper.h Wed Oct 7 15:32:43 2015
@@ -121,13 +121,20 @@ llvm::Value *expandCodeFor(Scop &S, llvm
/// the following conditions:
///
/// - It is terminated by an unreachable instruction
-/// - It contains a call to a function listed in the command line argument
-/// --polly-error-functions=name1,name2,name3
+/// - It contains a call to a non-pure function that is not immediately
+/// dominated by a loop header and that does not dominate the region exit.
+/// This is a heuristic to pick only error blocks that are conditionally
+/// executed and can be assumed to be not executed at all without the domains
+/// beeing available.
///
/// @param BB The block to check.
+/// @param R The analyzed region.
+/// @param LI The loop info analysis.
+/// @param DT The dominator tree of the function.
///
/// @return True if the block is a error block, false otherwise.
-bool isErrorBlock(llvm::BasicBlock &BB);
+bool isErrorBlock(llvm::BasicBlock &BB, const llvm::Region &R,
+ llvm::LoopInfo &LI, const llvm::DominatorTree &DT);
/// @brief Return the condition for the terminator @p TI.
///
Modified: polly/trunk/lib/Analysis/ScopDetection.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/ScopDetection.cpp?rev=249611&r1=249610&r2=249611&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/ScopDetection.cpp (original)
+++ polly/trunk/lib/Analysis/ScopDetection.cpp Wed Oct 7 15:32:43 2015
@@ -973,7 +973,7 @@ bool ScopDetection::allBlocksValid(Detec
for (BasicBlock *BB : CurRegion.blocks()) {
// Do not check exception blocks as we will never include them in the SCoP.
- if (isErrorBlock(*BB))
+ if (isErrorBlock(*BB, CurRegion, *LI, *DT))
continue;
if (!isValidCFG(*BB, false, Context) && !KeepGoing)
@@ -1096,6 +1096,7 @@ bool ScopDetection::runOnFunction(llvm::
AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
+ DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
Region *TopRegion = RI->getTopLevelRegion();
releaseMemory();
@@ -1171,6 +1172,7 @@ void polly::ScopDetection::verifyAnalysi
void ScopDetection::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<LoopInfoWrapperPass>();
AU.addRequired<ScalarEvolutionWrapperPass>();
+ AU.addRequired<DominatorTreeWrapperPass>();
// We also need AA and RegionInfo when we are verifying analysis.
AU.addRequiredTransitive<AAResultsWrapperPass>();
AU.addRequiredTransitive<RegionInfoPass>();
@@ -1205,6 +1207,7 @@ INITIALIZE_PASS_BEGIN(ScopDetection, "po
INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass);
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass);
INITIALIZE_PASS_DEPENDENCY(RegionInfoPass);
+INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass);
INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass);
INITIALIZE_PASS_END(ScopDetection, "polly-detect",
"Polly - Detect static control parts (SCoPs)", false, false)
Modified: polly/trunk/lib/Analysis/ScopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/ScopInfo.cpp?rev=249611&r1=249610&r2=249611&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/ScopInfo.cpp (original)
+++ polly/trunk/lib/Analysis/ScopInfo.cpp Wed Oct 7 15:32:43 2015
@@ -1698,11 +1698,12 @@ static inline unsigned getNumBlocksInReg
return NumBlocks;
}
-static bool containsErrorBlock(RegionNode *RN) {
+static bool containsErrorBlock(RegionNode *RN, const Region &R, LoopInfo &LI,
+ const DominatorTree &DT) {
if (!RN->isSubRegion())
- return isErrorBlock(*RN->getNodeAs<BasicBlock>());
+ return isErrorBlock(*RN->getNodeAs<BasicBlock>(), R, LI, DT);
for (BasicBlock *BB : RN->getNodeAs<Region>()->blocks())
- if (isErrorBlock(*BB))
+ if (isErrorBlock(*BB, R, LI, DT))
return true;
return false;
}
@@ -1785,7 +1786,7 @@ void Scop::buildDomainsWithBranchConstra
// the predecessors and can therefor look at the domain of a error block.
// That allows us to generate the assumptions needed for them not to be
// executed at runtime.
- if (containsErrorBlock(RN))
+ if (containsErrorBlock(RN, getRegion(), LI, DT))
continue;
BasicBlock *BB = getRegionNodeBasicBlock(RN);
@@ -1993,7 +1994,7 @@ void Scop::propagateDomainConstraints(Re
addLoopBoundsToHeaderDomain(BBLoop);
// Add assumptions for error blocks.
- if (containsErrorBlock(RN)) {
+ if (containsErrorBlock(RN, getRegion(), LI, DT)) {
IsOptimized = true;
isl_set *DomPar = isl_set_params(isl_set_copy(Domain));
addAssumption(isl_set_complement(DomPar));
@@ -2888,7 +2889,7 @@ bool Scop::isIgnored(RegionNode *RN) {
return true;
// Check if error blocks are contained.
- if (containsErrorBlock(RN))
+ if (containsErrorBlock(RN, getRegion(), LI, DT))
return true;
return false;
Modified: polly/trunk/lib/Support/ScopHelper.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Support/ScopHelper.cpp?rev=249611&r1=249610&r2=249611&view=diff
==============================================================================
--- polly/trunk/lib/Support/ScopHelper.cpp (original)
+++ polly/trunk/lib/Support/ScopHelper.cpp Wed Oct 7 15:32:43 2015
@@ -28,11 +28,6 @@ using namespace polly;
#define DEBUG_TYPE "polly-scop-helper"
-static cl::list<std::string>
- ErrorFunctions("polly-error-functions",
- cl::desc("A list of error functions"), cl::Hidden,
- cl::ZeroOrMore, cl::CommaSeparated, cl::cat(PollyCategory));
-
Value *polly::getPointerOperand(Instruction &Inst) {
if (LoadInst *load = dyn_cast<LoadInst>(&Inst))
return load->getPointerOperand();
@@ -346,22 +341,36 @@ Value *polly::expandCodeFor(Scop &S, Sca
return Expander.expandCodeFor(E, Ty, IP);
}
-bool polly::isErrorBlock(BasicBlock &BB) {
+bool polly::isErrorBlock(BasicBlock &BB, const Region &R, LoopInfo &LI,
+ const DominatorTree &DT) {
if (isa<UnreachableInst>(BB.getTerminator()))
return true;
- if (ErrorFunctions.empty())
+ if (LI.isLoopHeader(&BB))
+ return false;
+
+ if (DT.dominates(&BB, R.getExit()))
+ return false;
+
+ // FIXME: This is a simple heuristic to determine if the load is executed
+ // in a conditional. However, we actually would need the control
+ // condition, i.e., the post dominance frontier. Alternatively we
+ // could walk up the dominance tree until we find a block that is
+ // not post dominated by the load and check if it is a conditional
+ // or a loop header.
+ auto *DTNode = DT.getNode(&BB);
+ auto *IDomBB = DTNode->getIDom()->getBlock();
+ if (LI.isLoopHeader(IDomBB))
return false;
for (Instruction &Inst : BB)
- if (CallInst *CI = dyn_cast<CallInst>(&Inst))
- if (Function *F = CI->getCalledFunction()) {
- const auto &FnName = F->getName();
- for (const auto &ErrorFn : ErrorFunctions)
- if (FnName.equals(ErrorFn))
- return true;
- }
+ if (CallInst *CI = dyn_cast<CallInst>(&Inst)) {
+ if (!CI->doesNotAccessMemory())
+ return true;
+ if (CI->doesNotReturn())
+ return true;
+ }
return false;
}
Added: polly/trunk/test/ScopInfo/non-pure-function-call.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/non-pure-function-call.ll?rev=249611&view=auto
==============================================================================
--- polly/trunk/test/ScopInfo/non-pure-function-call.ll (added)
+++ polly/trunk/test/ScopInfo/non-pure-function-call.ll Wed Oct 7 15:32:43 2015
@@ -0,0 +1,50 @@
+; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s
+;
+; CHECK: Assumed Context:
+; CHECK-NEXT: [N] -> { : N <= 101 }
+;
+; void g(void);
+; void f(int *A, int N) {
+; for (int i = 0; i < N; i++) {
+; if (i > 100)
+; g();
+; A[i]++;
+; }
+; }
+;
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+define void @f(i32* %A, i32 %N) {
+entry:
+ %tmp = sext i32 %N to i64
+ br label %for.cond
+
+for.cond: ; preds = %for.inc, %entry
+ %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
+ %cmp = icmp slt i64 %indvars.iv, %tmp
+ br i1 %cmp, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %cmp1 = icmp sgt i64 %indvars.iv, 100
+ br i1 %cmp1, label %if.then, label %if.end
+
+if.then: ; preds = %for.body
+ call void @g() #2
+ br label %if.end
+
+if.end: ; preds = %if.then, %for.body
+ %arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
+ %tmp1 = load i32, i32* %arrayidx, align 4
+ %inc = add nsw i32 %tmp1, 1
+ store i32 %inc, i32* %arrayidx, align 4
+ br label %for.inc
+
+for.inc: ; preds = %if.end
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ ret void
+}
+
+declare void @g()
Added: polly/trunk/test/ScopInfo/non-pure-function-calls-causes-dead-blocks.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/non-pure-function-calls-causes-dead-blocks.ll?rev=249611&view=auto
==============================================================================
--- polly/trunk/test/ScopInfo/non-pure-function-calls-causes-dead-blocks.ll (added)
+++ polly/trunk/test/ScopInfo/non-pure-function-calls-causes-dead-blocks.ll Wed Oct 7 15:32:43 2015
@@ -0,0 +1,139 @@
+; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s
+;
+; Error blocks are skipped during SCoP detection. Hence, we have to skip
+; them during SCoP too as they might contain accesses or branches we cannot
+; handle. Additionally, some blocks might be only reachable via error blocks.
+; Such blocks should not be considered to be valid and therefor ignored.
+;
+; void timer_start(void);
+; void timer_stop(void);
+; void kernel(int *A, int *B, int timeit, int N) {
+;
+; if (timeit) {
+; timer_start();
+; // split BB
+; A[0] = 0; // Do not create a statement for this block
+; }
+;
+; for (int i = 0; i < N; i++)
+; A[i] += B[i];
+;
+; if (timeit) {
+; timer_stop();
+; if (invalid float branch) // Do not crash on the float branch
+; timer_start();
+; }
+;
+; for (int i = 0; i < N; i++)
+; A[i] += B[i];
+;
+; if (timeit)
+; timer_stop();
+; }
+;
+; The assumed context is empty because all statements are executed only
+; if timeit != 0. This is due to the fact that they are not "reached"
+; by the error blocks that are executed for timeit == 0.
+;
+; CHECK: Region: %entry.split---%if.end.20
+; CHECK: Assumed Context:
+; CHECK-NEXT: [timeit, N] -> { : }
+; CHECK: Statements {
+; CHECK-NOT: Stmt_if_then_split
+; CHECK: Stmt_for_body
+; CHECK-NOT: Stmt_if_then_split
+; CHECK: Stmt_for_body_9
+; CHECK-NOT: Stmt_if_then_split
+; CHECK: }
+;
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+define void @kernel(i32* %A, i32* %B, i32 %timeit, i32 %N) {
+entry:
+ br label %entry.split
+
+entry.split:
+ %tobool = icmp eq i32 %timeit, 0
+ br i1 %tobool, label %for.cond.pre, label %if.then
+
+if.then: ; preds = %entry
+ call void @timer_start()
+ br label %if.then.split
+
+; Dead block if we assume if.then not to be executed because of the call
+if.then.split: ; preds = %if.then
+ %A0 = getelementptr inbounds i32, i32* %A, i64 0
+ store i32 0, i32* %A0, align 4
+ br label %for.cond.pre
+
+for.cond.pre:
+ %tmp = sext i32 %N to i64
+ br label %for.cond
+
+for.cond: ; preds = %for.inc, %if.end
+ %indvars.iv1 = phi i64 [ %indvars.iv.next2, %for.inc ], [ 0, %for.cond.pre ]
+ %cmp = icmp slt i64 %indvars.iv1, %tmp
+ br i1 %cmp, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %arrayidx = getelementptr inbounds i32, i32* %B, i64 %indvars.iv1
+ %tmp3 = load i32, i32* %arrayidx, align 4
+ %arrayidx2 = getelementptr inbounds i32, i32* %A, i64 %indvars.iv1
+ %tmp4 = load i32, i32* %arrayidx2, align 4
+ %add = add nsw i32 %tmp4, %tmp3
+ store i32 %add, i32* %arrayidx2, align 4
+ br label %for.inc
+
+for.inc: ; preds = %for.body
+ %indvars.iv.next2 = add nuw nsw i64 %indvars.iv1, 1
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ %tobool3 = icmp eq i32 %timeit, 0
+ br i1 %tobool3, label %if.end.5, label %if.then.4
+
+if.then.4: ; preds = %for.end
+ call void @timer_stop()
+ %na = fcmp one float 4.0, 5.0
+ br i1 %na, label %if.end.5, label %if.then.4.rem
+
+if.then.4.rem: ; preds = %for.end
+ call void @timer_start()
+ br label %if.end.5
+
+if.end.5: ; preds = %for.end, %if.then.4
+ %tmp5 = sext i32 %N to i64
+ br label %for.cond.7
+
+for.cond.7: ; preds = %for.inc.15, %if.end.5
+ %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc.15 ], [ 0, %if.end.5 ]
+ %cmp8 = icmp slt i64 %indvars.iv, %tmp5
+ br i1 %cmp8, label %for.body.9, label %for.end.17
+
+for.body.9: ; preds = %for.cond.7
+ %arrayidx11 = getelementptr inbounds i32, i32* %B, i64 %indvars.iv
+ %tmp6 = load i32, i32* %arrayidx11, align 4
+ %arrayidx13 = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
+ %tmp7 = load i32, i32* %arrayidx13, align 4
+ %add14 = add nsw i32 %tmp7, %tmp6
+ store i32 %add14, i32* %arrayidx13, align 4
+ br label %for.inc.15
+
+for.inc.15: ; preds = %for.body.9
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ br label %for.cond.7
+
+for.end.17: ; preds = %for.cond.7
+ %tobool18 = icmp eq i32 %timeit, 0
+ br i1 %tobool18, label %if.end.20, label %if.then.19
+
+if.then.19: ; preds = %for.end.17
+ call void @timer_stop()
+ br label %if.end.20
+
+if.end.20: ; preds = %for.end.17, %if.then.19
+ ret void
+}
+
+declare void @timer_start()
+declare void @timer_stop()
Added: polly/trunk/test/ScopInfo/non-pure-function-calls.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/non-pure-function-calls.ll?rev=249611&view=auto
==============================================================================
--- polly/trunk/test/ScopInfo/non-pure-function-calls.ll (added)
+++ polly/trunk/test/ScopInfo/non-pure-function-calls.ll Wed Oct 7 15:32:43 2015
@@ -0,0 +1,114 @@
+; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s
+;
+; Allow the user to define function names that are treated as
+; error functions and assumed not to be executed.
+;
+; void timer_start(void);
+; void timer_stop(void);
+; void kernel(int *A, int *B, int timeit, int N) {
+;
+; if (timeit)
+; timer_start();
+;
+; for (int i = 0; i < N; i++)
+; A[i] += B[i];
+;
+; if (timeit) {
+; timer_stop();
+; timer_start();
+; }
+;
+; for (int i = 0; i < N; i++)
+; A[i] += B[i];
+;
+; if (timeit)
+; timer_stop();
+; }
+;
+; CHECK: Region: %for.cond---%if.end.20
+; CHECK: Assumed Context:
+; CHECK: [N, timeit] -> { : timeit = 0 }
+; CHECK: Statements {
+; CHECK: Stmt
+; CHECK: Stmt
+; CHECK-NOT Stmt
+; CHECK: }
+;
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+define void @kernel(i32* %A, i32* %B, i32 %timeit, i32 %N) {
+entry:
+ %tobool = icmp eq i32 %timeit, 0
+ br i1 %tobool, label %if.end, label %if.then
+
+if.then: ; preds = %entry
+ call void @timer_start()
+ br label %if.end
+
+if.end: ; preds = %entry, %if.then
+ %tmp = sext i32 %N to i64
+ br label %for.cond
+
+for.cond: ; preds = %for.inc, %if.end
+ %indvars.iv1 = phi i64 [ %indvars.iv.next2, %for.inc ], [ 0, %if.end ]
+ %cmp = icmp slt i64 %indvars.iv1, %tmp
+ br i1 %cmp, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %arrayidx = getelementptr inbounds i32, i32* %B, i64 %indvars.iv1
+ %tmp3 = load i32, i32* %arrayidx, align 4
+ %arrayidx2 = getelementptr inbounds i32, i32* %A, i64 %indvars.iv1
+ %tmp4 = load i32, i32* %arrayidx2, align 4
+ %add = add nsw i32 %tmp4, %tmp3
+ store i32 %add, i32* %arrayidx2, align 4
+ br label %for.inc
+
+for.inc: ; preds = %for.body
+ %indvars.iv.next2 = add nuw nsw i64 %indvars.iv1, 1
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ %tobool3 = icmp eq i32 %timeit, 0
+ br i1 %tobool3, label %if.end.5, label %if.then.4
+
+if.then.4: ; preds = %for.end
+ call void @timer_stop()
+ call void @timer_start()
+ br label %if.end.5
+
+if.end.5: ; preds = %for.end, %if.then.4
+ %tmp5 = sext i32 %N to i64
+ br label %for.cond.7
+
+for.cond.7: ; preds = %for.inc.15, %if.end.5
+ %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc.15 ], [ 0, %if.end.5 ]
+ %cmp8 = icmp slt i64 %indvars.iv, %tmp5
+ br i1 %cmp8, label %for.body.9, label %for.end.17
+
+for.body.9: ; preds = %for.cond.7
+ %arrayidx11 = getelementptr inbounds i32, i32* %B, i64 %indvars.iv
+ %tmp6 = load i32, i32* %arrayidx11, align 4
+ %arrayidx13 = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
+ %tmp7 = load i32, i32* %arrayidx13, align 4
+ %add14 = add nsw i32 %tmp7, %tmp6
+ store i32 %add14, i32* %arrayidx13, align 4
+ br label %for.inc.15
+
+for.inc.15: ; preds = %for.body.9
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ br label %for.cond.7
+
+for.end.17: ; preds = %for.cond.7
+ %tobool18 = icmp eq i32 %timeit, 0
+ br i1 %tobool18, label %if.end.20, label %if.then.19
+
+if.then.19: ; preds = %for.end.17
+ call void @timer_stop()
+ br label %if.end.20
+
+if.end.20: ; preds = %for.end.17, %if.then.19
+ ret void
+}
+
+declare void @timer_start()
+declare void @timer_stop()
Removed: polly/trunk/test/ScopInfo/user-defined-error-causes-dead-blocks.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/user-defined-error-causes-dead-blocks.ll?rev=249610&view=auto
==============================================================================
--- polly/trunk/test/ScopInfo/user-defined-error-causes-dead-blocks.ll (original)
+++ polly/trunk/test/ScopInfo/user-defined-error-causes-dead-blocks.ll (removed)
@@ -1,139 +0,0 @@
-; RUN: opt %loadPolly -polly-scops -polly-error-functions=timer_start,timer_stop -analyze < %s | FileCheck %s
-;
-; Error blocks are skipped during SCoP detection. Hence, we have to skip
-; them during SCoP too as they might contain accesses or branches we cannot
-; handle. Additionally, some blocks might be only reachable via error blocks.
-; Such blocks should not be considered to be valid and therefor ignored.
-;
-; void timer_start(void);
-; void timer_stop(void);
-; void kernel(int *A, int *B, int timeit, int N) {
-;
-; if (timeit) {
-; timer_start();
-; // split BB
-; A[0] = 0; // Do not create a statement for this block
-; }
-;
-; for (int i = 0; i < N; i++)
-; A[i] += B[i];
-;
-; if (timeit) {
-; timer_stop();
-; if (invalid float branch) // Do not crash on the float branch
-; timer_start();
-; }
-;
-; for (int i = 0; i < N; i++)
-; A[i] += B[i];
-;
-; if (timeit)
-; timer_stop();
-; }
-;
-; The assumed context is empty because all statements are executed only
-; if timeit != 0. This is due to the fact that they are not "reached"
-; by the error blocks that are executed for timeit == 0.
-;
-; CHECK: Region: %entry.split---%if.end.20
-; CHECK: Assumed Context:
-; CHECK-NEXT: [timeit, N] -> { : }
-; CHECK: Statements {
-; CHECK-NOT: Stmt_if_then_split
-; CHECK: Stmt_for_body
-; CHECK-NOT: Stmt_if_then_split
-; CHECK: Stmt_for_body_9
-; CHECK-NOT: Stmt_if_then_split
-; CHECK: }
-;
-target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
-
-define void @kernel(i32* %A, i32* %B, i32 %timeit, i32 %N) {
-entry:
- br label %entry.split
-
-entry.split:
- %tobool = icmp eq i32 %timeit, 0
- br i1 %tobool, label %for.cond.pre, label %if.then
-
-if.then: ; preds = %entry
- call void @timer_start()
- br label %if.then.split
-
-; Dead block if we assume if.then not to be executed because of the call
-if.then.split: ; preds = %if.then
- %A0 = getelementptr inbounds i32, i32* %A, i64 0
- store i32 0, i32* %A0, align 4
- br label %for.cond.pre
-
-for.cond.pre:
- %tmp = sext i32 %N to i64
- br label %for.cond
-
-for.cond: ; preds = %for.inc, %if.end
- %indvars.iv1 = phi i64 [ %indvars.iv.next2, %for.inc ], [ 0, %for.cond.pre ]
- %cmp = icmp slt i64 %indvars.iv1, %tmp
- br i1 %cmp, label %for.body, label %for.end
-
-for.body: ; preds = %for.cond
- %arrayidx = getelementptr inbounds i32, i32* %B, i64 %indvars.iv1
- %tmp3 = load i32, i32* %arrayidx, align 4
- %arrayidx2 = getelementptr inbounds i32, i32* %A, i64 %indvars.iv1
- %tmp4 = load i32, i32* %arrayidx2, align 4
- %add = add nsw i32 %tmp4, %tmp3
- store i32 %add, i32* %arrayidx2, align 4
- br label %for.inc
-
-for.inc: ; preds = %for.body
- %indvars.iv.next2 = add nuw nsw i64 %indvars.iv1, 1
- br label %for.cond
-
-for.end: ; preds = %for.cond
- %tobool3 = icmp eq i32 %timeit, 0
- br i1 %tobool3, label %if.end.5, label %if.then.4
-
-if.then.4: ; preds = %for.end
- call void @timer_stop()
- %na = fcmp one float 4.0, 5.0
- br i1 %na, label %if.end.5, label %if.then.4.rem
-
-if.then.4.rem: ; preds = %for.end
- call void @timer_start()
- br label %if.end.5
-
-if.end.5: ; preds = %for.end, %if.then.4
- %tmp5 = sext i32 %N to i64
- br label %for.cond.7
-
-for.cond.7: ; preds = %for.inc.15, %if.end.5
- %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc.15 ], [ 0, %if.end.5 ]
- %cmp8 = icmp slt i64 %indvars.iv, %tmp5
- br i1 %cmp8, label %for.body.9, label %for.end.17
-
-for.body.9: ; preds = %for.cond.7
- %arrayidx11 = getelementptr inbounds i32, i32* %B, i64 %indvars.iv
- %tmp6 = load i32, i32* %arrayidx11, align 4
- %arrayidx13 = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
- %tmp7 = load i32, i32* %arrayidx13, align 4
- %add14 = add nsw i32 %tmp7, %tmp6
- store i32 %add14, i32* %arrayidx13, align 4
- br label %for.inc.15
-
-for.inc.15: ; preds = %for.body.9
- %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
- br label %for.cond.7
-
-for.end.17: ; preds = %for.cond.7
- %tobool18 = icmp eq i32 %timeit, 0
- br i1 %tobool18, label %if.end.20, label %if.then.19
-
-if.then.19: ; preds = %for.end.17
- call void @timer_stop()
- br label %if.end.20
-
-if.end.20: ; preds = %for.end.17, %if.then.19
- ret void
-}
-
-declare void @timer_start()
-declare void @timer_stop()
Removed: polly/trunk/test/ScopInfo/user-defined-error-functions.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/user-defined-error-functions.ll?rev=249610&view=auto
==============================================================================
--- polly/trunk/test/ScopInfo/user-defined-error-functions.ll (original)
+++ polly/trunk/test/ScopInfo/user-defined-error-functions.ll (removed)
@@ -1,114 +0,0 @@
-; RUN: opt %loadPolly -polly-scops -polly-error-functions=timer_start,timer_stop -analyze < %s | FileCheck %s
-;
-; Allow the user to define function names that are treated as
-; error functions and assumed not to be executed.
-;
-; void timer_start(void);
-; void timer_stop(void);
-; void kernel(int *A, int *B, int timeit, int N) {
-;
-; if (timeit)
-; timer_start();
-;
-; for (int i = 0; i < N; i++)
-; A[i] += B[i];
-;
-; if (timeit) {
-; timer_stop();
-; timer_start();
-; }
-;
-; for (int i = 0; i < N; i++)
-; A[i] += B[i];
-;
-; if (timeit)
-; timer_stop();
-; }
-;
-; CHECK: Region: %for.cond---%if.end.20
-; CHECK: Assumed Context:
-; CHECK: [N, timeit] -> { : timeit = 0 }
-; CHECK: Statements {
-; CHECK: Stmt
-; CHECK: Stmt
-; CHECK-NOT Stmt
-; CHECK: }
-;
-target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
-
-define void @kernel(i32* %A, i32* %B, i32 %timeit, i32 %N) {
-entry:
- %tobool = icmp eq i32 %timeit, 0
- br i1 %tobool, label %if.end, label %if.then
-
-if.then: ; preds = %entry
- call void @timer_start()
- br label %if.end
-
-if.end: ; preds = %entry, %if.then
- %tmp = sext i32 %N to i64
- br label %for.cond
-
-for.cond: ; preds = %for.inc, %if.end
- %indvars.iv1 = phi i64 [ %indvars.iv.next2, %for.inc ], [ 0, %if.end ]
- %cmp = icmp slt i64 %indvars.iv1, %tmp
- br i1 %cmp, label %for.body, label %for.end
-
-for.body: ; preds = %for.cond
- %arrayidx = getelementptr inbounds i32, i32* %B, i64 %indvars.iv1
- %tmp3 = load i32, i32* %arrayidx, align 4
- %arrayidx2 = getelementptr inbounds i32, i32* %A, i64 %indvars.iv1
- %tmp4 = load i32, i32* %arrayidx2, align 4
- %add = add nsw i32 %tmp4, %tmp3
- store i32 %add, i32* %arrayidx2, align 4
- br label %for.inc
-
-for.inc: ; preds = %for.body
- %indvars.iv.next2 = add nuw nsw i64 %indvars.iv1, 1
- br label %for.cond
-
-for.end: ; preds = %for.cond
- %tobool3 = icmp eq i32 %timeit, 0
- br i1 %tobool3, label %if.end.5, label %if.then.4
-
-if.then.4: ; preds = %for.end
- call void @timer_stop()
- call void @timer_start()
- br label %if.end.5
-
-if.end.5: ; preds = %for.end, %if.then.4
- %tmp5 = sext i32 %N to i64
- br label %for.cond.7
-
-for.cond.7: ; preds = %for.inc.15, %if.end.5
- %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc.15 ], [ 0, %if.end.5 ]
- %cmp8 = icmp slt i64 %indvars.iv, %tmp5
- br i1 %cmp8, label %for.body.9, label %for.end.17
-
-for.body.9: ; preds = %for.cond.7
- %arrayidx11 = getelementptr inbounds i32, i32* %B, i64 %indvars.iv
- %tmp6 = load i32, i32* %arrayidx11, align 4
- %arrayidx13 = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
- %tmp7 = load i32, i32* %arrayidx13, align 4
- %add14 = add nsw i32 %tmp7, %tmp6
- store i32 %add14, i32* %arrayidx13, align 4
- br label %for.inc.15
-
-for.inc.15: ; preds = %for.body.9
- %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
- br label %for.cond.7
-
-for.end.17: ; preds = %for.cond.7
- %tobool18 = icmp eq i32 %timeit, 0
- br i1 %tobool18, label %if.end.20, label %if.then.19
-
-if.then.19: ; preds = %for.end.17
- call void @timer_stop()
- br label %if.end.20
-
-if.end.20: ; preds = %for.end.17, %if.then.19
- ret void
-}
-
-declare void @timer_start()
-declare void @timer_stop()
More information about the llvm-commits
mailing list