From b917f47fc4672d1a0757b1c49226191e86749cac Mon Sep 17 00:00:00 2001 From: Tobias Grosser Date: Sun, 26 Jan 2014 19:38:34 +0000 Subject: [PATCH] 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. llvm-svn: 200156 --- polly/lib/Analysis/Dependences.cpp | 45 +++++++++++++++-- polly/test/Dependences/computeout.ll | 72 ++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+), 3 deletions(-) create mode 100644 polly/test/Dependences/computeout.ll diff --git a/polly/lib/Analysis/Dependences.cpp b/polly/lib/Analysis/Dependences.cpp index 3b1af7ee9f86..f74bb66721ef 100644 --- a/polly/lib/Analysis/Dependences.cpp +++ b/polly/lib/Analysis/Dependences.cpp @@ -26,8 +26,10 @@ #include "polly/ScopInfo.h" #include "polly/Support/GICHelper.h" #include +#include #include #include +#include #include #define DEBUG_TYPE "polly-dependence" @@ -36,6 +38,12 @@ using namespace polly; using namespace llvm; +static cl::opt +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 LegalityCheckDisabled("disable-polly-legality", cl::desc("Disable polly legality check"), cl::Hidden, @@ -96,11 +104,17 @@ void Dependences::calculateDependences(Scop &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(Scop &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(__isl_take isl_set *ScheduleSubset, } 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() { diff --git a/polly/test/Dependences/computeout.ll b/polly/test/Dependences/computeout.ll new file mode 100644 index 000000000000..c2339d2aac1e --- /dev/null +++ b/polly/test/Dependences/computeout.ll @@ -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