[IslNodeBuilder] Move run-time check generation to NodeBuilder [NFC]

This improves the structure of the code and allows us to reuse the runtime
code generation in the PPCGCodeGeneration.

llvm-svn: 278017
This commit is contained in:
Tobias Grosser 2016-08-08 15:41:52 +00:00
parent 218c4cbd3d
commit 0aa29532b7
3 changed files with 32 additions and 22 deletions

View File

@ -66,6 +66,20 @@ public:
virtual ~IslNodeBuilder() {}
void addParameters(__isl_take isl_set *Context);
/// @brief Generate code that evaluates @p Condition at run-time.
///
/// This function is typically called to generate the LLVM-IR for the
/// run-time condition of the scop, that verifies that all the optimistic
/// assumptions we have taken during scop modeling and transformation
/// hold at run-time.
///
/// @param Condition The condition to evaluate
///
/// @result An llvm::Value that is true if the condition holds and false
/// otherwise.
Value *createRTC(isl_ast_expr *Condition);
void create(__isl_take isl_ast_node *Node);
/// @brief Allocate memory for all new arrays created by Polly.

View File

@ -66,19 +66,6 @@ public:
RegionInfo *RI;
///}
/// @brief Build the runtime condition.
///
/// Build the condition that evaluates at run-time to true iff all
/// assumptions taken for the SCoP hold, and to false otherwise.
///
/// @return A value evaluating to true/false if execution is save/unsafe.
Value *buildRTC(PollyIRBuilder &Builder, IslExprBuilder &ExprBuilder) {
Value *RTC = ExprBuilder.create(AI->getRunCondition());
if (!RTC->getType()->isIntegerTy(1))
RTC = Builder.CreateIsNotNull(RTC);
return RTC;
}
void verifyGeneratedFunction(Scop &S, Function &F) {
if (!verifyFunction(F, &errs()) || !Verify)
return;
@ -147,7 +134,6 @@ public:
PollyIRBuilder Builder = createPollyIRBuilder(EnteringBB, Annotator);
IslNodeBuilder NodeBuilder(Builder, Annotator, this, *DL, *LI, *SE, *DT, S);
IslExprBuilder &ExprBuilder = NodeBuilder.getExprBuilder();
// Only build the run-time condition and parameters _after_ having
// introduced the conditional branch. This is important as the conditional
@ -189,15 +175,8 @@ public:
isl_ast_node_free(AstRoot);
} else {
NodeBuilder.allocateNewArrays();
NodeBuilder.addParameters(S.getContext());
ExprBuilder.setTrackOverflow(true);
Value *RTC = buildRTC(Builder, ExprBuilder);
Value *OverflowHappened = Builder.CreateNot(
ExprBuilder.getOverflowState(), "polly.rtc.overflown");
RTC = Builder.CreateAnd(RTC, OverflowHappened, "polly.rtc.result");
ExprBuilder.setTrackOverflow(false);
Value *RTC = NodeBuilder.createRTC(AI->getRunCondition());
Builder.GetInsertBlock()->getTerminator()->setOperand(0, RTC);
Builder.SetInsertPoint(&StartBlock->front());

View File

@ -1239,3 +1239,20 @@ Value *IslNodeBuilder::generateSCEV(const SCEV *Expr) {
return expandCodeFor(S, SE, DL, "polly", Expr, Expr->getType(),
InsertLocation, &ValueMap);
}
/// The AST expression we generate to perform the run-time check assumes
/// computations on integer types of infinite size. As we only use 64-bit
/// arithmetic we check for overflows, in case of which we set the result
/// of this run-time check to false to be cosnservatively correct,
Value *IslNodeBuilder::createRTC(isl_ast_expr *Condition) {
auto ExprBuilder = getExprBuilder();
ExprBuilder.setTrackOverflow(true);
Value *RTC = ExprBuilder.create(Condition);
if (!RTC->getType()->isIntegerTy(1))
RTC = Builder.CreateIsNotNull(RTC);
Value *OverflowHappened =
Builder.CreateNot(ExprBuilder.getOverflowState(), "polly.rtc.overflown");
RTC = Builder.CreateAnd(RTC, OverflowHappened, "polly.rtc.result");
ExprBuilder.setTrackOverflow(false);
return RTC;
}