blob: 59e84763b0ecfc2045af0061fcd81def2ba30d43 [file] [log] [blame]
Sebastian Pop082cea82012-05-07 16:20:07 +00001//===------ IslCodeGeneration.cpp - Code generate the Scops using ISL. ----===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// The IslCodeGeneration pass takes a Scop created by ScopInfo and translates it
11// back to LLVM-IR using the ISL code generator.
12//
13// The Scop describes the high level memory behaviour of a control flow region.
14// Transformation passes can update the schedule (execution order) of statements
15// in the Scop. ISL is used to generate an abstract syntax tree that reflects
16// the updated execution order. This clast is used to create new LLVM-IR that is
17// computationally equivalent to the original control flow region, but executes
18// its code in the new execution order defined by the changed scattering.
19//
20//===----------------------------------------------------------------------===//
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +000021#include "polly/Config/config.h"
Tobias Grosser83628182013-05-07 08:11:54 +000022#include "polly/CodeGen/BlockGenerators.h"
23#include "polly/CodeGen/CodeGeneration.h"
24#include "polly/CodeGen/IslAst.h"
25#include "polly/CodeGen/LoopGenerators.h"
26#include "polly/CodeGen/Utils.h"
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +000027#include "polly/Dependences.h"
28#include "polly/LinkAllPasses.h"
29#include "polly/ScopInfo.h"
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +000030#include "polly/Support/GICHelper.h"
Tobias Grosser0ee50f62013-04-10 06:55:31 +000031#include "polly/Support/ScopHelper.h"
Tobias Grosser83628182013-05-07 08:11:54 +000032#include "polly/TempScopInfo.h"
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +000033#include "llvm/Analysis/LoopInfo.h"
Matt Arsenault8ca36812014-07-19 18:40:17 +000034#include "llvm/Analysis/PostDominators.h"
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +000035#include "llvm/Analysis/ScalarEvolutionExpander.h"
Tobias Grosser83628182013-05-07 08:11:54 +000036#include "llvm/IR/Module.h"
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +000037#include "llvm/Support/CommandLine.h"
38#include "llvm/Support/Debug.h"
Chandler Carruth535d52c2013-01-02 11:47:44 +000039#include "llvm/IR/DataLayout.h"
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +000040#include "llvm/Transforms/Utils/BasicBlockUtils.h"
41
42#include "isl/union_map.h"
43#include "isl/list.h"
44#include "isl/ast.h"
45#include "isl/ast_build.h"
46#include "isl/set.h"
47#include "isl/map.h"
48#include "isl/aff.h"
49
50#include <map>
51
52using namespace polly;
53using namespace llvm;
54
Chandler Carruth95fef942014-04-22 03:30:19 +000055#define DEBUG_TYPE "polly-codegen-isl"
56
Tobias Grosser9818bc82014-04-22 14:26:51 +000057/// @brief LLVM-IR generator for isl_ast_expr[essions]
58///
59/// This generator generates LLVM-IR that performs the computation described by
60/// an isl_ast_expr[ession].
61///
62/// Example:
63///
64/// An isl_ast_expr[ession] can look like this:
65///
66/// (N + M) + 10
67///
68/// The IslExprBuilder could create the following LLVM-IR:
69///
70/// %tmp1 = add nsw i64 %N
71/// %tmp2 = add nsw i64 %tmp1, %M
72/// %tmp3 = add nsw i64 %tmp2, 10
73///
74/// The implementation of this class is mostly a mapping from isl_ast_expr
75/// constructs to the corresponding LLVM-IR constructs.
76///
77/// The following decisions may need some explanation:
78///
79/// 1) Which data-type to choose
80///
81/// isl_ast_expr[essions] are untyped expressions that assume arbitrary
82/// precision integer computations. LLVM-IR instead has fixed size integers.
83/// When lowering to LLVM-IR we need to chose both the size of the data type and
84/// the sign of the operations we use.
85///
86/// At the moment, we hardcode i64 bit signed computations. Our experience has
87/// shown that 64 bit are generally large enough for the loop bounds that appear
88/// in the wild. Signed computations are needed, as loop bounds may become
89/// negative.
90///
91/// FIXME: Hardcoding sizes can cause issues:
92///
93/// a) Certain run-time checks that we may want to generate can involve the
94/// size of the data types the computation is performed on. When code
95/// generating these run-time checks to isl_ast_expr[essions], the
96/// resulting computation may require more than 64 bit.
97///
98/// b) On embedded systems and especially for high-level-synthesis 64 bit
99/// computations are very costly.
100///
101/// The right approach is to compute the minimal necessary bitwidth and
102/// signedness for each subexpression during in the isl AST generation and
103/// to use this information in our IslAstGenerator. Preliminary patches are
104/// available, but have not been committed yet.
105///
106/// 2) We always flag computations with 'nsw'
107///
108/// As isl_ast_expr[essions] assume arbitrary precision, no wrapping should
109/// ever occur in the generated LLVM-IR (assuming the data type chosen is large
110/// enough).
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000111class IslExprBuilder {
112public:
Tobias Grosser9818bc82014-04-22 14:26:51 +0000113 /// @brief Construct an IslExprBuilder.
114 ///
115 /// @param Builder The IRBuilder used to construct the isl_ast_expr[ession].
116 /// The insert location of this IRBuilder defines WHERE the
117 /// corresponding LLVM-IR is generated.
118 ///
119 /// @param IDToValue The isl_ast_expr[ession] may reference parameters or
120 /// variables (identified by an isl_id). The IDTOValue map
121 /// specifies the LLVM-IR Values that correspond to these
122 /// parameters and variables.
Tobias Grosser5103ba72014-03-04 14:58:49 +0000123 IslExprBuilder(PollyIRBuilder &Builder,
Tobias Grosser9818bc82014-04-22 14:26:51 +0000124 std::map<isl_id *, Value *> &IDToValue)
Tobias Grosser7242ad92013-02-22 08:07:06 +0000125 : Builder(Builder), IDToValue(IDToValue) {}
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000126
Tobias Grosser9818bc82014-04-22 14:26:51 +0000127 /// @brief Create LLVM-IR for an isl_ast_expr[ession].
128 ///
129 /// @param Expr The ast expression for which we generate LLVM-IR.
130 ///
131 /// @return The llvm::Value* containing the result of the computation.
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000132 Value *create(__isl_take isl_ast_expr *Expr);
Tobias Grosser9818bc82014-04-22 14:26:51 +0000133
134 /// @brief Return the largest of two types.
135 ///
136 /// @param T1 The first type.
137 /// @param T2 The second type.
138 ///
139 /// @return The largest of the two types.
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000140 Type *getWidestType(Type *T1, Type *T2);
Tobias Grosser9818bc82014-04-22 14:26:51 +0000141
142 /// @brief Return the type with which this expression should be computed.
143 ///
144 /// The type needs to be large enough to hold all possible input and all
145 /// possible output values.
146 ///
147 /// @param Expr The expression for which to find the type.
148 /// @return The type with which the expression should be computed.
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000149 IntegerType *getType(__isl_keep isl_ast_expr *Expr);
150
151private:
Tobias Grosser5103ba72014-03-04 14:58:49 +0000152 PollyIRBuilder &Builder;
Tobias Grosserc14582f2013-02-05 18:01:29 +0000153 std::map<isl_id *, Value *> &IDToValue;
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000154
155 Value *createOp(__isl_take isl_ast_expr *Expr);
156 Value *createOpUnary(__isl_take isl_ast_expr *Expr);
157 Value *createOpBin(__isl_take isl_ast_expr *Expr);
158 Value *createOpNAry(__isl_take isl_ast_expr *Expr);
159 Value *createOpSelect(__isl_take isl_ast_expr *Expr);
160 Value *createOpICmp(__isl_take isl_ast_expr *Expr);
161 Value *createOpBoolean(__isl_take isl_ast_expr *Expr);
162 Value *createId(__isl_take isl_ast_expr *Expr);
163 Value *createInt(__isl_take isl_ast_expr *Expr);
164};
165
166Type *IslExprBuilder::getWidestType(Type *T1, Type *T2) {
167 assert(isa<IntegerType>(T1) && isa<IntegerType>(T2));
168
169 if (T1->getPrimitiveSizeInBits() < T2->getPrimitiveSizeInBits())
170 return T2;
171 else
172 return T1;
173}
174
175Value *IslExprBuilder::createOpUnary(__isl_take isl_ast_expr *Expr) {
Tobias Grosserae2d83e2012-12-29 23:57:18 +0000176 assert(isl_ast_expr_get_op_type(Expr) == isl_ast_op_minus &&
177 "Unsupported unary operation");
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000178
179 Value *V;
180 Type *MaxType = getType(Expr);
181
182 V = create(isl_ast_expr_get_op_arg(Expr, 0));
183 MaxType = getWidestType(MaxType, V->getType());
184
185 if (MaxType != V->getType())
186 V = Builder.CreateSExt(V, MaxType);
187
188 isl_ast_expr_free(Expr);
189 return Builder.CreateNSWNeg(V);
190}
191
192Value *IslExprBuilder::createOpNAry(__isl_take isl_ast_expr *Expr) {
Tobias Grosserae2d83e2012-12-29 23:57:18 +0000193 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");
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000197
198 Value *V;
199
200 V = create(isl_ast_expr_get_op_arg(Expr, 0));
201
202 for (int i = 0; i < isl_ast_expr_get_op_n_arg(Expr); ++i) {
203 Value *OpV;
204 OpV = create(isl_ast_expr_get_op_arg(Expr, i));
205
206 Type *Ty = getWidestType(V->getType(), OpV->getType());
207
208 if (Ty != OpV->getType())
209 OpV = Builder.CreateSExt(OpV, Ty);
210
211 if (Ty != V->getType())
212 V = Builder.CreateSExt(V, Ty);
213
214 switch (isl_ast_expr_get_op_type(Expr)) {
215 default:
216 llvm_unreachable("This is no n-ary isl ast expression");
217
Tobias Grosserc14582f2013-02-05 18:01:29 +0000218 case isl_ast_op_max: {
219 Value *Cmp = Builder.CreateICmpSGT(V, OpV);
220 V = Builder.CreateSelect(Cmp, V, OpV);
221 continue;
222 }
223 case isl_ast_op_min: {
224 Value *Cmp = Builder.CreateICmpSLT(V, OpV);
225 V = Builder.CreateSelect(Cmp, V, OpV);
226 continue;
227 }
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000228 }
229 }
230
231 // TODO: We can truncate the result, if it fits into a smaller type. This can
232 // help in cases where we have larger operands (e.g. i67) but the result is
233 // known to fit into i64. Without the truncation, the larger i67 type may
234 // force all subsequent operations to be performed on a non-native type.
235 isl_ast_expr_free(Expr);
236 return V;
237}
238
239Value *IslExprBuilder::createOpBin(__isl_take isl_ast_expr *Expr) {
240 Value *LHS, *RHS, *Res;
241 Type *MaxType;
242 isl_ast_op_type OpType;
243
Tobias Grosserae2d83e2012-12-29 23:57:18 +0000244 assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
245 "isl ast expression not of type isl_ast_op");
246 assert(isl_ast_expr_get_op_n_arg(Expr) == 2 &&
247 "not a binary isl ast expression");
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000248
249 OpType = isl_ast_expr_get_op_type(Expr);
250
251 LHS = create(isl_ast_expr_get_op_arg(Expr, 0));
252 RHS = create(isl_ast_expr_get_op_arg(Expr, 1));
253
254 MaxType = LHS->getType();
255 MaxType = getWidestType(MaxType, RHS->getType());
256
257 // Take the result into account when calculating the widest type.
258 //
259 // For operations such as '+' the result may require a type larger than
260 // the type of the individual operands. For other operations such as '/', the
261 // result type cannot be larger than the type of the individual operand. isl
262 // does not calculate correct types for these operations and we consequently
263 // exclude those operations here.
Tobias Grosser1bb59b02012-12-29 23:47:38 +0000264 switch (OpType) {
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000265 case isl_ast_op_pdiv_q:
266 case isl_ast_op_pdiv_r:
267 case isl_ast_op_div:
268 case isl_ast_op_fdiv_q:
269 // Do nothing
270 break;
271 case isl_ast_op_add:
272 case isl_ast_op_sub:
273 case isl_ast_op_mul:
274 MaxType = getWidestType(MaxType, getType(Expr));
275 break;
276 default:
277 llvm_unreachable("This is no binary isl ast expression");
278 }
279
280 if (MaxType != RHS->getType())
281 RHS = Builder.CreateSExt(RHS, MaxType);
282
283 if (MaxType != LHS->getType())
284 LHS = Builder.CreateSExt(LHS, MaxType);
285
286 switch (OpType) {
287 default:
288 llvm_unreachable("This is no binary isl ast expression");
289 case isl_ast_op_add:
290 Res = Builder.CreateNSWAdd(LHS, RHS);
291 break;
292 case isl_ast_op_sub:
293 Res = Builder.CreateNSWSub(LHS, RHS);
294 break;
295 case isl_ast_op_mul:
296 Res = Builder.CreateNSWMul(LHS, RHS);
297 break;
298 case isl_ast_op_div:
299 case isl_ast_op_pdiv_q: // Dividend is non-negative
300 Res = Builder.CreateSDiv(LHS, RHS);
301 break;
Tobias Grosserc14582f2013-02-05 18:01:29 +0000302 case isl_ast_op_fdiv_q: { // Round towards -infty
303 // TODO: Review code and check that this calculation does not yield
304 // incorrect overflow in some bordercases.
305 //
306 // floord(n,d) ((n < 0) ? (n - d + 1) : n) / d
307 Value *One = ConstantInt::get(MaxType, 1);
308 Value *Zero = ConstantInt::get(MaxType, 0);
309 Value *Sum1 = Builder.CreateSub(LHS, RHS);
310 Value *Sum2 = Builder.CreateAdd(Sum1, One);
311 Value *isNegative = Builder.CreateICmpSLT(LHS, Zero);
312 Value *Dividend = Builder.CreateSelect(isNegative, Sum2, LHS);
313 Res = Builder.CreateSDiv(Dividend, RHS);
314 break;
315 }
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000316 case isl_ast_op_pdiv_r: // Dividend is non-negative
317 Res = Builder.CreateSRem(LHS, RHS);
318 break;
319 }
320
321 // TODO: We can truncate the result, if it fits into a smaller type. This can
322 // help in cases where we have larger operands (e.g. i67) but the result is
323 // known to fit into i64. Without the truncation, the larger i67 type may
324 // force all subsequent operations to be performed on a non-native type.
325 isl_ast_expr_free(Expr);
326 return Res;
327}
328
329Value *IslExprBuilder::createOpSelect(__isl_take isl_ast_expr *Expr) {
Tobias Grosserae2d83e2012-12-29 23:57:18 +0000330 assert(isl_ast_expr_get_op_type(Expr) == isl_ast_op_select &&
331 "Unsupported unary isl ast expression");
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000332 Value *LHS, *RHS, *Cond;
333 Type *MaxType = getType(Expr);
334
335 Cond = create(isl_ast_expr_get_op_arg(Expr, 0));
336
337 LHS = create(isl_ast_expr_get_op_arg(Expr, 1));
338 RHS = create(isl_ast_expr_get_op_arg(Expr, 2));
339
340 MaxType = getWidestType(MaxType, LHS->getType());
341 MaxType = getWidestType(MaxType, RHS->getType());
342
343 if (MaxType != RHS->getType())
344 RHS = Builder.CreateSExt(RHS, MaxType);
345
346 if (MaxType != LHS->getType())
347 LHS = Builder.CreateSExt(LHS, MaxType);
348
349 // TODO: Do we want to truncate the result?
350 isl_ast_expr_free(Expr);
351 return Builder.CreateSelect(Cond, LHS, RHS);
352}
353
354Value *IslExprBuilder::createOpICmp(__isl_take isl_ast_expr *Expr) {
355 assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
356 "Expected an isl_ast_expr_op expression");
357
358 Value *LHS, *RHS, *Res;
359
360 LHS = create(isl_ast_expr_get_op_arg(Expr, 0));
361 RHS = create(isl_ast_expr_get_op_arg(Expr, 1));
362
363 Type *MaxType = LHS->getType();
364 MaxType = getWidestType(MaxType, RHS->getType());
365
366 if (MaxType != RHS->getType())
367 RHS = Builder.CreateSExt(RHS, MaxType);
368
369 if (MaxType != LHS->getType())
370 LHS = Builder.CreateSExt(LHS, MaxType);
371
372 switch (isl_ast_expr_get_op_type(Expr)) {
373 default:
374 llvm_unreachable("Unsupported ICmp isl ast expression");
375 case isl_ast_op_eq:
376 Res = Builder.CreateICmpEQ(LHS, RHS);
377 break;
378 case isl_ast_op_le:
379 Res = Builder.CreateICmpSLE(LHS, RHS);
380 break;
Tobias Grosserc967d8e2012-10-16 07:29:13 +0000381 case isl_ast_op_lt:
382 Res = Builder.CreateICmpSLT(LHS, RHS);
383 break;
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000384 case isl_ast_op_ge:
385 Res = Builder.CreateICmpSGE(LHS, RHS);
386 break;
Tobias Grosserc967d8e2012-10-16 07:29:13 +0000387 case isl_ast_op_gt:
388 Res = Builder.CreateICmpSGT(LHS, RHS);
389 break;
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000390 }
391
392 isl_ast_expr_free(Expr);
393 return Res;
394}
395
396Value *IslExprBuilder::createOpBoolean(__isl_take isl_ast_expr *Expr) {
397 assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
398 "Expected an isl_ast_expr_op expression");
399
400 Value *LHS, *RHS, *Res;
401 isl_ast_op_type OpType;
402
403 OpType = isl_ast_expr_get_op_type(Expr);
404
405 assert((OpType == isl_ast_op_and || OpType == isl_ast_op_or) &&
406 "Unsupported isl_ast_op_type");
407
408 LHS = create(isl_ast_expr_get_op_arg(Expr, 0));
409 RHS = create(isl_ast_expr_get_op_arg(Expr, 1));
410
411 // Even though the isl pretty printer prints the expressions as 'exp && exp'
412 // or 'exp || exp', we actually code generate the bitwise expressions
413 // 'exp & exp' or 'exp | exp'. This forces the evaluation of both branches,
414 // but it is, due to the use of i1 types, otherwise equivalent. The reason
415 // to go for bitwise operations is, that we assume the reduced control flow
416 // will outweight the overhead introduced by evaluating unneeded expressions.
417 // The isl code generation currently does not take advantage of the fact that
418 // the expression after an '||' or '&&' is in some cases not evaluated.
419 // Evaluating it anyways does not cause any undefined behaviour.
420 //
421 // TODO: Document in isl itself, that the unconditionally evaluating the
422 // second part of '||' or '&&' expressions is safe.
423 assert(LHS->getType() == Builder.getInt1Ty() && "Expected i1 type");
424 assert(RHS->getType() == Builder.getInt1Ty() && "Expected i1 type");
425
426 switch (OpType) {
427 default:
428 llvm_unreachable("Unsupported boolean expression");
429 case isl_ast_op_and:
430 Res = Builder.CreateAnd(LHS, RHS);
431 break;
432 case isl_ast_op_or:
433 Res = Builder.CreateOr(LHS, RHS);
434 break;
435 }
436
437 isl_ast_expr_free(Expr);
438 return Res;
439}
440
441Value *IslExprBuilder::createOp(__isl_take isl_ast_expr *Expr) {
Tobias Grosserae2d83e2012-12-29 23:57:18 +0000442 assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
443 "Expression not of type isl_ast_expr_op");
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000444 switch (isl_ast_expr_get_op_type(Expr)) {
445 case isl_ast_op_error:
446 case isl_ast_op_cond:
447 case isl_ast_op_and_then:
448 case isl_ast_op_or_else:
449 case isl_ast_op_call:
Tobias Grossera38c9242014-01-26 19:36:28 +0000450 case isl_ast_op_member:
451 case isl_ast_op_access:
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000452 llvm_unreachable("Unsupported isl ast expression");
453 case isl_ast_op_max:
454 case isl_ast_op_min:
455 return createOpNAry(Expr);
456 case isl_ast_op_add:
457 case isl_ast_op_sub:
458 case isl_ast_op_mul:
459 case isl_ast_op_div:
460 case isl_ast_op_fdiv_q: // Round towards -infty
461 case isl_ast_op_pdiv_q: // Dividend is non-negative
462 case isl_ast_op_pdiv_r: // Dividend is non-negative
463 return createOpBin(Expr);
464 case isl_ast_op_minus:
465 return createOpUnary(Expr);
466 case isl_ast_op_select:
467 return createOpSelect(Expr);
468 case isl_ast_op_and:
469 case isl_ast_op_or:
470 return createOpBoolean(Expr);
471 case isl_ast_op_eq:
472 case isl_ast_op_le:
Tobias Grosserc967d8e2012-10-16 07:29:13 +0000473 case isl_ast_op_lt:
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000474 case isl_ast_op_ge:
Tobias Grosserc967d8e2012-10-16 07:29:13 +0000475 case isl_ast_op_gt:
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000476 return createOpICmp(Expr);
477 }
478
479 llvm_unreachable("Unsupported isl_ast_expr_op kind.");
480}
481
482Value *IslExprBuilder::createId(__isl_take isl_ast_expr *Expr) {
Tobias Grosserae2d83e2012-12-29 23:57:18 +0000483 assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_id &&
484 "Expression not of type isl_ast_expr_ident");
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000485
486 isl_id *Id;
487 Value *V;
488
489 Id = isl_ast_expr_get_id(Expr);
490
491 assert(IDToValue.count(Id) && "Identifier not found");
492
493 V = IDToValue[Id];
494
495 isl_id_free(Id);
496 isl_ast_expr_free(Expr);
497
498 return V;
499}
500
501IntegerType *IslExprBuilder::getType(__isl_keep isl_ast_expr *Expr) {
502 // XXX: We assume i64 is large enough. This is often true, but in general
503 // incorrect. Also, on 32bit architectures, it would be beneficial to
504 // use a smaller type. We can and should directly derive this information
505 // during code generation.
506 return IntegerType::get(Builder.getContext(), 64);
507}
508
509Value *IslExprBuilder::createInt(__isl_take isl_ast_expr *Expr) {
Tobias Grosserae2d83e2012-12-29 23:57:18 +0000510 assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_int &&
511 "Expression not of type isl_ast_expr_int");
Tobias Grosseredab1352013-06-21 06:41:31 +0000512 isl_val *Val;
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000513 Value *V;
514 APInt APValue;
515 IntegerType *T;
516
Tobias Grosseredab1352013-06-21 06:41:31 +0000517 Val = isl_ast_expr_get_val(Expr);
518 APValue = APIntFromVal(Val);
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000519 T = getType(Expr);
520 APValue = APValue.sextOrSelf(T->getBitWidth());
521 V = ConstantInt::get(T, APValue);
522
523 isl_ast_expr_free(Expr);
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000524 return V;
525}
526
527Value *IslExprBuilder::create(__isl_take isl_ast_expr *Expr) {
528 switch (isl_ast_expr_get_type(Expr)) {
529 case isl_ast_expr_error:
530 llvm_unreachable("Code generation error");
531 case isl_ast_expr_op:
532 return createOp(Expr);
533 case isl_ast_expr_id:
534 return createId(Expr);
535 case isl_ast_expr_int:
536 return createInt(Expr);
537 }
538
539 llvm_unreachable("Unexpected enum value");
540}
541
542class IslNodeBuilder {
543public:
Tobias Grosser37c9b8e2014-03-04 14:59:00 +0000544 IslNodeBuilder(PollyIRBuilder &Builder, LoopAnnotator &Annotator, Pass *P)
Tobias Grosser34c87872014-04-22 16:39:41 +0000545 : Builder(Builder), Annotator(Annotator), ExprBuilder(Builder, IDToValue),
546 P(P) {}
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000547
548 void addParameters(__isl_take isl_set *Context);
549 void create(__isl_take isl_ast_node *Node);
Tobias Grosser54ee0ba2013-11-17 03:18:25 +0000550 IslExprBuilder &getExprBuilder() { return ExprBuilder; }
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000551
552private:
Tobias Grosser5103ba72014-03-04 14:58:49 +0000553 PollyIRBuilder &Builder;
Tobias Grosser37c9b8e2014-03-04 14:59:00 +0000554 LoopAnnotator &Annotator;
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000555 IslExprBuilder ExprBuilder;
556 Pass *P;
557
558 // This maps an isl_id* to the Value* it has in the generated program. For now
559 // on, the only isl_ids that are stored here are the newly calculated loop
560 // ivs.
Tobias Grosserc14582f2013-02-05 18:01:29 +0000561 std::map<isl_id *, Value *> IDToValue;
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000562
563 // Extract the upper bound of this loop
564 //
565 // The isl code generation can generate arbitrary expressions to check if the
566 // upper bound of a loop is reached, but it provides an option to enforce
567 // 'atomic' upper bounds. An 'atomic upper bound is always of the form
568 // iv <= expr, where expr is an (arbitrary) expression not containing iv.
569 //
570 // This function extracts 'atomic' upper bounds. Polly, in general, requires
571 // atomic upper bounds for the following reasons:
572 //
573 // 1. An atomic upper bound is loop invariant
574 //
575 // It must not be calculated at each loop iteration and can often even be
576 // hoisted out further by the loop invariant code motion.
577 //
578 // 2. OpenMP needs a loop invarient upper bound to calculate the number
579 // of loop iterations.
580 //
581 // 3. With the existing code, upper bounds have been easier to implement.
Tobias Grossere602a072013-05-07 07:30:56 +0000582 __isl_give isl_ast_expr *getUpperBound(__isl_keep isl_ast_node *For,
583 CmpInst::Predicate &Predicate);
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000584
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000585 unsigned getNumberOfIterations(__isl_keep isl_ast_node *For);
586
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000587 void createFor(__isl_take isl_ast_node *For);
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000588 void createForVector(__isl_take isl_ast_node *For, int VectorWidth);
589 void createForSequential(__isl_take isl_ast_node *For);
Tobias Grosserce67a042014-07-02 16:26:47 +0000590
591 /// Generate LLVM-IR that computes the values of the original induction
592 /// variables in function of the newly generated loop induction variables.
593 ///
594 /// Example:
595 ///
596 /// // Original
597 /// for i
598 /// for j
599 /// S(i)
600 ///
601 /// Schedule: [i,j] -> [i+j, j]
602 ///
603 /// // New
604 /// for c0
605 /// for c1
606 /// S(c0 - c1, c1)
607 ///
608 /// Assuming the original code consists of two loops which are
609 /// transformed according to a schedule [i,j] -> [c0=i+j,c1=j]. The resulting
610 /// ast models the original statement as a call expression where each argument
611 /// is an expression that computes the old induction variables from the new
612 /// ones, ordered such that the first argument computes the value of induction
613 /// variable that was outermost in the original code.
614 ///
615 /// @param Expr The call expression that represents the statement.
616 /// @param Stmt The statement that is called.
617 /// @param VMap The value map into which the mapping from the old induction
618 /// variable to the new one is inserted. This mapping is used
619 /// for the classical code generation (not scev-based) and
620 /// gives an explicit mapping from an original, materialized
621 /// induction variable. It consequently can only be expressed
622 /// if there was an explicit induction variable.
623 /// @param LTS The loop to SCEV map in which the mapping from the original
624 /// loop to a SCEV representing the new loop iv is added. This
625 /// mapping does not require an explicit induction variable.
626 /// Instead, we think in terms of an implicit induction variable
627 /// that counts the number of times a loop is executed. For each
628 /// original loop this count, expressed in function of the new
629 /// induction variables, is added to the LTS map.
630 void createSubstitutions(__isl_take isl_ast_expr *Expr, ScopStmt *Stmt,
Sebastian Pop9d10fff2013-02-15 20:55:59 +0000631 ValueMapT &VMap, LoopToScevMapT &LTS);
Tobias Grosserce67a042014-07-02 16:26:47 +0000632 void createSubstitutionsVector(__isl_take isl_ast_expr *Expr, ScopStmt *Stmt,
633 VectorValueMapT &VMap,
Tobias Grossere602a072013-05-07 07:30:56 +0000634 std::vector<LoopToScevMapT> &VLTS,
635 std::vector<Value *> &IVS,
636 __isl_take isl_id *IteratorID);
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000637 void createIf(__isl_take isl_ast_node *If);
Tobias Grossere602a072013-05-07 07:30:56 +0000638 void createUserVector(__isl_take isl_ast_node *User,
639 std::vector<Value *> &IVS,
640 __isl_take isl_id *IteratorID,
641 __isl_take isl_union_map *Schedule);
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000642 void createUser(__isl_take isl_ast_node *User);
643 void createBlock(__isl_take isl_ast_node *Block);
644};
645
Tobias Grossere602a072013-05-07 07:30:56 +0000646__isl_give isl_ast_expr *
647IslNodeBuilder::getUpperBound(__isl_keep isl_ast_node *For,
648 ICmpInst::Predicate &Predicate) {
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000649 isl_id *UBID, *IteratorID;
650 isl_ast_expr *Cond, *Iterator, *UB, *Arg0;
Tobias Grosserc967d8e2012-10-16 07:29:13 +0000651 isl_ast_op_type Type;
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000652
653 Cond = isl_ast_node_for_get_cond(For);
654 Iterator = isl_ast_node_for_get_iterator(For);
Tobias Grosserc967d8e2012-10-16 07:29:13 +0000655 Type = isl_ast_expr_get_op_type(Cond);
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000656
Tobias Grosserae2d83e2012-12-29 23:57:18 +0000657 assert(isl_ast_expr_get_type(Cond) == isl_ast_expr_op &&
658 "conditional expression is not an atomic upper bound");
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000659
Tobias Grosserc967d8e2012-10-16 07:29:13 +0000660 switch (Type) {
Tobias Grosserc14582f2013-02-05 18:01:29 +0000661 case isl_ast_op_le:
662 Predicate = ICmpInst::ICMP_SLE;
663 break;
664 case isl_ast_op_lt:
665 Predicate = ICmpInst::ICMP_SLT;
666 break;
667 default:
668 llvm_unreachable("Unexpected comparision type in loop conditon");
Tobias Grosserc967d8e2012-10-16 07:29:13 +0000669 }
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000670
671 Arg0 = isl_ast_expr_get_op_arg(Cond, 0);
672
Tobias Grosserae2d83e2012-12-29 23:57:18 +0000673 assert(isl_ast_expr_get_type(Arg0) == isl_ast_expr_id &&
674 "conditional expression is not an atomic upper bound");
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000675
676 UBID = isl_ast_expr_get_id(Arg0);
677
Tobias Grosserae2d83e2012-12-29 23:57:18 +0000678 assert(isl_ast_expr_get_type(Iterator) == isl_ast_expr_id &&
679 "Could not get the iterator");
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000680
681 IteratorID = isl_ast_expr_get_id(Iterator);
682
Tobias Grosserae2d83e2012-12-29 23:57:18 +0000683 assert(UBID == IteratorID &&
684 "conditional expression is not an atomic upper bound");
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000685
686 UB = isl_ast_expr_get_op_arg(Cond, 1);
687
688 isl_ast_expr_free(Cond);
689 isl_ast_expr_free(Iterator);
690 isl_ast_expr_free(Arg0);
691 isl_id_free(IteratorID);
692 isl_id_free(UBID);
693
694 return UB;
695}
696
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000697unsigned IslNodeBuilder::getNumberOfIterations(__isl_keep isl_ast_node *For) {
Johannes Doerfert94d90822014-07-23 20:26:25 +0000698 isl_union_map *Schedule = IslAstInfo::getSchedule(For);
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000699 isl_set *LoopDomain = isl_set_from_union_set(isl_union_map_range(Schedule));
Sebastian Pop2aa5c242012-12-18 08:56:51 +0000700 int NumberOfIterations = polly::getNumberOfIterations(LoopDomain);
701 if (NumberOfIterations == -1)
702 return -1;
703 return NumberOfIterations + 1;
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000704}
705
Tobias Grossere602a072013-05-07 07:30:56 +0000706void IslNodeBuilder::createUserVector(__isl_take isl_ast_node *User,
707 std::vector<Value *> &IVS,
708 __isl_take isl_id *IteratorID,
709 __isl_take isl_union_map *Schedule) {
Tobias Grosserce67a042014-07-02 16:26:47 +0000710 isl_ast_expr *Expr = isl_ast_node_user_get_expr(User);
711 isl_ast_expr *StmtExpr = isl_ast_expr_get_op_arg(Expr, 0);
712 isl_id *Id = isl_ast_expr_get_id(StmtExpr);
713 isl_ast_expr_free(StmtExpr);
Tobias Grosserc14582f2013-02-05 18:01:29 +0000714 ScopStmt *Stmt = (ScopStmt *)isl_id_get_user(Id);
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000715 VectorValueMapT VectorMap(IVS.size());
Sebastian Pop9d10fff2013-02-15 20:55:59 +0000716 std::vector<LoopToScevMapT> VLTS(IVS.size());
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000717
718 isl_union_set *Domain = isl_union_set_from_set(Stmt->getDomain());
719 Schedule = isl_union_map_intersect_domain(Schedule, Domain);
720 isl_map *S = isl_map_from_union_map(Schedule);
721
Tobias Grosserce67a042014-07-02 16:26:47 +0000722 createSubstitutionsVector(Expr, Stmt, VectorMap, VLTS, IVS, IteratorID);
Sebastian Pop9d10fff2013-02-15 20:55:59 +0000723 VectorBlockGenerator::generate(Builder, *Stmt, VectorMap, VLTS, S, P);
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000724
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000725 isl_map_free(S);
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000726 isl_id_free(Id);
727 isl_ast_node_free(User);
728}
729
Tobias Grossere602a072013-05-07 07:30:56 +0000730void IslNodeBuilder::createForVector(__isl_take isl_ast_node *For,
731 int VectorWidth) {
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000732 isl_ast_node *Body = isl_ast_node_for_get_body(For);
733 isl_ast_expr *Init = isl_ast_node_for_get_init(For);
734 isl_ast_expr *Inc = isl_ast_node_for_get_inc(For);
735 isl_ast_expr *Iterator = isl_ast_node_for_get_iterator(For);
736 isl_id *IteratorID = isl_ast_expr_get_id(Iterator);
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000737
738 Value *ValueLB = ExprBuilder.create(Init);
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000739 Value *ValueInc = ExprBuilder.create(Inc);
740
741 Type *MaxType = ExprBuilder.getType(Iterator);
742 MaxType = ExprBuilder.getWidestType(MaxType, ValueLB->getType());
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000743 MaxType = ExprBuilder.getWidestType(MaxType, ValueInc->getType());
744
745 if (MaxType != ValueLB->getType())
746 ValueLB = Builder.CreateSExt(ValueLB, MaxType);
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000747 if (MaxType != ValueInc->getType())
748 ValueInc = Builder.CreateSExt(ValueInc, MaxType);
749
Tobias Grosserc14582f2013-02-05 18:01:29 +0000750 std::vector<Value *> IVS(VectorWidth);
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000751 IVS[0] = ValueLB;
752
753 for (int i = 1; i < VectorWidth; i++)
Tobias Grosserc14582f2013-02-05 18:01:29 +0000754 IVS[i] = Builder.CreateAdd(IVS[i - 1], ValueInc, "p_vector_iv");
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000755
Johannes Doerfert94d90822014-07-23 20:26:25 +0000756 isl_union_map *Schedule = IslAstInfo::getSchedule(For);
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000757 assert(Schedule && "For statement annotation does not contain its schedule");
758
759 IDToValue[IteratorID] = ValueLB;
760
761 switch (isl_ast_node_get_type(Body)) {
762 case isl_ast_node_user:
763 createUserVector(Body, IVS, isl_id_copy(IteratorID),
764 isl_union_map_copy(Schedule));
765 break;
766 case isl_ast_node_block: {
767 isl_ast_node_list *List = isl_ast_node_block_get_children(Body);
768
769 for (int i = 0; i < isl_ast_node_list_n_ast_node(List); ++i)
770 createUserVector(isl_ast_node_list_get_ast_node(List, i), IVS,
Tobias Grosser1bb59b02012-12-29 23:47:38 +0000771 isl_id_copy(IteratorID), isl_union_map_copy(Schedule));
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000772
773 isl_ast_node_free(Body);
774 isl_ast_node_list_free(List);
775 break;
776 }
777 default:
778 isl_ast_node_dump(Body);
779 llvm_unreachable("Unhandled isl_ast_node in vectorizer");
780 }
781
782 IDToValue.erase(IteratorID);
783 isl_id_free(IteratorID);
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000784 isl_union_map_free(Schedule);
785
786 isl_ast_node_free(For);
787 isl_ast_expr_free(Iterator);
788}
789
790void IslNodeBuilder::createForSequential(__isl_take isl_ast_node *For) {
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000791 isl_ast_node *Body;
792 isl_ast_expr *Init, *Inc, *Iterator, *UB;
793 isl_id *IteratorID;
794 Value *ValueLB, *ValueUB, *ValueInc;
795 Type *MaxType;
Tobias Grosser5db6ffd2013-05-16 06:40:06 +0000796 BasicBlock *ExitBlock;
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000797 Value *IV;
Tobias Grosserc967d8e2012-10-16 07:29:13 +0000798 CmpInst::Predicate Predicate;
Tobias Grosser37c9b8e2014-03-04 14:59:00 +0000799 bool Parallel;
800
Johannes Doerfert6e819052014-07-17 16:11:28 +0000801 Parallel = IslAstInfo::isInnermostParallel(For);
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000802
803 Body = isl_ast_node_for_get_body(For);
804
805 // isl_ast_node_for_is_degenerate(For)
806 //
807 // TODO: For degenerated loops we could generate a plain assignment.
808 // However, for now we just reuse the logic for normal loops, which will
809 // create a loop with a single iteration.
810
811 Init = isl_ast_node_for_get_init(For);
812 Inc = isl_ast_node_for_get_inc(For);
813 Iterator = isl_ast_node_for_get_iterator(For);
814 IteratorID = isl_ast_expr_get_id(Iterator);
Tobias Grosserc967d8e2012-10-16 07:29:13 +0000815 UB = getUpperBound(For, Predicate);
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000816
817 ValueLB = ExprBuilder.create(Init);
818 ValueUB = ExprBuilder.create(UB);
819 ValueInc = ExprBuilder.create(Inc);
820
821 MaxType = ExprBuilder.getType(Iterator);
822 MaxType = ExprBuilder.getWidestType(MaxType, ValueLB->getType());
823 MaxType = ExprBuilder.getWidestType(MaxType, ValueUB->getType());
824 MaxType = ExprBuilder.getWidestType(MaxType, ValueInc->getType());
825
826 if (MaxType != ValueLB->getType())
827 ValueLB = Builder.CreateSExt(ValueLB, MaxType);
828 if (MaxType != ValueUB->getType())
829 ValueUB = Builder.CreateSExt(ValueUB, MaxType);
830 if (MaxType != ValueInc->getType())
831 ValueInc = Builder.CreateSExt(ValueInc, MaxType);
832
Tobias Grosser37c9b8e2014-03-04 14:59:00 +0000833 IV = createLoop(ValueLB, ValueUB, ValueInc, Builder, P, ExitBlock, Predicate,
834 &Annotator, Parallel);
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000835 IDToValue[IteratorID] = IV;
836
837 create(Body);
838
Tobias Grosser37c9b8e2014-03-04 14:59:00 +0000839 Annotator.End();
840
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000841 IDToValue.erase(IteratorID);
842
Tobias Grosser5db6ffd2013-05-16 06:40:06 +0000843 Builder.SetInsertPoint(ExitBlock->begin());
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000844
845 isl_ast_node_free(For);
846 isl_ast_expr_free(Iterator);
847 isl_id_free(IteratorID);
848}
849
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000850void IslNodeBuilder::createFor(__isl_take isl_ast_node *For) {
851 bool Vector = PollyVectorizerChoice != VECTORIZER_NONE;
852
Johannes Doerfert6e819052014-07-17 16:11:28 +0000853 if (Vector && IslAstInfo::isInnermostParallel(For)) {
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000854 int VectorWidth = getNumberOfIterations(For);
855 if (1 < VectorWidth && VectorWidth <= 16) {
856 createForVector(For, VectorWidth);
857 return;
858 }
859 }
860 createForSequential(For);
861}
862
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000863void IslNodeBuilder::createIf(__isl_take isl_ast_node *If) {
864 isl_ast_expr *Cond = isl_ast_node_if_get_cond(If);
865
866 Function *F = Builder.GetInsertBlock()->getParent();
867 LLVMContext &Context = F->getContext();
868
Tobias Grosserc14582f2013-02-05 18:01:29 +0000869 BasicBlock *CondBB =
870 SplitBlock(Builder.GetInsertBlock(), Builder.GetInsertPoint(), P);
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000871 CondBB->setName("polly.cond");
872 BasicBlock *MergeBB = SplitBlock(CondBB, CondBB->begin(), P);
873 MergeBB->setName("polly.merge");
874 BasicBlock *ThenBB = BasicBlock::Create(Context, "polly.then", F);
875 BasicBlock *ElseBB = BasicBlock::Create(Context, "polly.else", F);
876
Tobias Grosser42aff302014-01-13 22:29:56 +0000877 DominatorTree &DT = P->getAnalysis<DominatorTreeWrapperPass>().getDomTree();
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000878 DT.addNewBlock(ThenBB, CondBB);
879 DT.addNewBlock(ElseBB, CondBB);
880 DT.changeImmediateDominator(MergeBB, CondBB);
881
Tobias Grosser3081b0f2013-05-16 06:40:24 +0000882 LoopInfo &LI = P->getAnalysis<LoopInfo>();
883 Loop *L = LI.getLoopFor(CondBB);
884 if (L) {
885 L->addBasicBlockToLoop(ThenBB, LI.getBase());
886 L->addBasicBlockToLoop(ElseBB, LI.getBase());
887 }
888
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000889 CondBB->getTerminator()->eraseFromParent();
890
891 Builder.SetInsertPoint(CondBB);
892 Value *Predicate = ExprBuilder.create(Cond);
893 Builder.CreateCondBr(Predicate, ThenBB, ElseBB);
894 Builder.SetInsertPoint(ThenBB);
895 Builder.CreateBr(MergeBB);
896 Builder.SetInsertPoint(ElseBB);
897 Builder.CreateBr(MergeBB);
898 Builder.SetInsertPoint(ThenBB->begin());
899
900 create(isl_ast_node_if_get_then(If));
901
902 Builder.SetInsertPoint(ElseBB->begin());
903
904 if (isl_ast_node_if_has_else(If))
905 create(isl_ast_node_if_get_else(If));
906
907 Builder.SetInsertPoint(MergeBB->begin());
908
909 isl_ast_node_free(If);
910}
911
Tobias Grosserce67a042014-07-02 16:26:47 +0000912void IslNodeBuilder::createSubstitutions(isl_ast_expr *Expr, ScopStmt *Stmt,
913 ValueMapT &VMap, LoopToScevMapT &LTS) {
914 assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
915 "Expression of type 'op' expected");
916 assert(isl_ast_expr_get_op_type(Expr) == isl_ast_op_call &&
917 "Opertation of type 'call' expected");
918 for (int i = 0; i < isl_ast_expr_get_op_n_arg(Expr) - 1; ++i) {
919 isl_ast_expr *SubExpr;
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000920 Value *V;
921
Tobias Grosserce67a042014-07-02 16:26:47 +0000922 SubExpr = isl_ast_expr_get_op_arg(Expr, i + 1);
923 V = ExprBuilder.create(SubExpr);
Sebastian Pope039bb12013-03-18 19:09:49 +0000924 ScalarEvolution *SE = Stmt->getParent()->getSE();
925 LTS[Stmt->getLoopForDimension(i)] = SE->getUnknown(V);
926
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000927 // CreateIntCast can introduce trunc expressions. This is correct, as the
928 // result will always fit into the type of the original induction variable
929 // (because we calculate a value of the original induction variable).
Sebastian Pope039bb12013-03-18 19:09:49 +0000930 const Value *OldIV = Stmt->getInductionVariableForDimension(i);
931 if (OldIV) {
932 V = Builder.CreateIntCast(V, OldIV->getType(), true);
933 VMap[OldIV] = V;
934 }
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000935 }
936
Tobias Grosserce67a042014-07-02 16:26:47 +0000937 isl_ast_expr_free(Expr);
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000938}
939
Tobias Grosserc14582f2013-02-05 18:01:29 +0000940void IslNodeBuilder::createSubstitutionsVector(
Tobias Grosserce67a042014-07-02 16:26:47 +0000941 __isl_take isl_ast_expr *Expr, ScopStmt *Stmt, VectorValueMapT &VMap,
942 std::vector<LoopToScevMapT> &VLTS, std::vector<Value *> &IVS,
943 __isl_take isl_id *IteratorID) {
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000944 int i = 0;
945
946 Value *OldValue = IDToValue[IteratorID];
Tobias Grosser91f5b262014-06-04 08:06:40 +0000947 for (Value *IV : IVS) {
948 IDToValue[IteratorID] = IV;
Tobias Grosserce67a042014-07-02 16:26:47 +0000949 createSubstitutions(isl_ast_expr_copy(Expr), Stmt, VMap[i], VLTS[i]);
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000950 i++;
951 }
952
953 IDToValue[IteratorID] = OldValue;
954 isl_id_free(IteratorID);
Tobias Grosserce67a042014-07-02 16:26:47 +0000955 isl_ast_expr_free(Expr);
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000956}
957
958void IslNodeBuilder::createUser(__isl_take isl_ast_node *User) {
959 ValueMapT VMap;
Sebastian Pop9d10fff2013-02-15 20:55:59 +0000960 LoopToScevMapT LTS;
Tobias Grosserce67a042014-07-02 16:26:47 +0000961 isl_id *Id;
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000962 ScopStmt *Stmt;
963
Tobias Grosserce67a042014-07-02 16:26:47 +0000964 isl_ast_expr *Expr = isl_ast_node_user_get_expr(User);
965 isl_ast_expr *StmtExpr = isl_ast_expr_get_op_arg(Expr, 0);
966 Id = isl_ast_expr_get_id(StmtExpr);
967 isl_ast_expr_free(StmtExpr);
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000968
Tobias Grosserc14582f2013-02-05 18:01:29 +0000969 Stmt = (ScopStmt *)isl_id_get_user(Id);
Tobias Grosserce67a042014-07-02 16:26:47 +0000970 createSubstitutions(Expr, Stmt, VMap, LTS);
Sebastian Pop9d10fff2013-02-15 20:55:59 +0000971 BlockGenerator::generate(Builder, *Stmt, VMap, LTS, P);
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000972
973 isl_ast_node_free(User);
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000974 isl_id_free(Id);
975}
976
977void IslNodeBuilder::createBlock(__isl_take isl_ast_node *Block) {
978 isl_ast_node_list *List = isl_ast_node_block_get_children(Block);
979
980 for (int i = 0; i < isl_ast_node_list_n_ast_node(List); ++i)
981 create(isl_ast_node_list_get_ast_node(List, i));
982
983 isl_ast_node_free(Block);
984 isl_ast_node_list_free(List);
985}
986
987void IslNodeBuilder::create(__isl_take isl_ast_node *Node) {
988 switch (isl_ast_node_get_type(Node)) {
989 case isl_ast_node_error:
990 llvm_unreachable("code generation error");
991 case isl_ast_node_for:
992 createFor(Node);
993 return;
994 case isl_ast_node_if:
995 createIf(Node);
996 return;
997 case isl_ast_node_user:
998 createUser(Node);
999 return;
1000 case isl_ast_node_block:
1001 createBlock(Node);
1002 return;
1003 }
1004
1005 llvm_unreachable("Unknown isl_ast_node type");
1006}
1007
1008void IslNodeBuilder::addParameters(__isl_take isl_set *Context) {
1009 SCEVExpander Rewriter(P->getAnalysis<ScalarEvolution>(), "polly");
1010
1011 for (unsigned i = 0; i < isl_set_dim(Context, isl_dim_param); ++i) {
1012 isl_id *Id;
1013 const SCEV *Scev;
1014 IntegerType *T;
1015 Instruction *InsertLocation;
1016
1017 Id = isl_set_get_dim_id(Context, isl_dim_param, i);
Tobias Grosserc14582f2013-02-05 18:01:29 +00001018 Scev = (const SCEV *)isl_id_get_user(Id);
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001019 T = dyn_cast<IntegerType>(Scev->getType());
1020 InsertLocation = --(Builder.GetInsertBlock()->end());
1021 Value *V = Rewriter.expandCodeFor(Scev, T, InsertLocation);
1022 IDToValue[Id] = V;
1023
1024 isl_id_free(Id);
1025 }
1026
1027 isl_set_free(Context);
1028}
1029
1030namespace {
1031class IslCodeGeneration : public ScopPass {
Tobias Grosser1bb59b02012-12-29 23:47:38 +00001032public:
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001033 static char ID;
1034
1035 IslCodeGeneration() : ScopPass(ID) {}
1036
1037 bool runOnScop(Scop &S) {
1038 IslAstInfo &AstInfo = getAnalysis<IslAstInfo>();
Tobias Grosser0ee50f62013-04-10 06:55:31 +00001039
Tobias Grossere602a072013-05-07 07:30:56 +00001040 assert(!S.getRegion().isTopLevelRegion() &&
1041 "Top level regions are not supported");
Tobias Grosser0ee50f62013-04-10 06:55:31 +00001042
Tobias Grosser8edce4e2013-04-16 08:04:42 +00001043 simplifyRegion(&S, this);
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001044
1045 BasicBlock *StartBlock = executeScopConditionally(S, this);
1046 isl_ast_node *Ast = AstInfo.getAst();
Tobias Grosser37c9b8e2014-03-04 14:59:00 +00001047 LoopAnnotator Annotator;
1048 PollyIRBuilder Builder(StartBlock->getContext(), llvm::ConstantFolder(),
1049 polly::IRInserter(Annotator));
1050 Builder.SetInsertPoint(StartBlock->begin());
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001051
Tobias Grosser37c9b8e2014-03-04 14:59:00 +00001052 IslNodeBuilder NodeBuilder(Builder, Annotator, this);
Tobias Grosser54ee0ba2013-11-17 03:18:25 +00001053
Tobias Grosser5e6813d2014-07-02 17:47:48 +00001054 Builder.SetInsertPoint(StartBlock->getSinglePredecessor()->begin());
1055 NodeBuilder.addParameters(S.getContext());
Tobias Grosser54ee0ba2013-11-17 03:18:25 +00001056 // Build condition that evaluates at run-time if all assumptions taken
1057 // for the scop hold. If we detect some assumptions do not hold, the
1058 // original code is executed.
1059 Value *V = NodeBuilder.getExprBuilder().create(AstInfo.getRunCondition());
1060 Value *Zero = ConstantInt::get(V->getType(), 0);
1061 V = Builder.CreateICmp(CmpInst::ICMP_NE, Zero, V);
1062 BasicBlock *PrevBB = StartBlock->getUniquePredecessor();
1063 BranchInst *Branch = dyn_cast<BranchInst>(PrevBB->getTerminator());
1064 Branch->setCondition(V);
Tobias Grosser5e6813d2014-07-02 17:47:48 +00001065 Builder.SetInsertPoint(StartBlock->begin());
Tobias Grosser54ee0ba2013-11-17 03:18:25 +00001066
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001067 NodeBuilder.create(Ast);
1068 return true;
1069 }
1070
Tobias Grosserc14582f2013-02-05 18:01:29 +00001071 virtual void printScop(raw_ostream &OS) const {}
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001072
1073 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
Tobias Grosser42aff302014-01-13 22:29:56 +00001074 AU.addRequired<DominatorTreeWrapperPass>();
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001075 AU.addRequired<IslAstInfo>();
Matt Arsenault8ca36812014-07-19 18:40:17 +00001076 AU.addRequired<RegionInfoPass>();
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001077 AU.addRequired<ScalarEvolution>();
1078 AU.addRequired<ScopDetection>();
1079 AU.addRequired<ScopInfo>();
Tobias Grosserecfe21b2013-03-20 18:03:18 +00001080 AU.addRequired<LoopInfo>();
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001081
1082 AU.addPreserved<Dependences>();
1083
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001084 AU.addPreserved<LoopInfo>();
Tobias Grosser42aff302014-01-13 22:29:56 +00001085 AU.addPreserved<DominatorTreeWrapperPass>();
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001086 AU.addPreserved<IslAstInfo>();
1087 AU.addPreserved<ScopDetection>();
1088 AU.addPreserved<ScalarEvolution>();
1089
1090 // FIXME: We do not yet add regions for the newly generated code to the
1091 // region tree.
Matt Arsenault8ca36812014-07-19 18:40:17 +00001092 AU.addPreserved<RegionInfoPass>();
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001093 AU.addPreserved<TempScopInfo>();
1094 AU.addPreserved<ScopInfo>();
1095 AU.addPreservedID(IndependentBlocksID);
1096 }
1097};
1098}
1099
1100char IslCodeGeneration::ID = 1;
1101
Tobias Grosser7242ad92013-02-22 08:07:06 +00001102Pass *polly::createIslCodeGenerationPass() { return new IslCodeGeneration(); }
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001103
Tobias Grosser7242ad92013-02-22 08:07:06 +00001104INITIALIZE_PASS_BEGIN(IslCodeGeneration, "polly-codegen-isl",
1105 "Polly - Create LLVM-IR from SCoPs", false, false);
1106INITIALIZE_PASS_DEPENDENCY(Dependences);
Tobias Grosser42aff302014-01-13 22:29:56 +00001107INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass);
Tobias Grosser7242ad92013-02-22 08:07:06 +00001108INITIALIZE_PASS_DEPENDENCY(LoopInfo);
Matt Arsenault8ca36812014-07-19 18:40:17 +00001109INITIALIZE_PASS_DEPENDENCY(RegionInfoPass);
Tobias Grosser7242ad92013-02-22 08:07:06 +00001110INITIALIZE_PASS_DEPENDENCY(ScalarEvolution);
1111INITIALIZE_PASS_DEPENDENCY(ScopDetection);
1112INITIALIZE_PASS_END(IslCodeGeneration, "polly-codegen-isl",
1113 "Polly - Create LLVM-IR from SCoPs", false, false)