summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--polly/include/polly/CodeGen/IslExprBuilder.h10
-rw-r--r--polly/lib/CodeGen/IslCodeGeneration.cpp4
-rw-r--r--polly/lib/CodeGen/IslExprBuilder.cpp65
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:
OpenPOWER on IntegriCloud