[polly] r200156 - Dependences: Bound the time dependence calculation is allowed to take

Tobias Grosser tobias at grosser.es
Sun Jan 26 11:38:35 PST 2014


Author: grosser
Date: Sun Jan 26 13:38:34 2014
New Revision: 200156

URL: http://llvm.org/viewvc/llvm-project?rev=200156&view=rev
Log:
Dependences: Bound the time dependence calculation is allowed to take

Count the number of computational steps that have been used to solve the
dependence problem and abort in case we reach the "compute-out". This ensures we
do not hang forever in cases the dependence problem is too difficult to solve.
There is just a single case in the LLVM test-suite that runs into the
compute-out. Even in this case, we can probably coalesce some of the parameters
(i32 b, i32 b zext i64, ...) to simplify the problem enough to not hit the
compute out. However, for now we set the compute out in place to address the
general issue. The compute out was choosen such that it stops on a recent laptop
after about 8 seconds.

Added:
    polly/trunk/test/Dependences/computeout.ll
Modified:
    polly/trunk/lib/Analysis/Dependences.cpp

Modified: polly/trunk/lib/Analysis/Dependences.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/Dependences.cpp?rev=200156&r1=200155&r2=200156&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/Dependences.cpp (original)
+++ polly/trunk/lib/Analysis/Dependences.cpp Sun Jan 26 13:38:34 2014
@@ -26,8 +26,10 @@
 #include "polly/ScopInfo.h"
 #include "polly/Support/GICHelper.h"
 #include <isl/aff.h>
+#include <isl/ctx.h>
 #include <isl/flow.h>
 #include <isl/map.h>
+#include <isl/options.h>
 #include <isl/set.h>
 
 #define DEBUG_TYPE "polly-dependence"
@@ -36,6 +38,12 @@
 using namespace polly;
 using namespace llvm;
 
+static cl::opt<int>
+OptComputeOut("polly-dependences-computeout",
+              cl::desc("Bound the dependence analysis by a maximal amount of "
+                       "computational steps"),
+              cl::Hidden, cl::init(100000), cl::cat(PollyCategory));
+
 static cl::opt<bool>
 LegalityCheckDisabled("disable-polly-legality",
                       cl::desc("Disable polly legality check"), cl::Hidden,
@@ -96,11 +104,17 @@ void Dependences::calculateDependences(S
   Write = isl_union_map_coalesce(Write);
   MayWrite = isl_union_map_coalesce(MayWrite);
 
+  long MaxOpsOld = isl_ctx_get_max_operations(S.getIslCtx());
+  isl_ctx_set_max_operations(S.getIslCtx(), OptComputeOut);
+  isl_options_set_on_error(S.getIslCtx(), ISL_ON_ERROR_CONTINUE);
+
   DEBUG(dbgs() << "Read: " << Read << "\n";
         dbgs() << "Write: " << Write << "\n";
         dbgs() << "MayWrite: " << MayWrite << "\n";
         dbgs() << "Schedule: " << Schedule << "\n");
 
+  WAW = WAW = WAR;
+
   if (OptAnalysisType == VALUE_BASED_ANALYSIS) {
     isl_union_map_compute_flow(
         isl_union_map_copy(Read), isl_union_map_copy(Write),
@@ -143,6 +157,17 @@ void Dependences::calculateDependences(S
   WAW = isl_union_map_coalesce(WAW);
   WAR = isl_union_map_coalesce(WAR);
 
+  if (isl_ctx_last_error(S.getIslCtx()) == isl_error_quota) {
+    isl_union_map_free(RAW);
+    isl_union_map_free(WAW);
+    isl_union_map_free(WAR);
+    RAW = WAW = WAR = NULL;
+    isl_ctx_reset_error(S.getIslCtx());
+  }
+  isl_options_set_on_error(S.getIslCtx(), ISL_ON_ERROR_ABORT);
+  isl_ctx_reset_operations(S.getIslCtx());
+  isl_ctx_set_max_operations(S.getIslCtx(), MaxOpsOld);
+
   DEBUG(printScop(dbgs()));
 }
 
@@ -262,9 +287,23 @@ bool Dependences::isParallelDimension(__
 }
 
 void Dependences::printScop(raw_ostream &OS) const {
-  OS << "\tRAW dependences:\n\t\t" << RAW << "\n";
-  OS << "\tWAR dependences:\n\t\t" << WAR << "\n";
-  OS << "\tWAW dependences:\n\t\t" << WAW << "\n";
+  OS << "\tRAW dependences:\n\t\t";
+  if (RAW)
+    OS << RAW << "\n";
+  else
+    OS << "n/a\n";
+
+  OS << "\tWAR dependences:\n\t\t";
+  if (WAR)
+    OS << WAR << "\n";
+  else
+    OS << "n/a\n";
+
+  OS << "\tWAW dependences:\n\t\t";
+  if (WAW)
+    OS << WAW << "\n";
+  else
+    OS << "n/a\n";
 }
 
 void Dependences::releaseMemory() {

Added: polly/trunk/test/Dependences/computeout.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Dependences/computeout.ll?rev=200156&view=auto
==============================================================================
--- polly/trunk/test/Dependences/computeout.ll (added)
+++ polly/trunk/test/Dependences/computeout.ll Sun Jan 26 13:38:34 2014
@@ -0,0 +1,72 @@
+; RUN: opt -S %loadPolly -basicaa -polly-dependences -analyze < %s | FileCheck %s -check-prefix=VALUE
+; RUN: opt -S %loadPolly -basicaa -polly-dependences -analyze -polly-dependences-computeout=1 < %s | FileCheck %s -check-prefix=TIMEOUT
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-pc-linux-gnu"
+
+;     for(i = 0; i < 100; i++ )
+; S1:   A[i] = 2;
+;
+;     for (i = 0; i < 10; i++ )
+; S2:   A[i]  = 5;
+;
+;     for (i = 0; i < 200; i++ )
+; S3:   A[i] = 5;
+
+define void @sequential_writes() {
+entry:
+  %A = alloca [200 x i32]
+  br label %S1
+
+S1:
+  %indvar.1 = phi i64 [ 0, %entry ], [ %indvar.next.1, %S1 ]
+  %arrayidx.1 = getelementptr [200 x i32]* %A, i64 0, i64 %indvar.1
+  store i32 2, i32* %arrayidx.1
+  %indvar.next.1 = add i64 %indvar.1, 1
+  %exitcond.1 = icmp ne i64 %indvar.next.1, 100
+  br i1 %exitcond.1, label %S1, label %exit.1
+
+exit.1:
+  br label %S2
+
+S2:
+  %indvar.2 = phi i64 [ 0, %exit.1 ], [ %indvar.next.2, %S2 ]
+  %arrayidx.2 = getelementptr [200 x i32]* %A, i64 0, i64 %indvar.2
+  store i32 5, i32* %arrayidx.2
+  %indvar.next.2 = add i64 %indvar.2, 1
+  %exitcond.2 = icmp ne i64 %indvar.next.2, 10
+  br i1 %exitcond.2, label %S2, label %exit.2
+
+exit.2:
+  br label %S3
+
+S3:
+  %indvar.3 = phi i64 [ 0, %exit.2 ], [ %indvar.next.3, %S3 ]
+  %arrayidx.3 = getelementptr [200 x i32]* %A, i64 0, i64 %indvar.3
+  store i32 7, i32* %arrayidx.3
+  %indvar.next.3 = add i64 %indvar.3, 1
+  %exitcond.3 = icmp ne i64 %indvar.next.3, 200
+  br i1 %exitcond.3, label %S3 , label %exit.3
+
+exit.3:
+  ret void
+}
+
+; VALUE: region: 'S1 => exit.3' in function 'sequential_writes':
+; VALUE:   RAW dependences:
+; VALUE:     {  }
+; VALUE:   WAR dependences:
+; VALUE:     {  }
+; VALUE:   WAW dependences:
+; VALUE:     {
+; VALUE:       Stmt_S1[i0] -> Stmt_S2[i0] : i0 >= 0 and i0 <= 9;
+; VALUE:       Stmt_S2[i0] -> Stmt_S3[i0] : i0 >= 0 and i0 <= 9;
+; VALUE:       Stmt_S1[i0] -> Stmt_S3[i0] : i0 >= 10 and i0 <= 99
+; VALUE:     }
+
+; TIMEOUT: region: 'S1 => exit.3' in function 'sequential_writes':
+; TIMEOUT:   RAW dependences:
+; TIMEOUT:     n/a
+; TIMEOUT:   WAR dependences:
+; TIMEOUT:     n/a
+; TIMEOUT:   WAW dependences:
+; TIMEOUT:     n/a





More information about the llvm-commits mailing list