diff options
-rw-r--r-- | polly/include/polly/CodeGen/IslExprBuilder.h | 10 | ||||
-rw-r--r-- | polly/lib/CodeGen/IslCodeGeneration.cpp | 4 | ||||
-rw-r--r-- | polly/lib/CodeGen/IslExprBuilder.cpp | 65 |
3 files changed, 73 insertions, 6 deletions
diff --git a/polly/include/polly/CodeGen/IslExprBuilder.h b/polly/include/polly/CodeGen/IslExprBuilder.h index 74b1a099fab..99e6d8b09fe 100644 --- a/polly/include/polly/CodeGen/IslExprBuilder.h +++ b/polly/include/polly/CodeGen/IslExprBuilder.h @@ -96,8 +96,10 @@ public: /// @param Expander A SCEVExpander to create the indices for multi /// dimensional accesses. IslExprBuilder(PollyIRBuilder &Builder, IDToValueTy &IDToValue, - llvm::SCEVExpander &Expander) - : Builder(Builder), IDToValue(IDToValue), Expander(Expander) {} + llvm::SCEVExpander &Expander, llvm::DominatorTree &DT, + llvm::LoopInfo &LI) + : Builder(Builder), IDToValue(IDToValue), Expander(Expander), DT(DT), + LI(LI) {} /// @brief Create LLVM-IR for an isl_ast_expr[ession]. /// @@ -130,6 +132,9 @@ private: /// @brief A SCEVExpander to translate dimension sizes to llvm values. llvm::SCEVExpander &Expander; + llvm::DominatorTree &DT; + llvm::LoopInfo &LI; + llvm::Value *createOp(__isl_take isl_ast_expr *Expr); llvm::Value *createOpUnary(__isl_take isl_ast_expr *Expr); llvm::Value *createOpAccess(__isl_take isl_ast_expr *Expr); @@ -138,6 +143,7 @@ private: llvm::Value *createOpSelect(__isl_take isl_ast_expr *Expr); llvm::Value *createOpICmp(__isl_take isl_ast_expr *Expr); llvm::Value *createOpBoolean(__isl_take isl_ast_expr *Expr); + llvm::Value *createOpBooleanConditional(__isl_take isl_ast_expr *Expr); llvm::Value *createId(__isl_take isl_ast_expr *Expr); llvm::Value *createInt(__isl_take isl_ast_expr *Expr); llvm::Value *createOpAddressOf(__isl_take isl_ast_expr *Expr); diff --git a/polly/lib/CodeGen/IslCodeGeneration.cpp b/polly/lib/CodeGen/IslCodeGeneration.cpp index b4d23a13641..b8bdadd9e1b 100644 --- a/polly/lib/CodeGen/IslCodeGeneration.cpp +++ b/polly/lib/CodeGen/IslCodeGeneration.cpp @@ -65,8 +65,8 @@ public: DominatorTree &DT, Scop &S) : S(S), Builder(Builder), Annotator(Annotator), Rewriter(new SCEVExpander(SE, "polly")), - ExprBuilder(Builder, IDToValue, *Rewriter), - BlockGen(Builder, LI, SE, DT, &ExprBuilder), RegionGen(BlockGen), P(P), + ExprBuilder(Builder, IDToValue, *Rewriter, DT, LI), + BlockGen(Builder, LI, SE, DT, &ExprBuilder), RegionGen(BlockGen), DL(DL), LI(LI), SE(SE), DT(DT) {} ~IslNodeBuilder() { delete Rewriter; } diff --git a/polly/lib/CodeGen/IslExprBuilder.cpp b/polly/lib/CodeGen/IslExprBuilder.cpp index f40da395a6b..7ff01915a04 100644 --- a/polly/lib/CodeGen/IslExprBuilder.cpp +++ b/polly/lib/CodeGen/IslExprBuilder.cpp @@ -16,6 +16,7 @@ #include "llvm/Analysis/ScalarEvolutionExpander.h" #include "llvm/Support/Debug.h" +#include "llvm/Transforms/Utils/BasicBlockUtils.h" using namespace llvm; using namespace polly; @@ -444,14 +445,71 @@ Value *IslExprBuilder::createOpBoolean(__isl_take isl_ast_expr *Expr) { return Res; } +Value * +IslExprBuilder::createOpBooleanConditional(__isl_take isl_ast_expr *Expr) { + assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op && + "Expected an isl_ast_expr_op expression"); + + Value *LHS, *RHS; + isl_ast_op_type OpType; + + Function *F = Builder.GetInsertBlock()->getParent(); + LLVMContext &Context = F->getContext(); + + OpType = isl_ast_expr_get_op_type(Expr); + + assert((OpType == isl_ast_op_and_then || OpType == isl_ast_op_or_else) && + "Unsupported isl_ast_op_type"); + + auto InsertBB = Builder.GetInsertBlock(); + auto InsertPoint = Builder.GetInsertPoint(); + auto NextBB = SplitBlock(InsertBB, InsertPoint, &DT, &LI); + BasicBlock *CondBB = BasicBlock::Create(Context, "polly.cond", F); + LI.changeLoopFor(CondBB, LI.getLoopFor(InsertBB)); + DT.addNewBlock(CondBB, InsertBB); + + InsertBB->getTerminator()->eraseFromParent(); + Builder.SetInsertPoint(InsertBB); + auto BR = Builder.CreateCondBr(Builder.getTrue(), NextBB, CondBB); + + Builder.SetInsertPoint(CondBB); + Builder.CreateBr(NextBB); + + Builder.SetInsertPoint(InsertBB->getTerminator()); + + LHS = create(isl_ast_expr_get_op_arg(Expr, 0)); + if (!LHS->getType()->isIntegerTy(1)) + LHS = Builder.CreateIsNotNull(LHS); + auto LeftBB = Builder.GetInsertBlock(); + + if (OpType == isl_ast_op_and || OpType == isl_ast_op_and_then) + BR->setCondition(Builder.CreateNeg(LHS)); + else + BR->setCondition(LHS); + + Builder.SetInsertPoint(CondBB->getTerminator()); + RHS = create(isl_ast_expr_get_op_arg(Expr, 1)); + if (!RHS->getType()->isIntegerTy(1)) + RHS = Builder.CreateIsNotNull(RHS); + auto RightBB = Builder.GetInsertBlock(); + + Builder.SetInsertPoint(NextBB->getTerminator()); + auto PHI = Builder.CreatePHI(Builder.getInt1Ty(), 2); + PHI->addIncoming(OpType == isl_ast_op_and_then ? Builder.getFalse() + : Builder.getTrue(), + LeftBB); + PHI->addIncoming(RHS, RightBB); + + isl_ast_expr_free(Expr); + return PHI; +} + Value *IslExprBuilder::createOp(__isl_take isl_ast_expr *Expr) { assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op && "Expression not of type isl_ast_expr_op"); switch (isl_ast_expr_get_op_type(Expr)) { case isl_ast_op_error: case isl_ast_op_cond: - case isl_ast_op_and_then: - case isl_ast_op_or_else: case isl_ast_op_call: case isl_ast_op_member: llvm_unreachable("Unsupported isl ast expression"); @@ -476,6 +534,9 @@ Value *IslExprBuilder::createOp(__isl_take isl_ast_expr *Expr) { case isl_ast_op_and: case isl_ast_op_or: return createOpBoolean(Expr); + case isl_ast_op_and_then: + case isl_ast_op_or_else: + return createOpBooleanConditional(Expr); case isl_ast_op_eq: case isl_ast_op_le: case isl_ast_op_lt: |