1 //===------ IslExprBuilder.cpp ----- Code generate isl AST expressions ----===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 //===----------------------------------------------------------------------===//
11 #include "polly/CodeGen/IslExprBuilder.h"
12 #include "polly/CodeGen/RuntimeDebugBuilder.h"
13 #include "polly/Options.h"
14 #include "polly/ScopInfo.h"
15 #include "polly/Support/GICHelper.h"
16 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
19 using namespace polly
;
21 /// Different overflow tracking modes.
22 enum OverflowTrackingChoice
{
23 OT_NEVER
, ///< Never tack potential overflows.
24 OT_REQUEST
, ///< Track potential overflows if requested.
25 OT_ALWAYS
///< Always track potential overflows.
28 static cl::opt
<OverflowTrackingChoice
> OTMode(
29 "polly-overflow-tracking",
30 cl::desc("Define where potential integer overflows in generated "
31 "expressions should be tracked."),
32 cl::values(clEnumValN(OT_NEVER
, "never", "Never track the overflow bit."),
33 clEnumValN(OT_REQUEST
, "request",
34 "Track the overflow bit if requested."),
35 clEnumValN(OT_ALWAYS
, "always",
36 "Always track the overflow bit.")),
37 cl::Hidden
, cl::init(OT_REQUEST
), cl::ZeroOrMore
, cl::cat(PollyCategory
));
39 IslExprBuilder::IslExprBuilder(Scop
&S
, PollyIRBuilder
&Builder
,
40 IDToValueTy
&IDToValue
, ValueMapT
&GlobalMap
,
41 const DataLayout
&DL
, ScalarEvolution
&SE
,
42 DominatorTree
&DT
, LoopInfo
&LI
,
43 BasicBlock
*StartBlock
)
44 : S(S
), Builder(Builder
), IDToValue(IDToValue
), GlobalMap(GlobalMap
),
45 DL(DL
), SE(SE
), DT(DT
), LI(LI
), StartBlock(StartBlock
) {
46 OverflowState
= (OTMode
== OT_ALWAYS
) ? Builder
.getFalse() : nullptr;
49 void IslExprBuilder::setTrackOverflow(bool Enable
) {
50 // If potential overflows are tracked always or never we ignore requests
51 // to change the behavior.
52 if (OTMode
!= OT_REQUEST
)
56 // If tracking should be enabled initialize the OverflowState.
57 OverflowState
= Builder
.getFalse();
59 // If tracking should be disabled just unset the OverflowState.
60 OverflowState
= nullptr;
64 Value
*IslExprBuilder::getOverflowState() const {
65 // If the overflow tracking was requested but it is disabled we avoid the
66 // additional nullptr checks at the call sides but instead provide a
68 if (OTMode
== OT_NEVER
)
69 return Builder
.getFalse();
73 bool IslExprBuilder::hasLargeInts(isl::ast_expr Expr
) {
74 enum isl_ast_expr_type Type
= isl_ast_expr_get_type(Expr
.get());
76 if (Type
== isl_ast_expr_id
)
79 if (Type
== isl_ast_expr_int
) {
80 isl::val Val
= Expr
.get_val();
81 APInt APValue
= APIntFromVal(Val
);
82 auto BitWidth
= APValue
.getBitWidth();
83 return BitWidth
>= 64;
86 assert(Type
== isl_ast_expr_op
&& "Expected isl_ast_expr of type operation");
88 int NumArgs
= isl_ast_expr_get_op_n_arg(Expr
.get());
90 for (int i
= 0; i
< NumArgs
; i
++) {
91 isl::ast_expr Operand
= Expr
.get_op_arg(i
);
92 if (hasLargeInts(Operand
))
99 Value
*IslExprBuilder::createBinOp(BinaryOperator::BinaryOps Opc
, Value
*LHS
,
100 Value
*RHS
, const Twine
&Name
) {
101 // Handle the plain operation (without overflow tracking) first.
102 if (!OverflowState
) {
104 case Instruction::Add
:
105 return Builder
.CreateNSWAdd(LHS
, RHS
, Name
);
106 case Instruction::Sub
:
107 return Builder
.CreateNSWSub(LHS
, RHS
, Name
);
108 case Instruction::Mul
:
109 return Builder
.CreateNSWMul(LHS
, RHS
, Name
);
111 llvm_unreachable("Unknown binary operator!");
115 Function
*F
= nullptr;
116 Module
*M
= Builder
.GetInsertBlock()->getModule();
118 case Instruction::Add
:
119 F
= Intrinsic::getDeclaration(M
, Intrinsic::sadd_with_overflow
,
122 case Instruction::Sub
:
123 F
= Intrinsic::getDeclaration(M
, Intrinsic::ssub_with_overflow
,
126 case Instruction::Mul
:
127 F
= Intrinsic::getDeclaration(M
, Intrinsic::smul_with_overflow
,
131 llvm_unreachable("No overflow intrinsic for binary operator found!");
134 auto *ResultStruct
= Builder
.CreateCall(F
, {LHS
, RHS
}, Name
);
135 assert(ResultStruct
->getType()->isStructTy());
138 Builder
.CreateExtractValue(ResultStruct
, 1, Name
+ ".obit");
140 // If all overflows are tracked we do not combine the results as this could
141 // cause dominance problems. Instead we will always keep the last overflow
142 // flag as current state.
143 if (OTMode
== OT_ALWAYS
)
144 OverflowState
= OverflowFlag
;
147 Builder
.CreateOr(OverflowState
, OverflowFlag
, "polly.overflow.state");
149 return Builder
.CreateExtractValue(ResultStruct
, 0, Name
+ ".res");
152 Value
*IslExprBuilder::createAdd(Value
*LHS
, Value
*RHS
, const Twine
&Name
) {
153 return createBinOp(Instruction::Add
, LHS
, RHS
, Name
);
156 Value
*IslExprBuilder::createSub(Value
*LHS
, Value
*RHS
, const Twine
&Name
) {
157 return createBinOp(Instruction::Sub
, LHS
, RHS
, Name
);
160 Value
*IslExprBuilder::createMul(Value
*LHS
, Value
*RHS
, const Twine
&Name
) {
161 return createBinOp(Instruction::Mul
, LHS
, RHS
, Name
);
164 Type
*IslExprBuilder::getWidestType(Type
*T1
, Type
*T2
) {
165 assert(isa
<IntegerType
>(T1
) && isa
<IntegerType
>(T2
));
167 if (T1
->getPrimitiveSizeInBits() < T2
->getPrimitiveSizeInBits())
173 Value
*IslExprBuilder::createOpUnary(__isl_take isl_ast_expr
*Expr
) {
174 assert(isl_ast_expr_get_op_type(Expr
) == isl_ast_op_minus
&&
175 "Unsupported unary operation");
178 Type
*MaxType
= getType(Expr
);
179 assert(MaxType
->isIntegerTy() &&
180 "Unary expressions can only be created for integer types");
182 V
= create(isl_ast_expr_get_op_arg(Expr
, 0));
183 MaxType
= getWidestType(MaxType
, V
->getType());
185 if (MaxType
!= V
->getType())
186 V
= Builder
.CreateSExt(V
, MaxType
);
188 isl_ast_expr_free(Expr
);
189 return createSub(ConstantInt::getNullValue(MaxType
), V
);
192 Value
*IslExprBuilder::createOpNAry(__isl_take isl_ast_expr
*Expr
) {
193 assert(isl_ast_expr_get_type(Expr
) == isl_ast_expr_op
&&
194 "isl ast expression not of type isl_ast_op");
195 assert(isl_ast_expr_get_op_n_arg(Expr
) >= 2 &&
196 "We need at least two operands in an n-ary operation");
198 CmpInst::Predicate Pred
;
199 switch (isl_ast_expr_get_op_type(Expr
)) {
201 llvm_unreachable("This is not a an n-ary isl ast expression");
203 Pred
= CmpInst::ICMP_SGT
;
206 Pred
= CmpInst::ICMP_SLT
;
210 Value
*V
= create(isl_ast_expr_get_op_arg(Expr
, 0));
212 for (int i
= 1; i
< isl_ast_expr_get_op_n_arg(Expr
); ++i
) {
213 Value
*OpV
= create(isl_ast_expr_get_op_arg(Expr
, i
));
214 Type
*Ty
= getWidestType(V
->getType(), OpV
->getType());
216 if (Ty
!= OpV
->getType())
217 OpV
= Builder
.CreateSExt(OpV
, Ty
);
219 if (Ty
!= V
->getType())
220 V
= Builder
.CreateSExt(V
, Ty
);
222 Value
*Cmp
= Builder
.CreateICmp(Pred
, V
, OpV
);
223 V
= Builder
.CreateSelect(Cmp
, V
, OpV
);
226 // TODO: We can truncate the result, if it fits into a smaller type. This can
227 // help in cases where we have larger operands (e.g. i67) but the result is
228 // known to fit into i64. Without the truncation, the larger i67 type may
229 // force all subsequent operations to be performed on a non-native type.
230 isl_ast_expr_free(Expr
);
234 Value
*IslExprBuilder::createAccessAddress(isl_ast_expr
*Expr
) {
235 assert(isl_ast_expr_get_type(Expr
) == isl_ast_expr_op
&&
236 "isl ast expression not of type isl_ast_op");
237 assert(isl_ast_expr_get_op_type(Expr
) == isl_ast_op_access
&&
238 "not an access isl ast expression");
239 assert(isl_ast_expr_get_op_n_arg(Expr
) >= 1 &&
240 "We need at least two operands to create a member access.");
242 Value
*Base
, *IndexOp
, *Access
;
243 isl_ast_expr
*BaseExpr
;
246 BaseExpr
= isl_ast_expr_get_op_arg(Expr
, 0);
247 BaseId
= isl_ast_expr_get_id(BaseExpr
);
248 isl_ast_expr_free(BaseExpr
);
250 const ScopArrayInfo
*SAI
= nullptr;
252 if (PollyDebugPrinting
)
253 RuntimeDebugBuilder::createCPUPrinter(Builder
, isl_id_get_name(BaseId
));
256 SAI
= (*IDToSAI
)[BaseId
];
259 SAI
= ScopArrayInfo::getFromId(isl::manage(BaseId
));
263 assert(SAI
&& "No ScopArrayInfo found for this isl_id.");
265 Base
= SAI
->getBasePtr();
267 if (auto NewBase
= GlobalMap
.lookup(Base
))
270 assert(Base
->getType()->isPointerTy() && "Access base should be a pointer");
271 StringRef BaseName
= Base
->getName();
273 auto PointerTy
= PointerType::get(SAI
->getElementType(),
274 Base
->getType()->getPointerAddressSpace());
275 if (Base
->getType() != PointerTy
) {
277 Builder
.CreateBitCast(Base
, PointerTy
, "polly.access.cast." + BaseName
);
280 if (isl_ast_expr_get_op_n_arg(Expr
) == 1) {
281 isl_ast_expr_free(Expr
);
282 if (PollyDebugPrinting
)
283 RuntimeDebugBuilder::createCPUPrinter(Builder
, "\n");
288 for (unsigned u
= 1, e
= isl_ast_expr_get_op_n_arg(Expr
); u
< e
; u
++) {
289 Value
*NextIndex
= create(isl_ast_expr_get_op_arg(Expr
, u
));
290 assert(NextIndex
->getType()->isIntegerTy() &&
291 "Access index should be an integer");
293 if (PollyDebugPrinting
)
294 RuntimeDebugBuilder::createCPUPrinter(Builder
, "[", NextIndex
, "]");
299 Type
*Ty
= getWidestType(NextIndex
->getType(), IndexOp
->getType());
301 if (Ty
!= NextIndex
->getType())
302 NextIndex
= Builder
.CreateIntCast(NextIndex
, Ty
, true);
303 if (Ty
!= IndexOp
->getType())
304 IndexOp
= Builder
.CreateIntCast(IndexOp
, Ty
, true);
306 IndexOp
= createAdd(IndexOp
, NextIndex
, "polly.access.add." + BaseName
);
309 // For every but the last dimension multiply the size, for the last
310 // dimension we can exit the loop.
314 const SCEV
*DimSCEV
= SAI
->getDimensionSize(u
);
316 llvm::ValueToSCEVMapTy Map
;
317 for (auto &KV
: GlobalMap
)
318 Map
[KV
.first
] = SE
.getSCEV(KV
.second
);
319 DimSCEV
= SCEVParameterRewriter::rewrite(DimSCEV
, SE
, Map
);
321 expandCodeFor(S
, SE
, DL
, "polly", DimSCEV
, DimSCEV
->getType(),
322 &*Builder
.GetInsertPoint(), nullptr,
323 StartBlock
->getSinglePredecessor());
325 Type
*Ty
= getWidestType(DimSize
->getType(), IndexOp
->getType());
327 if (Ty
!= IndexOp
->getType())
328 IndexOp
= Builder
.CreateSExtOrTrunc(IndexOp
, Ty
,
329 "polly.access.sext." + BaseName
);
330 if (Ty
!= DimSize
->getType())
331 DimSize
= Builder
.CreateSExtOrTrunc(DimSize
, Ty
,
332 "polly.access.sext." + BaseName
);
333 IndexOp
= createMul(IndexOp
, DimSize
, "polly.access.mul." + BaseName
);
336 Access
= Builder
.CreateGEP(Base
, IndexOp
, "polly.access." + BaseName
);
338 if (PollyDebugPrinting
)
339 RuntimeDebugBuilder::createCPUPrinter(Builder
, "\n");
340 isl_ast_expr_free(Expr
);
344 Value
*IslExprBuilder::createOpAccess(isl_ast_expr
*Expr
) {
345 Value
*Addr
= createAccessAddress(Expr
);
346 assert(Addr
&& "Could not create op access address");
347 return Builder
.CreateLoad(Addr
, Addr
->getName() + ".load");
350 Value
*IslExprBuilder::createOpBin(__isl_take isl_ast_expr
*Expr
) {
351 Value
*LHS
, *RHS
, *Res
;
353 isl_ast_op_type OpType
;
355 assert(isl_ast_expr_get_type(Expr
) == isl_ast_expr_op
&&
356 "isl ast expression not of type isl_ast_op");
357 assert(isl_ast_expr_get_op_n_arg(Expr
) == 2 &&
358 "not a binary isl ast expression");
360 OpType
= isl_ast_expr_get_op_type(Expr
);
362 LHS
= create(isl_ast_expr_get_op_arg(Expr
, 0));
363 RHS
= create(isl_ast_expr_get_op_arg(Expr
, 1));
365 Type
*LHSType
= LHS
->getType();
366 Type
*RHSType
= RHS
->getType();
368 MaxType
= getWidestType(LHSType
, RHSType
);
370 // Take the result into account when calculating the widest type.
372 // For operations such as '+' the result may require a type larger than
373 // the type of the individual operands. For other operations such as '/', the
374 // result type cannot be larger than the type of the individual operand. isl
375 // does not calculate correct types for these operations and we consequently
376 // exclude those operations here.
378 case isl_ast_op_pdiv_q
:
379 case isl_ast_op_pdiv_r
:
381 case isl_ast_op_fdiv_q
:
382 case isl_ast_op_zdiv_r
:
388 MaxType
= getWidestType(MaxType
, getType(Expr
));
391 llvm_unreachable("This is no binary isl ast expression");
394 if (MaxType
!= RHS
->getType())
395 RHS
= Builder
.CreateSExt(RHS
, MaxType
);
397 if (MaxType
!= LHS
->getType())
398 LHS
= Builder
.CreateSExt(LHS
, MaxType
);
402 llvm_unreachable("This is no binary isl ast expression");
404 Res
= createAdd(LHS
, RHS
);
407 Res
= createSub(LHS
, RHS
);
410 Res
= createMul(LHS
, RHS
);
413 Res
= Builder
.CreateSDiv(LHS
, RHS
, "pexp.div", true);
415 case isl_ast_op_pdiv_q
: // Dividend is non-negative
416 Res
= Builder
.CreateUDiv(LHS
, RHS
, "pexp.p_div_q");
418 case isl_ast_op_fdiv_q
: { // Round towards -infty
419 if (auto *Const
= dyn_cast
<ConstantInt
>(RHS
)) {
420 auto &Val
= Const
->getValue();
421 if (Val
.isPowerOf2() && Val
.isNonNegative()) {
422 Res
= Builder
.CreateAShr(LHS
, Val
.ceilLogBase2(), "polly.fdiv_q.shr");
426 // TODO: Review code and check that this calculation does not yield
427 // incorrect overflow in some edge cases.
429 // floord(n,d) ((n < 0) ? (n - d + 1) : n) / d
430 Value
*One
= ConstantInt::get(MaxType
, 1);
431 Value
*Zero
= ConstantInt::get(MaxType
, 0);
432 Value
*Sum1
= createSub(LHS
, RHS
, "pexp.fdiv_q.0");
433 Value
*Sum2
= createAdd(Sum1
, One
, "pexp.fdiv_q.1");
434 Value
*isNegative
= Builder
.CreateICmpSLT(LHS
, Zero
, "pexp.fdiv_q.2");
436 Builder
.CreateSelect(isNegative
, Sum2
, LHS
, "pexp.fdiv_q.3");
437 Res
= Builder
.CreateSDiv(Dividend
, RHS
, "pexp.fdiv_q.4");
440 case isl_ast_op_pdiv_r
: // Dividend is non-negative
441 Res
= Builder
.CreateURem(LHS
, RHS
, "pexp.pdiv_r");
444 case isl_ast_op_zdiv_r
: // Result only compared against zero
445 Res
= Builder
.CreateSRem(LHS
, RHS
, "pexp.zdiv_r");
449 // TODO: We can truncate the result, if it fits into a smaller type. This can
450 // help in cases where we have larger operands (e.g. i67) but the result is
451 // known to fit into i64. Without the truncation, the larger i67 type may
452 // force all subsequent operations to be performed on a non-native type.
453 isl_ast_expr_free(Expr
);
457 Value
*IslExprBuilder::createOpSelect(__isl_take isl_ast_expr
*Expr
) {
458 assert(isl_ast_expr_get_op_type(Expr
) == isl_ast_op_select
&&
459 "Unsupported unary isl ast expression");
460 Value
*LHS
, *RHS
, *Cond
;
461 Type
*MaxType
= getType(Expr
);
463 Cond
= create(isl_ast_expr_get_op_arg(Expr
, 0));
464 if (!Cond
->getType()->isIntegerTy(1))
465 Cond
= Builder
.CreateIsNotNull(Cond
);
467 LHS
= create(isl_ast_expr_get_op_arg(Expr
, 1));
468 RHS
= create(isl_ast_expr_get_op_arg(Expr
, 2));
470 MaxType
= getWidestType(MaxType
, LHS
->getType());
471 MaxType
= getWidestType(MaxType
, RHS
->getType());
473 if (MaxType
!= RHS
->getType())
474 RHS
= Builder
.CreateSExt(RHS
, MaxType
);
476 if (MaxType
!= LHS
->getType())
477 LHS
= Builder
.CreateSExt(LHS
, MaxType
);
479 // TODO: Do we want to truncate the result?
480 isl_ast_expr_free(Expr
);
481 return Builder
.CreateSelect(Cond
, LHS
, RHS
);
484 Value
*IslExprBuilder::createOpICmp(__isl_take isl_ast_expr
*Expr
) {
485 assert(isl_ast_expr_get_type(Expr
) == isl_ast_expr_op
&&
486 "Expected an isl_ast_expr_op expression");
488 Value
*LHS
, *RHS
, *Res
;
490 auto *Op0
= isl_ast_expr_get_op_arg(Expr
, 0);
491 auto *Op1
= isl_ast_expr_get_op_arg(Expr
, 1);
492 bool HasNonAddressOfOperand
=
493 isl_ast_expr_get_type(Op0
) != isl_ast_expr_op
||
494 isl_ast_expr_get_type(Op1
) != isl_ast_expr_op
||
495 isl_ast_expr_get_op_type(Op0
) != isl_ast_op_address_of
||
496 isl_ast_expr_get_op_type(Op1
) != isl_ast_op_address_of
;
501 auto *LHSTy
= LHS
->getType();
502 auto *RHSTy
= RHS
->getType();
503 bool IsPtrType
= LHSTy
->isPointerTy() || RHSTy
->isPointerTy();
504 bool UseUnsignedCmp
= IsPtrType
&& !HasNonAddressOfOperand
;
506 auto *PtrAsIntTy
= Builder
.getIntNTy(DL
.getPointerSizeInBits());
507 if (LHSTy
->isPointerTy())
508 LHS
= Builder
.CreatePtrToInt(LHS
, PtrAsIntTy
);
509 if (RHSTy
->isPointerTy())
510 RHS
= Builder
.CreatePtrToInt(RHS
, PtrAsIntTy
);
512 if (LHS
->getType() != RHS
->getType()) {
513 Type
*MaxType
= LHS
->getType();
514 MaxType
= getWidestType(MaxType
, RHS
->getType());
516 if (MaxType
!= RHS
->getType())
517 RHS
= Builder
.CreateSExt(RHS
, MaxType
);
519 if (MaxType
!= LHS
->getType())
520 LHS
= Builder
.CreateSExt(LHS
, MaxType
);
523 isl_ast_op_type OpType
= isl_ast_expr_get_op_type(Expr
);
524 assert(OpType
>= isl_ast_op_eq
&& OpType
<= isl_ast_op_gt
&&
525 "Unsupported ICmp isl ast expression");
526 assert(isl_ast_op_eq
+ 4 == isl_ast_op_gt
&&
527 "Isl ast op type interface changed");
529 CmpInst::Predicate Predicates
[5][2] = {
530 {CmpInst::ICMP_EQ
, CmpInst::ICMP_EQ
},
531 {CmpInst::ICMP_SLE
, CmpInst::ICMP_ULE
},
532 {CmpInst::ICMP_SLT
, CmpInst::ICMP_ULT
},
533 {CmpInst::ICMP_SGE
, CmpInst::ICMP_UGE
},
534 {CmpInst::ICMP_SGT
, CmpInst::ICMP_UGT
},
537 Res
= Builder
.CreateICmp(Predicates
[OpType
- isl_ast_op_eq
][UseUnsignedCmp
],
540 isl_ast_expr_free(Expr
);
544 Value
*IslExprBuilder::createOpBoolean(__isl_take isl_ast_expr
*Expr
) {
545 assert(isl_ast_expr_get_type(Expr
) == isl_ast_expr_op
&&
546 "Expected an isl_ast_expr_op expression");
548 Value
*LHS
, *RHS
, *Res
;
549 isl_ast_op_type OpType
;
551 OpType
= isl_ast_expr_get_op_type(Expr
);
553 assert((OpType
== isl_ast_op_and
|| OpType
== isl_ast_op_or
) &&
554 "Unsupported isl_ast_op_type");
556 LHS
= create(isl_ast_expr_get_op_arg(Expr
, 0));
557 RHS
= create(isl_ast_expr_get_op_arg(Expr
, 1));
559 // Even though the isl pretty printer prints the expressions as 'exp && exp'
560 // or 'exp || exp', we actually code generate the bitwise expressions
561 // 'exp & exp' or 'exp | exp'. This forces the evaluation of both branches,
562 // but it is, due to the use of i1 types, otherwise equivalent. The reason
563 // to go for bitwise operations is, that we assume the reduced control flow
564 // will outweigh the overhead introduced by evaluating unneeded expressions.
565 // The isl code generation currently does not take advantage of the fact that
566 // the expression after an '||' or '&&' is in some cases not evaluated.
567 // Evaluating it anyways does not cause any undefined behaviour.
569 // TODO: Document in isl itself, that the unconditionally evaluating the
570 // second part of '||' or '&&' expressions is safe.
571 if (!LHS
->getType()->isIntegerTy(1))
572 LHS
= Builder
.CreateIsNotNull(LHS
);
573 if (!RHS
->getType()->isIntegerTy(1))
574 RHS
= Builder
.CreateIsNotNull(RHS
);
578 llvm_unreachable("Unsupported boolean expression");
580 Res
= Builder
.CreateAnd(LHS
, RHS
);
583 Res
= Builder
.CreateOr(LHS
, RHS
);
587 isl_ast_expr_free(Expr
);
592 IslExprBuilder::createOpBooleanConditional(__isl_take isl_ast_expr
*Expr
) {
593 assert(isl_ast_expr_get_type(Expr
) == isl_ast_expr_op
&&
594 "Expected an isl_ast_expr_op expression");
597 isl_ast_op_type OpType
;
599 Function
*F
= Builder
.GetInsertBlock()->getParent();
600 LLVMContext
&Context
= F
->getContext();
602 OpType
= isl_ast_expr_get_op_type(Expr
);
604 assert((OpType
== isl_ast_op_and_then
|| OpType
== isl_ast_op_or_else
) &&
605 "Unsupported isl_ast_op_type");
607 auto InsertBB
= Builder
.GetInsertBlock();
608 auto InsertPoint
= Builder
.GetInsertPoint();
609 auto NextBB
= SplitBlock(InsertBB
, &*InsertPoint
, &DT
, &LI
);
610 BasicBlock
*CondBB
= BasicBlock::Create(Context
, "polly.cond", F
);
611 LI
.changeLoopFor(CondBB
, LI
.getLoopFor(InsertBB
));
612 DT
.addNewBlock(CondBB
, InsertBB
);
614 InsertBB
->getTerminator()->eraseFromParent();
615 Builder
.SetInsertPoint(InsertBB
);
616 auto BR
= Builder
.CreateCondBr(Builder
.getTrue(), NextBB
, CondBB
);
618 Builder
.SetInsertPoint(CondBB
);
619 Builder
.CreateBr(NextBB
);
621 Builder
.SetInsertPoint(InsertBB
->getTerminator());
623 LHS
= create(isl_ast_expr_get_op_arg(Expr
, 0));
624 if (!LHS
->getType()->isIntegerTy(1))
625 LHS
= Builder
.CreateIsNotNull(LHS
);
626 auto LeftBB
= Builder
.GetInsertBlock();
628 if (OpType
== isl_ast_op_and
|| OpType
== isl_ast_op_and_then
)
629 BR
->setCondition(Builder
.CreateNeg(LHS
));
631 BR
->setCondition(LHS
);
633 Builder
.SetInsertPoint(CondBB
->getTerminator());
634 RHS
= create(isl_ast_expr_get_op_arg(Expr
, 1));
635 if (!RHS
->getType()->isIntegerTy(1))
636 RHS
= Builder
.CreateIsNotNull(RHS
);
637 auto RightBB
= Builder
.GetInsertBlock();
639 Builder
.SetInsertPoint(NextBB
->getTerminator());
640 auto PHI
= Builder
.CreatePHI(Builder
.getInt1Ty(), 2);
641 PHI
->addIncoming(OpType
== isl_ast_op_and_then
? Builder
.getFalse()
644 PHI
->addIncoming(RHS
, RightBB
);
646 isl_ast_expr_free(Expr
);
650 Value
*IslExprBuilder::createOp(__isl_take isl_ast_expr
*Expr
) {
651 assert(isl_ast_expr_get_type(Expr
) == isl_ast_expr_op
&&
652 "Expression not of type isl_ast_expr_op");
653 switch (isl_ast_expr_get_op_type(Expr
)) {
654 case isl_ast_op_error
:
655 case isl_ast_op_cond
:
656 case isl_ast_op_call
:
657 case isl_ast_op_member
:
658 llvm_unreachable("Unsupported isl ast expression");
659 case isl_ast_op_access
:
660 return createOpAccess(Expr
);
663 return createOpNAry(Expr
);
668 case isl_ast_op_fdiv_q
: // Round towards -infty
669 case isl_ast_op_pdiv_q
: // Dividend is non-negative
670 case isl_ast_op_pdiv_r
: // Dividend is non-negative
671 case isl_ast_op_zdiv_r
: // Result only compared against zero
672 return createOpBin(Expr
);
673 case isl_ast_op_minus
:
674 return createOpUnary(Expr
);
675 case isl_ast_op_select
:
676 return createOpSelect(Expr
);
679 return createOpBoolean(Expr
);
680 case isl_ast_op_and_then
:
681 case isl_ast_op_or_else
:
682 return createOpBooleanConditional(Expr
);
688 return createOpICmp(Expr
);
689 case isl_ast_op_address_of
:
690 return createOpAddressOf(Expr
);
693 llvm_unreachable("Unsupported isl_ast_expr_op kind.");
696 Value
*IslExprBuilder::createOpAddressOf(__isl_take isl_ast_expr
*Expr
) {
697 assert(isl_ast_expr_get_type(Expr
) == isl_ast_expr_op
&&
698 "Expected an isl_ast_expr_op expression.");
699 assert(isl_ast_expr_get_op_n_arg(Expr
) == 1 && "Address of should be unary.");
701 isl_ast_expr
*Op
= isl_ast_expr_get_op_arg(Expr
, 0);
702 assert(isl_ast_expr_get_type(Op
) == isl_ast_expr_op
&&
703 "Expected address of operator to be an isl_ast_expr_op expression.");
704 assert(isl_ast_expr_get_op_type(Op
) == isl_ast_op_access
&&
705 "Expected address of operator to be an access expression.");
707 Value
*V
= createAccessAddress(Op
);
709 isl_ast_expr_free(Expr
);
714 Value
*IslExprBuilder::createId(__isl_take isl_ast_expr
*Expr
) {
715 assert(isl_ast_expr_get_type(Expr
) == isl_ast_expr_id
&&
716 "Expression not of type isl_ast_expr_ident");
721 Id
= isl_ast_expr_get_id(Expr
);
723 assert(IDToValue
.count(Id
) && "Identifier not found");
727 V
= UndefValue::get(getType(Expr
));
729 if (V
->getType()->isPointerTy())
730 V
= Builder
.CreatePtrToInt(V
, Builder
.getIntNTy(DL
.getPointerSizeInBits()));
732 assert(V
&& "Unknown parameter id found");
735 isl_ast_expr_free(Expr
);
740 IntegerType
*IslExprBuilder::getType(__isl_keep isl_ast_expr
*Expr
) {
741 // XXX: We assume i64 is large enough. This is often true, but in general
742 // incorrect. Also, on 32bit architectures, it would be beneficial to
743 // use a smaller type. We can and should directly derive this information
744 // during code generation.
745 return IntegerType::get(Builder
.getContext(), 64);
748 Value
*IslExprBuilder::createInt(__isl_take isl_ast_expr
*Expr
) {
749 assert(isl_ast_expr_get_type(Expr
) == isl_ast_expr_int
&&
750 "Expression not of type isl_ast_expr_int");
756 Val
= isl_ast_expr_get_val(Expr
);
757 APValue
= APIntFromVal(Val
);
759 auto BitWidth
= APValue
.getBitWidth();
763 T
= Builder
.getIntNTy(BitWidth
);
765 APValue
= APValue
.sextOrSelf(T
->getBitWidth());
766 V
= ConstantInt::get(T
, APValue
);
768 isl_ast_expr_free(Expr
);
772 Value
*IslExprBuilder::create(__isl_take isl_ast_expr
*Expr
) {
773 switch (isl_ast_expr_get_type(Expr
)) {
774 case isl_ast_expr_error
:
775 llvm_unreachable("Code generation error");
776 case isl_ast_expr_op
:
777 return createOp(Expr
);
778 case isl_ast_expr_id
:
779 return createId(Expr
);
780 case isl_ast_expr_int
:
781 return createInt(Expr
);
784 llvm_unreachable("Unexpected enum value");