[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