[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();
/// @brief Get the run-time conditions for the 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.
/// @brief Build the run-time condition for the current scop.
///
/// @returns An ast expression that describes the necessary run-time check.
static isl_ast_expr *buildRunCondition(Scop *S,
__isl_keep isl_ast_build *Build);
__isl_give isl_ast_expr *buildRunCondition();
private:
Scop *S;
isl_ast_node *Root;
isl_ast_expr *RunCondition;
isl_ast_build *Build;
std::shared_ptr<isl_ctx> Ctx;
IslAst(Scop *Scop);

View File

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

View File

@ -331,8 +331,7 @@ buildCondition(__isl_keep isl_ast_build *Build, const Scop::MinMaxAccessTy *It0,
return NonAliasGroup;
}
__isl_give isl_ast_expr *
IslAst::buildRunCondition(Scop *S, __isl_keep isl_ast_build *Build) {
__isl_give isl_ast_expr *IslAst::buildRunCondition() {
isl_ast_expr *RunCondition;
// 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)
: S(Scop), Root(nullptr), RunCondition(nullptr),
Ctx(Scop->getSharedIslCtx()) {}
: S(Scop), Root(nullptr), Build(nullptr), Ctx(Scop->getSharedIslCtx()) {}
void IslAst::init(const Dependences &D) {
bool PerformParallelTest = PollyParallel || DetectParallel ||
@ -407,7 +405,6 @@ void IslAst::init(const Dependences &D) {
isl_ctx *Ctx = S->getIslCtx();
isl_options_set_ast_build_atomic_upper_bound(Ctx, true);
isl_options_set_ast_build_detect_min_max(Ctx, true);
isl_ast_build *Build;
AstBuildUserInfo BuildInfo;
if (UseContext)
@ -433,11 +430,7 @@ void IslAst::init(const Dependences &D) {
&BuildInfo);
}
RunCondition = buildRunCondition(S, Build);
Root = isl_ast_build_node_from_schedule(Build, S->getScheduleTree());
isl_ast_build_free(Build);
}
IslAst *IslAst::create(Scop *Scop, const Dependences &D) {
@ -448,13 +441,10 @@ IslAst *IslAst::create(Scop *Scop, const Dependences &D) {
IslAst::~IslAst() {
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_expr *IslAst::getRunCondition() {
return isl_ast_expr_copy(RunCondition);
}
void IslAstInfo::releaseMemory() {
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_expr *IslAstInfo::getRunCondition() const {
return Ast->getRunCondition();
return Ast->buildRunCondition();
}
IslAstUserPayload *IslAstInfo::getNodePayload(__isl_keep isl_ast_node *Node) {

View File

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

View File

@ -12,21 +12,21 @@
; }
; Short[0]
; CHECK: %polly.access.Short10 = getelementptr i8, i8* %Short, i1 false
; CHECK: %24 = bitcast i8* %polly.access.Short10 to i16*
; CHECK: %tmp5_p_scalar_ = load i16, i16* %24
; CHECK: %polly.access.Short{{[0-9]*}} = getelementptr i8, i8* %Short, i1 false
; CHECK: %[[R0:[0-9]*]] = bitcast i8* %polly.access.Short{{[0-9]*}} to i16*
; CHECK: %tmp5_p_scalar_ = load i16, i16* %[[R0]]
; Float[8 * i]
; CHECK: %26 = sext i8 %polly.indvar to i13
; CHECK: %27 = mul nsw i13 8, %26
; CHECK: %polly.access.Float11 = getelementptr i8, i8* %Float, i13 %27
; CHECK: %28 = bitcast i8* %polly.access.Float11 to float*
; CHECK: %tmp11_p_scalar_ = load float, float* %28
; CHECK: %[[R1:[0-9]*]] = sext i8 %polly.indvar to i13
; CHECK: %[[R2:[0-9]*]] = mul nsw i13 8, %[[R1]]
; CHECK: %polly.access.Float{{[0-9]*}} = getelementptr i8, i8* %Float, i13 %[[R2]]
; CHECK: %[[R3:[0-9]*]] = bitcast i8* %polly.access.Float{{[0-9]*}} to float*
; CHECK: %tmp11_p_scalar_ = load float, float* %[[R3]]
; Double[8]
; CHECK: %polly.access.Double13 = getelementptr i8, i8* %Double, i5 8
; CHECK: %30 = bitcast i8* %polly.access.Double13 to double*
; CHECK: %tmp17_p_scalar_ = load double, double* %30
; CHECK: %polly.access.Double{{[0-9]*}} = getelementptr i8, i8* %Double, i5 8
; CHECK: %[[R4:[0-9]*]] = bitcast i8* %polly.access.Double{{[0-9]*}} to double*
; CHECK: %tmp17_p_scalar_ = load double, double* %[[R4]]
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: %[[paAb:[._a-zA-Z0-9]]] = ptrtoint double** %polly.access.A to i64
; CHECK: %[[ALeB:[._a-zA-Z0-9]]] = icmp ule i64 %[[paBb]], %[[paAb]]
; CHECK: %polly.access.A1 = getelementptr double*, double** %A, i12 1024
; CHECK: %polly.access.B2 = getelementptr float*, float** %B, i1 false
; CHECK: %[[paA1b:[._a-zA-Z0-9]]] = ptrtoint double** %polly.access.A1 to i64
; CHECK: %[[paB2b:[._a-zA-Z0-9]]] = ptrtoint float** %polly.access.B2 to i64
; CHECK: %polly.access.A[[R0:[0-9]*]] = getelementptr double*, double** %A, i12 1024
; CHECK: %polly.access.B[[R1:[0-9]*]] = getelementptr float*, float** %B, i1 false
; CHECK: %[[paA1b:[._a-zA-Z0-9]]] = ptrtoint double** %polly.access.A[[R0]] 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: %[[le1OrLe2:[._a-zA-Z0-9]]] = or i1 %[[ALeB]], %[[A1LeB2]]
; CHECK: %[[orAndTrue:[._a-zA-Z0-9]]] = and i1 true, %[[le1OrLe2]]

View File

@ -18,7 +18,7 @@
; A[i % 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)]
;
@ -28,7 +28,7 @@
; each value of i to indeed be mapped to a value.
;
; 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
; 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: %[[r1:[0-9]*]] = mul nsw i64 127, %pexp.fdiv_q.4
; 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]
; 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]
; 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)]
; 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
; A[p + 128 * floord(-p - 1, 128) + 128]
; POW2: %polly.fdiv_q.shr = ashr i64 %p, 7
; POW2: %[[r1:[0-9]*]] = mul nsw i64 128, %polly.fdiv_q.shr
; 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]
; 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"

View File

@ -9,7 +9,7 @@
; for (int c4 = 0; c4 <= 3; c4 += 1)
; 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_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