[NFC] Generate runtime checks after the SCoP

We now generate runtime checks __after__ the SCoP code generation and
  not before, though they are still inserted at the same position int
  the code. This allows to modify the runtime check during SCoP code
  generation.

llvm-svn: 271894
This commit is contained in:
Johannes Doerfert 2016-06-06 13:32:52 +00:00
parent e27aec9f4a
commit c0ece9b67e
8 changed files with 42 additions and 57 deletions

View File

@ -53,22 +53,15 @@ public:
__isl_give isl_ast_node *getAst(); __isl_give isl_ast_node *getAst();
/// @brief Get the run-time conditions for the Scop. /// @brief Build the run-time condition for the current scop.
__isl_give isl_ast_expr *getRunCondition();
/// @brief Build run-time condition for scop.
///
/// @param S The scop to build the condition for.
/// @param Build The isl_build object to use to build the condition.
/// ///
/// @returns An ast expression that describes the necessary run-time check. /// @returns An ast expression that describes the necessary run-time check.
static isl_ast_expr *buildRunCondition(Scop *S, __isl_give isl_ast_expr *buildRunCondition();
__isl_keep isl_ast_build *Build);
private: private:
Scop *S; Scop *S;
isl_ast_node *Root; isl_ast_node *Root;
isl_ast_expr *RunCondition; isl_ast_build *Build;
std::shared_ptr<isl_ctx> Ctx; std::shared_ptr<isl_ctx> Ctx;
IslAst(Scop *Scop); IslAst(Scop *Scop);

View File

@ -191,7 +191,12 @@ public:
} else { } else {
NodeBuilder.addParameters(S.getContext()); NodeBuilder.addParameters(S.getContext());
SplitBlock = Builder.GetInsertBlock();
Builder.SetInsertPoint(&StartBlock->front());
NodeBuilder.create(AstRoot);
Builder.SetInsertPoint(SplitBlock->getTerminator());
ExprBuilder.setTrackOverflow(true); ExprBuilder.setTrackOverflow(true);
Value *RTC = buildRTC(Builder, ExprBuilder); Value *RTC = buildRTC(Builder, ExprBuilder);
Value *OverflowHappened = Builder.CreateNot( Value *OverflowHappened = Builder.CreateNot(
@ -199,10 +204,7 @@ public:
RTC = Builder.CreateAnd(RTC, OverflowHappened, "polly.rtc.result"); RTC = Builder.CreateAnd(RTC, OverflowHappened, "polly.rtc.result");
ExprBuilder.setTrackOverflow(false); ExprBuilder.setTrackOverflow(false);
Builder.GetInsertBlock()->getTerminator()->setOperand(0, RTC); SplitBlock->getTerminator()->setOperand(0, RTC);
Builder.SetInsertPoint(&StartBlock->front());
NodeBuilder.create(AstRoot);
NodeBuilder.finalizeSCoP(S); NodeBuilder.finalizeSCoP(S);
fixRegionInfo(EnteringBB->getParent(), R->getParent()); fixRegionInfo(EnteringBB->getParent(), R->getParent());

View File

@ -331,8 +331,7 @@ buildCondition(__isl_keep isl_ast_build *Build, const Scop::MinMaxAccessTy *It0,
return NonAliasGroup; return NonAliasGroup;
} }
__isl_give isl_ast_expr * __isl_give isl_ast_expr *IslAst::buildRunCondition() {
IslAst::buildRunCondition(Scop *S, __isl_keep isl_ast_build *Build) {
isl_ast_expr *RunCondition; isl_ast_expr *RunCondition;
// The conditions that need to be checked at run-time for this scop are // The conditions that need to be checked at run-time for this scop are
@ -393,8 +392,7 @@ static bool benefitsFromPolly(Scop *Scop, bool PerformParallelTest) {
} }
IslAst::IslAst(Scop *Scop) IslAst::IslAst(Scop *Scop)
: S(Scop), Root(nullptr), RunCondition(nullptr), : S(Scop), Root(nullptr), Build(nullptr), Ctx(Scop->getSharedIslCtx()) {}
Ctx(Scop->getSharedIslCtx()) {}
void IslAst::init(const Dependences &D) { void IslAst::init(const Dependences &D) {
bool PerformParallelTest = PollyParallel || DetectParallel || bool PerformParallelTest = PollyParallel || DetectParallel ||
@ -407,7 +405,6 @@ void IslAst::init(const Dependences &D) {
isl_ctx *Ctx = S->getIslCtx(); isl_ctx *Ctx = S->getIslCtx();
isl_options_set_ast_build_atomic_upper_bound(Ctx, true); isl_options_set_ast_build_atomic_upper_bound(Ctx, true);
isl_options_set_ast_build_detect_min_max(Ctx, true); isl_options_set_ast_build_detect_min_max(Ctx, true);
isl_ast_build *Build;
AstBuildUserInfo BuildInfo; AstBuildUserInfo BuildInfo;
if (UseContext) if (UseContext)
@ -433,11 +430,7 @@ void IslAst::init(const Dependences &D) {
&BuildInfo); &BuildInfo);
} }
RunCondition = buildRunCondition(S, Build);
Root = isl_ast_build_node_from_schedule(Build, S->getScheduleTree()); Root = isl_ast_build_node_from_schedule(Build, S->getScheduleTree());
isl_ast_build_free(Build);
} }
IslAst *IslAst::create(Scop *Scop, const Dependences &D) { IslAst *IslAst::create(Scop *Scop, const Dependences &D) {
@ -448,13 +441,10 @@ IslAst *IslAst::create(Scop *Scop, const Dependences &D) {
IslAst::~IslAst() { IslAst::~IslAst() {
isl_ast_node_free(Root); isl_ast_node_free(Root);
isl_ast_expr_free(RunCondition); isl_ast_build_free(Build);
} }
__isl_give isl_ast_node *IslAst::getAst() { return isl_ast_node_copy(Root); } __isl_give isl_ast_node *IslAst::getAst() { return isl_ast_node_copy(Root); }
__isl_give isl_ast_expr *IslAst::getRunCondition() {
return isl_ast_expr_copy(RunCondition);
}
void IslAstInfo::releaseMemory() { void IslAstInfo::releaseMemory() {
if (Ast) { if (Ast) {
@ -480,7 +470,7 @@ bool IslAstInfo::runOnScop(Scop &Scop) {
__isl_give isl_ast_node *IslAstInfo::getAst() const { return Ast->getAst(); } __isl_give isl_ast_node *IslAstInfo::getAst() const { return Ast->getAst(); }
__isl_give isl_ast_expr *IslAstInfo::getRunCondition() const { __isl_give isl_ast_expr *IslAstInfo::getRunCondition() const {
return Ast->getRunCondition(); return Ast->buildRunCondition();
} }
IslAstUserPayload *IslAstInfo::getNodePayload(__isl_keep isl_ast_node *Node) { IslAstUserPayload *IslAstInfo::getNodePayload(__isl_keep isl_ast_node *Node) {

View File

@ -9,14 +9,14 @@
; A[i] += 10; ; A[i] += 10;
; } ; }
; CHECK: %polly.access.cast.A14 = bitcast float* %A to i32* ; CHECK: %polly.access.cast.A{{[0-9]*}} = bitcast float* %A to i32*
; CHECK: %[[R0:[._0-9]*]] = sext i8 %polly.indvar11 to i9 ; CHECK: %[[R0:[._0-9]*]] = sext i8 %polly.indvar{{[0-9]*}} to i9
; CHECK: %[[R1:[._0-9]*]] = sub nsw i9 0, %[[R0]] ; CHECK: %[[R1:[._0-9]*]] = sub nsw i9 0, %[[R0]]
; CHECK: %[[R1s:[._0-9]*]] = sext i9 %[[R1]] to i10 ; CHECK: %[[R1s:[._0-9]*]] = sext i9 %[[R1]] to i10
; CHECK: %[[R2:[._0-9]*]] = add nsw i10 %[[R1s]], 99 ; CHECK: %[[R2:[._0-9]*]] = add nsw i10 %[[R1s]], 99
; CHECK: %polly.access.A15 = getelementptr i32, i32* %polly.access.cast.A14, i10 %[[R2]] ; CHECK: %polly.access.A{{[0-9]*}} = getelementptr i32, i32* %polly.access.cast.A{{[0-9]*}}, i10 %[[R2]]
; CHECK: %[[R3:[._0-9]*]] = bitcast i32* %polly.access.A15 to float* ; CHECK: %[[R3:[._0-9]*]] = bitcast i32* %polly.access.A{{[0-9]*}} to float*
; CHECK: %tmp14_p_scalar_ = load float, float* %[[R3]], align 4, !alias.scope !3, !noalias !4 ; CHECK: %tmp14_p_scalar_ = load float, float* %[[R3]]
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"

View File

@ -12,21 +12,21 @@
; } ; }
; Short[0] ; Short[0]
; CHECK: %polly.access.Short10 = getelementptr i8, i8* %Short, i1 false ; CHECK: %polly.access.Short{{[0-9]*}} = getelementptr i8, i8* %Short, i1 false
; CHECK: %24 = bitcast i8* %polly.access.Short10 to i16* ; CHECK: %[[R0:[0-9]*]] = bitcast i8* %polly.access.Short{{[0-9]*}} to i16*
; CHECK: %tmp5_p_scalar_ = load i16, i16* %24 ; CHECK: %tmp5_p_scalar_ = load i16, i16* %[[R0]]
; Float[8 * i] ; Float[8 * i]
; CHECK: %26 = sext i8 %polly.indvar to i13 ; CHECK: %[[R1:[0-9]*]] = sext i8 %polly.indvar to i13
; CHECK: %27 = mul nsw i13 8, %26 ; CHECK: %[[R2:[0-9]*]] = mul nsw i13 8, %[[R1]]
; CHECK: %polly.access.Float11 = getelementptr i8, i8* %Float, i13 %27 ; CHECK: %polly.access.Float{{[0-9]*}} = getelementptr i8, i8* %Float, i13 %[[R2]]
; CHECK: %28 = bitcast i8* %polly.access.Float11 to float* ; CHECK: %[[R3:[0-9]*]] = bitcast i8* %polly.access.Float{{[0-9]*}} to float*
; CHECK: %tmp11_p_scalar_ = load float, float* %28 ; CHECK: %tmp11_p_scalar_ = load float, float* %[[R3]]
; Double[8] ; Double[8]
; CHECK: %polly.access.Double13 = getelementptr i8, i8* %Double, i5 8 ; CHECK: %polly.access.Double{{[0-9]*}} = getelementptr i8, i8* %Double, i5 8
; CHECK: %30 = bitcast i8* %polly.access.Double13 to double* ; CHECK: %[[R4:[0-9]*]] = bitcast i8* %polly.access.Double{{[0-9]*}} to double*
; CHECK: %tmp17_p_scalar_ = load double, double* %30 ; CHECK: %tmp17_p_scalar_ = load double, double* %[[R4]]
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"

View File

@ -9,10 +9,10 @@
; CHECK: %[[paBb:[._a-zA-Z0-9]]] = ptrtoint float** %polly.access.B to i64 ; CHECK: %[[paBb:[._a-zA-Z0-9]]] = ptrtoint float** %polly.access.B to i64
; CHECK: %[[paAb:[._a-zA-Z0-9]]] = ptrtoint double** %polly.access.A to i64 ; CHECK: %[[paAb:[._a-zA-Z0-9]]] = ptrtoint double** %polly.access.A to i64
; CHECK: %[[ALeB:[._a-zA-Z0-9]]] = icmp ule i64 %[[paBb]], %[[paAb]] ; CHECK: %[[ALeB:[._a-zA-Z0-9]]] = icmp ule i64 %[[paBb]], %[[paAb]]
; CHECK: %polly.access.A1 = getelementptr double*, double** %A, i12 1024 ; CHECK: %polly.access.A[[R0:[0-9]*]] = getelementptr double*, double** %A, i12 1024
; CHECK: %polly.access.B2 = getelementptr float*, float** %B, i1 false ; CHECK: %polly.access.B[[R1:[0-9]*]] = getelementptr float*, float** %B, i1 false
; CHECK: %[[paA1b:[._a-zA-Z0-9]]] = ptrtoint double** %polly.access.A1 to i64 ; CHECK: %[[paA1b:[._a-zA-Z0-9]]] = ptrtoint double** %polly.access.A[[R0]] to i64
; CHECK: %[[paB2b:[._a-zA-Z0-9]]] = ptrtoint float** %polly.access.B2 to i64 ; CHECK: %[[paB2b:[._a-zA-Z0-9]]] = ptrtoint float** %polly.access.B[[R1]] to i64
; CHECK: %[[A1LeB2:[._a-zA-Z0-9]]] = icmp ule i64 %[[paA1b]], %[[paB2b]] ; CHECK: %[[A1LeB2:[._a-zA-Z0-9]]] = icmp ule i64 %[[paA1b]], %[[paB2b]]
; CHECK: %[[le1OrLe2:[._a-zA-Z0-9]]] = or i1 %[[ALeB]], %[[A1LeB2]] ; CHECK: %[[le1OrLe2:[._a-zA-Z0-9]]] = or i1 %[[ALeB]], %[[A1LeB2]]
; CHECK: %[[orAndTrue:[._a-zA-Z0-9]]] = and i1 true, %[[le1OrLe2]] ; CHECK: %[[orAndTrue:[._a-zA-Z0-9]]] = and i1 true, %[[le1OrLe2]]

View File

@ -18,7 +18,7 @@
; A[i % 127] ; A[i % 127]
; CHECK: %pexp.pdiv_r = urem i64 %polly.indvar, 127 ; CHECK: %pexp.pdiv_r = urem i64 %polly.indvar, 127
; CHECK: %polly.access.A9 = getelementptr float, float* %A, i64 %pexp.pdiv_r ; CHECK: %polly.access.A{{[0-9]*}} = getelementptr float, float* %A, i64 %pexp.pdiv_r
; A[floor(i / 127)] ; A[floor(i / 127)]
; ;
@ -28,7 +28,7 @@
; each value of i to indeed be mapped to a value. ; each value of i to indeed be mapped to a value.
; ;
; CHECK: %pexp.p_div_q = udiv i64 %polly.indvar, 127 ; CHECK: %pexp.p_div_q = udiv i64 %polly.indvar, 127
; CHECK: %polly.access.B10 = getelementptr float, float* %B, i64 %pexp.p_div_q ; CHECK: %polly.access.B{{[0-9]*}} = getelementptr float, float* %B, i64 %pexp.p_div_q
; #define floord(n,d) ((n < 0) ? (n - d + 1) : n) / d ; #define floord(n,d) ((n < 0) ? (n - d + 1) : n) / d
; A[p + 127 * floord(-p - 1, 127) + 127] ; A[p + 127 * floord(-p - 1, 127) + 127]
@ -39,30 +39,30 @@
; CHECK: %pexp.fdiv_q.4 = sdiv i64 %pexp.fdiv_q.3, 127 ; CHECK: %pexp.fdiv_q.4 = sdiv i64 %pexp.fdiv_q.3, 127
; CHECK: %[[r1:[0-9]*]] = mul nsw i64 127, %pexp.fdiv_q.4 ; CHECK: %[[r1:[0-9]*]] = mul nsw i64 127, %pexp.fdiv_q.4
; CHECK: %[[r2:[0-9]*]] = sub nsw i64 %p, %[[r1]] ; CHECK: %[[r2:[0-9]*]] = sub nsw i64 %p, %[[r1]]
; CHECK: %polly.access.A11 = getelementptr float, float* %A, i64 %[[r2]] ; CHECK: %polly.access.A{{[0-9]*}} = getelementptr float, float* %A, i64 %[[r2]]
; A[p / 127] ; A[p / 127]
; CHECK: %pexp.div = sdiv exact i64 %p, 127 ; CHECK: %pexp.div = sdiv exact i64 %p, 127
; CHECK: %polly.access.B12 = getelementptr float, float* %B, i64 %pexp.div ; CHECK: %polly.access.B{{[0-9]*}} = getelementptr float, float* %B, i64 %pexp.div
; A[i % 128] ; A[i % 128]
; POW2: %pexp.pdiv_r = urem i64 %polly.indvar, 128 ; POW2: %pexp.pdiv_r = urem i64 %polly.indvar, 128
; POW2: %polly.access.A9 = getelementptr float, float* %A, i64 %pexp.pdiv_r ; POW2: %polly.access.A{{[0-9]*}} = getelementptr float, float* %A, i64 %pexp.pdiv_r
; A[floor(i / 128)] ; A[floor(i / 128)]
; POW2: %pexp.p_div_q = udiv i64 %polly.indvar, 128 ; POW2: %pexp.p_div_q = udiv i64 %polly.indvar, 128
; POW2: %polly.access.B10 = getelementptr float, float* %B, i64 %pexp.p_div_q ; POW2: %polly.access.B{{[0-9]*}} = getelementptr float, float* %B, i64 %pexp.p_div_q
; #define floord(n,d) ((n < 0) ? (n - d + 1) : n) / d ; #define floord(n,d) ((n < 0) ? (n - d + 1) : n) / d
; A[p + 128 * floord(-p - 1, 128) + 128] ; A[p + 128 * floord(-p - 1, 128) + 128]
; POW2: %polly.fdiv_q.shr = ashr i64 %p, 7 ; POW2: %polly.fdiv_q.shr = ashr i64 %p, 7
; POW2: %[[r1:[0-9]*]] = mul nsw i64 128, %polly.fdiv_q.shr ; POW2: %[[r1:[0-9]*]] = mul nsw i64 128, %polly.fdiv_q.shr
; POW2: %[[r2:[0-9]*]] = sub nsw i64 %p, %[[r1]] ; POW2: %[[r2:[0-9]*]] = sub nsw i64 %p, %[[r1]]
; POW2: %polly.access.A11 = getelementptr float, float* %A, i64 %[[r2]] ; POW2: %polly.access.A{{[0-9]*}} = getelementptr float, float* %A, i64 %[[r2]]
; A[p / 128] ; A[p / 128]
; POW2: %pexp.div = sdiv exact i64 %p, 128 ; POW2: %pexp.div = sdiv exact i64 %p, 128
; POW2: %polly.access.B12 = getelementptr float, float* %B, i64 %pexp.div ; POW2: %polly.access.B{{[0-9]*}} = getelementptr float, float* %B, i64 %pexp.div
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"

View File

@ -9,7 +9,7 @@
; for (int c4 = 0; c4 <= 3; c4 += 1) ; for (int c4 = 0; c4 <= 3; c4 += 1)
; Stmt_for_body_3(32 * c0 + 4 * c2 + c4, 32 * c1 + c3); ; Stmt_for_body_3(32 * c0 + 4 * c2 + c4, 32 * c1 + c3);
; CHECK: polly.stmt.for.body.3: ; preds = %polly.loop_header18 ; CHECK: polly.stmt.for.body.3:
; CHECK: %_p_splat_one = load <1 x double>, <1 x double>* %_p_vec_p, align 8, !alias.scope !1, !noalias !3, !llvm.mem.parallel_loop_access !0 ; CHECK: %_p_splat_one = load <1 x double>, <1 x double>* %_p_vec_p, align 8, !alias.scope !1, !noalias !3, !llvm.mem.parallel_loop_access !0
; CHECK: %_p_vec_full = load <4 x double>, <4 x double>* %vector_ptr, align 8, !alias.scope !4, !noalias !5, !llvm.mem.parallel_loop_access !0 ; CHECK: %_p_vec_full = load <4 x double>, <4 x double>* %vector_ptr, align 8, !alias.scope !4, !noalias !5, !llvm.mem.parallel_loop_access !0
; CHECK: extractelement <4 x double> %addp_vec, i32 0 ; CHECK: extractelement <4 x double> %addp_vec, i32 0