blob: 952e653c89a317d288f5d639f8922b213f030d5f [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"
34#include "llvm/Analysis/ScalarEvolutionExpander.h"
Tobias Grosser83628182013-05-07 08:11:54 +000035#include "llvm/IR/Module.h"
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +000036#include "llvm/Support/CommandLine.h"
37#include "llvm/Support/Debug.h"
Chandler Carruth535d52c2013-01-02 11:47:44 +000038#include "llvm/IR/DataLayout.h"
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +000039#include "llvm/Transforms/Utils/BasicBlockUtils.h"
40
41#include "isl/union_map.h"
42#include "isl/list.h"
43#include "isl/ast.h"
44#include "isl/ast_build.h"
45#include "isl/set.h"
46#include "isl/map.h"
47#include "isl/aff.h"
48
49#include <map>
50
51using namespace polly;
52using namespace llvm;
53
Chandler Carruth95fef942014-04-22 03:30:19 +000054#define DEBUG_TYPE "polly-codegen-isl"
55
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +000056/// @brief Insert function calls that print certain LLVM values at run time.
57///
58/// This class inserts libc function calls to print certain LLVM values at
59/// run time.
60class RuntimeDebugBuilder {
61public:
Tobias Grosser5103ba72014-03-04 14:58:49 +000062 RuntimeDebugBuilder(PollyIRBuilder &Builder) : Builder(Builder) {}
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +000063
64 /// @brief Print a string to stdout.
65 ///
66 /// @param String The string to print.
67 void createStrPrinter(std::string String);
68
69 /// @brief Print an integer value to stdout.
70 ///
71 /// @param V The value to print.
72 void createIntPrinter(Value *V);
73
74private:
Tobias Grosser5103ba72014-03-04 14:58:49 +000075 PollyIRBuilder &Builder;
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +000076
77 /// @brief Add a call to the fflush function with no file pointer given.
78 ///
79 /// This call will flush all opened file pointers including stdout and stderr.
80 void createFlush();
81
82 /// @brief Get a reference to the 'printf' function.
83 ///
84 /// If the current module does not yet contain a reference to printf, we
85 /// insert a reference to it. Otherwise the existing reference is returned.
86 Function *getPrintF();
87};
88
89Function *RuntimeDebugBuilder::getPrintF() {
90 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
91 const char *Name = "printf";
92 Function *F = M->getFunction(Name);
93
94 if (!F) {
95 GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
Tobias Grosserc14582f2013-02-05 18:01:29 +000096 FunctionType *Ty =
97 FunctionType::get(Builder.getInt32Ty(), Builder.getInt8PtrTy(), true);
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +000098 F = Function::Create(Ty, Linkage, Name, M);
99 }
100
101 return F;
102}
103
104void RuntimeDebugBuilder::createFlush() {
105 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
106 const char *Name = "fflush";
107 Function *F = M->getFunction(Name);
108
109 if (!F) {
110 GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
Tobias Grosserc14582f2013-02-05 18:01:29 +0000111 FunctionType *Ty =
112 FunctionType::get(Builder.getInt32Ty(), Builder.getInt8PtrTy(), false);
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000113 F = Function::Create(Ty, Linkage, Name, M);
114 }
115
116 Builder.CreateCall(F, Constant::getNullValue(Builder.getInt8PtrTy()));
117}
118
119void RuntimeDebugBuilder::createStrPrinter(std::string String) {
120 Function *F = getPrintF();
121 Value *StringValue = Builder.CreateGlobalStringPtr(String);
122 Builder.CreateCall(F, StringValue);
123
124 createFlush();
125}
126
127void RuntimeDebugBuilder::createIntPrinter(Value *V) {
128 IntegerType *Ty = dyn_cast<IntegerType>(V->getType());
Tobias Grosser58032cb2013-06-23 01:29:29 +0000129 (void)Ty;
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000130 assert(Ty && Ty->getBitWidth() == 64 &&
131 "Cannot insert printer for this type.");
132
133 Function *F = getPrintF();
134 Value *String = Builder.CreateGlobalStringPtr("%ld");
135 Builder.CreateCall2(F, String, V);
136 createFlush();
137}
138
Tobias Grosser9818bc82014-04-22 14:26:51 +0000139/// @brief LLVM-IR generator for isl_ast_expr[essions]
140///
141/// This generator generates LLVM-IR that performs the computation described by
142/// an isl_ast_expr[ession].
143///
144/// Example:
145///
146/// An isl_ast_expr[ession] can look like this:
147///
148/// (N + M) + 10
149///
150/// The IslExprBuilder could create the following LLVM-IR:
151///
152/// %tmp1 = add nsw i64 %N
153/// %tmp2 = add nsw i64 %tmp1, %M
154/// %tmp3 = add nsw i64 %tmp2, 10
155///
156/// The implementation of this class is mostly a mapping from isl_ast_expr
157/// constructs to the corresponding LLVM-IR constructs.
158///
159/// The following decisions may need some explanation:
160///
161/// 1) Which data-type to choose
162///
163/// isl_ast_expr[essions] are untyped expressions that assume arbitrary
164/// precision integer computations. LLVM-IR instead has fixed size integers.
165/// When lowering to LLVM-IR we need to chose both the size of the data type and
166/// the sign of the operations we use.
167///
168/// At the moment, we hardcode i64 bit signed computations. Our experience has
169/// shown that 64 bit are generally large enough for the loop bounds that appear
170/// in the wild. Signed computations are needed, as loop bounds may become
171/// negative.
172///
173/// FIXME: Hardcoding sizes can cause issues:
174///
175/// a) Certain run-time checks that we may want to generate can involve the
176/// size of the data types the computation is performed on. When code
177/// generating these run-time checks to isl_ast_expr[essions], the
178/// resulting computation may require more than 64 bit.
179///
180/// b) On embedded systems and especially for high-level-synthesis 64 bit
181/// computations are very costly.
182///
183/// The right approach is to compute the minimal necessary bitwidth and
184/// signedness for each subexpression during in the isl AST generation and
185/// to use this information in our IslAstGenerator. Preliminary patches are
186/// available, but have not been committed yet.
187///
188/// 2) We always flag computations with 'nsw'
189///
190/// As isl_ast_expr[essions] assume arbitrary precision, no wrapping should
191/// ever occur in the generated LLVM-IR (assuming the data type chosen is large
192/// enough).
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000193class IslExprBuilder {
194public:
Tobias Grosser9818bc82014-04-22 14:26:51 +0000195 /// @brief Construct an IslExprBuilder.
196 ///
197 /// @param Builder The IRBuilder used to construct the isl_ast_expr[ession].
198 /// The insert location of this IRBuilder defines WHERE the
199 /// corresponding LLVM-IR is generated.
200 ///
201 /// @param IDToValue The isl_ast_expr[ession] may reference parameters or
202 /// variables (identified by an isl_id). The IDTOValue map
203 /// specifies the LLVM-IR Values that correspond to these
204 /// parameters and variables.
Tobias Grosser5103ba72014-03-04 14:58:49 +0000205 IslExprBuilder(PollyIRBuilder &Builder,
Tobias Grosser9818bc82014-04-22 14:26:51 +0000206 std::map<isl_id *, Value *> &IDToValue)
Tobias Grosser7242ad92013-02-22 08:07:06 +0000207 : Builder(Builder), IDToValue(IDToValue) {}
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000208
Tobias Grosser9818bc82014-04-22 14:26:51 +0000209 /// @brief Create LLVM-IR for an isl_ast_expr[ession].
210 ///
211 /// @param Expr The ast expression for which we generate LLVM-IR.
212 ///
213 /// @return The llvm::Value* containing the result of the computation.
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000214 Value *create(__isl_take isl_ast_expr *Expr);
Tobias Grosser9818bc82014-04-22 14:26:51 +0000215
216 /// @brief Return the largest of two types.
217 ///
218 /// @param T1 The first type.
219 /// @param T2 The second type.
220 ///
221 /// @return The largest of the two types.
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000222 Type *getWidestType(Type *T1, Type *T2);
Tobias Grosser9818bc82014-04-22 14:26:51 +0000223
224 /// @brief Return the type with which this expression should be computed.
225 ///
226 /// The type needs to be large enough to hold all possible input and all
227 /// possible output values.
228 ///
229 /// @param Expr The expression for which to find the type.
230 /// @return The type with which the expression should be computed.
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000231 IntegerType *getType(__isl_keep isl_ast_expr *Expr);
232
233private:
Tobias Grosser5103ba72014-03-04 14:58:49 +0000234 PollyIRBuilder &Builder;
Tobias Grosserc14582f2013-02-05 18:01:29 +0000235 std::map<isl_id *, Value *> &IDToValue;
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000236
237 Value *createOp(__isl_take isl_ast_expr *Expr);
238 Value *createOpUnary(__isl_take isl_ast_expr *Expr);
239 Value *createOpBin(__isl_take isl_ast_expr *Expr);
240 Value *createOpNAry(__isl_take isl_ast_expr *Expr);
241 Value *createOpSelect(__isl_take isl_ast_expr *Expr);
242 Value *createOpICmp(__isl_take isl_ast_expr *Expr);
243 Value *createOpBoolean(__isl_take isl_ast_expr *Expr);
244 Value *createId(__isl_take isl_ast_expr *Expr);
245 Value *createInt(__isl_take isl_ast_expr *Expr);
246};
247
248Type *IslExprBuilder::getWidestType(Type *T1, Type *T2) {
249 assert(isa<IntegerType>(T1) && isa<IntegerType>(T2));
250
251 if (T1->getPrimitiveSizeInBits() < T2->getPrimitiveSizeInBits())
252 return T2;
253 else
254 return T1;
255}
256
257Value *IslExprBuilder::createOpUnary(__isl_take isl_ast_expr *Expr) {
Tobias Grosserae2d83e2012-12-29 23:57:18 +0000258 assert(isl_ast_expr_get_op_type(Expr) == isl_ast_op_minus &&
259 "Unsupported unary operation");
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000260
261 Value *V;
262 Type *MaxType = getType(Expr);
263
264 V = create(isl_ast_expr_get_op_arg(Expr, 0));
265 MaxType = getWidestType(MaxType, V->getType());
266
267 if (MaxType != V->getType())
268 V = Builder.CreateSExt(V, MaxType);
269
270 isl_ast_expr_free(Expr);
271 return Builder.CreateNSWNeg(V);
272}
273
274Value *IslExprBuilder::createOpNAry(__isl_take isl_ast_expr *Expr) {
Tobias Grosserae2d83e2012-12-29 23:57:18 +0000275 assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
276 "isl ast expression not of type isl_ast_op");
277 assert(isl_ast_expr_get_op_n_arg(Expr) >= 2 &&
278 "We need at least two operands in an n-ary operation");
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000279
280 Value *V;
281
282 V = create(isl_ast_expr_get_op_arg(Expr, 0));
283
284 for (int i = 0; i < isl_ast_expr_get_op_n_arg(Expr); ++i) {
285 Value *OpV;
286 OpV = create(isl_ast_expr_get_op_arg(Expr, i));
287
288 Type *Ty = getWidestType(V->getType(), OpV->getType());
289
290 if (Ty != OpV->getType())
291 OpV = Builder.CreateSExt(OpV, Ty);
292
293 if (Ty != V->getType())
294 V = Builder.CreateSExt(V, Ty);
295
296 switch (isl_ast_expr_get_op_type(Expr)) {
297 default:
298 llvm_unreachable("This is no n-ary isl ast expression");
299
Tobias Grosserc14582f2013-02-05 18:01:29 +0000300 case isl_ast_op_max: {
301 Value *Cmp = Builder.CreateICmpSGT(V, OpV);
302 V = Builder.CreateSelect(Cmp, V, OpV);
303 continue;
304 }
305 case isl_ast_op_min: {
306 Value *Cmp = Builder.CreateICmpSLT(V, OpV);
307 V = Builder.CreateSelect(Cmp, V, OpV);
308 continue;
309 }
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000310 }
311 }
312
313 // TODO: We can truncate the result, if it fits into a smaller type. This can
314 // help in cases where we have larger operands (e.g. i67) but the result is
315 // known to fit into i64. Without the truncation, the larger i67 type may
316 // force all subsequent operations to be performed on a non-native type.
317 isl_ast_expr_free(Expr);
318 return V;
319}
320
321Value *IslExprBuilder::createOpBin(__isl_take isl_ast_expr *Expr) {
322 Value *LHS, *RHS, *Res;
323 Type *MaxType;
324 isl_ast_op_type OpType;
325
Tobias Grosserae2d83e2012-12-29 23:57:18 +0000326 assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
327 "isl ast expression not of type isl_ast_op");
328 assert(isl_ast_expr_get_op_n_arg(Expr) == 2 &&
329 "not a binary isl ast expression");
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000330
331 OpType = isl_ast_expr_get_op_type(Expr);
332
333 LHS = create(isl_ast_expr_get_op_arg(Expr, 0));
334 RHS = create(isl_ast_expr_get_op_arg(Expr, 1));
335
336 MaxType = LHS->getType();
337 MaxType = getWidestType(MaxType, RHS->getType());
338
339 // Take the result into account when calculating the widest type.
340 //
341 // For operations such as '+' the result may require a type larger than
342 // the type of the individual operands. For other operations such as '/', the
343 // result type cannot be larger than the type of the individual operand. isl
344 // does not calculate correct types for these operations and we consequently
345 // exclude those operations here.
Tobias Grosser1bb59b02012-12-29 23:47:38 +0000346 switch (OpType) {
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000347 case isl_ast_op_pdiv_q:
348 case isl_ast_op_pdiv_r:
349 case isl_ast_op_div:
350 case isl_ast_op_fdiv_q:
351 // Do nothing
352 break;
353 case isl_ast_op_add:
354 case isl_ast_op_sub:
355 case isl_ast_op_mul:
356 MaxType = getWidestType(MaxType, getType(Expr));
357 break;
358 default:
359 llvm_unreachable("This is no binary isl ast expression");
360 }
361
362 if (MaxType != RHS->getType())
363 RHS = Builder.CreateSExt(RHS, MaxType);
364
365 if (MaxType != LHS->getType())
366 LHS = Builder.CreateSExt(LHS, MaxType);
367
368 switch (OpType) {
369 default:
370 llvm_unreachable("This is no binary isl ast expression");
371 case isl_ast_op_add:
372 Res = Builder.CreateNSWAdd(LHS, RHS);
373 break;
374 case isl_ast_op_sub:
375 Res = Builder.CreateNSWSub(LHS, RHS);
376 break;
377 case isl_ast_op_mul:
378 Res = Builder.CreateNSWMul(LHS, RHS);
379 break;
380 case isl_ast_op_div:
381 case isl_ast_op_pdiv_q: // Dividend is non-negative
382 Res = Builder.CreateSDiv(LHS, RHS);
383 break;
Tobias Grosserc14582f2013-02-05 18:01:29 +0000384 case isl_ast_op_fdiv_q: { // Round towards -infty
385 // TODO: Review code and check that this calculation does not yield
386 // incorrect overflow in some bordercases.
387 //
388 // floord(n,d) ((n < 0) ? (n - d + 1) : n) / d
389 Value *One = ConstantInt::get(MaxType, 1);
390 Value *Zero = ConstantInt::get(MaxType, 0);
391 Value *Sum1 = Builder.CreateSub(LHS, RHS);
392 Value *Sum2 = Builder.CreateAdd(Sum1, One);
393 Value *isNegative = Builder.CreateICmpSLT(LHS, Zero);
394 Value *Dividend = Builder.CreateSelect(isNegative, Sum2, LHS);
395 Res = Builder.CreateSDiv(Dividend, RHS);
396 break;
397 }
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000398 case isl_ast_op_pdiv_r: // Dividend is non-negative
399 Res = Builder.CreateSRem(LHS, RHS);
400 break;
401 }
402
403 // TODO: We can truncate the result, if it fits into a smaller type. This can
404 // help in cases where we have larger operands (e.g. i67) but the result is
405 // known to fit into i64. Without the truncation, the larger i67 type may
406 // force all subsequent operations to be performed on a non-native type.
407 isl_ast_expr_free(Expr);
408 return Res;
409}
410
411Value *IslExprBuilder::createOpSelect(__isl_take isl_ast_expr *Expr) {
Tobias Grosserae2d83e2012-12-29 23:57:18 +0000412 assert(isl_ast_expr_get_op_type(Expr) == isl_ast_op_select &&
413 "Unsupported unary isl ast expression");
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000414 Value *LHS, *RHS, *Cond;
415 Type *MaxType = getType(Expr);
416
417 Cond = create(isl_ast_expr_get_op_arg(Expr, 0));
418
419 LHS = create(isl_ast_expr_get_op_arg(Expr, 1));
420 RHS = create(isl_ast_expr_get_op_arg(Expr, 2));
421
422 MaxType = getWidestType(MaxType, LHS->getType());
423 MaxType = getWidestType(MaxType, RHS->getType());
424
425 if (MaxType != RHS->getType())
426 RHS = Builder.CreateSExt(RHS, MaxType);
427
428 if (MaxType != LHS->getType())
429 LHS = Builder.CreateSExt(LHS, MaxType);
430
431 // TODO: Do we want to truncate the result?
432 isl_ast_expr_free(Expr);
433 return Builder.CreateSelect(Cond, LHS, RHS);
434}
435
436Value *IslExprBuilder::createOpICmp(__isl_take isl_ast_expr *Expr) {
437 assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
438 "Expected an isl_ast_expr_op expression");
439
440 Value *LHS, *RHS, *Res;
441
442 LHS = create(isl_ast_expr_get_op_arg(Expr, 0));
443 RHS = create(isl_ast_expr_get_op_arg(Expr, 1));
444
445 Type *MaxType = LHS->getType();
446 MaxType = getWidestType(MaxType, RHS->getType());
447
448 if (MaxType != RHS->getType())
449 RHS = Builder.CreateSExt(RHS, MaxType);
450
451 if (MaxType != LHS->getType())
452 LHS = Builder.CreateSExt(LHS, MaxType);
453
454 switch (isl_ast_expr_get_op_type(Expr)) {
455 default:
456 llvm_unreachable("Unsupported ICmp isl ast expression");
457 case isl_ast_op_eq:
458 Res = Builder.CreateICmpEQ(LHS, RHS);
459 break;
460 case isl_ast_op_le:
461 Res = Builder.CreateICmpSLE(LHS, RHS);
462 break;
Tobias Grosserc967d8e2012-10-16 07:29:13 +0000463 case isl_ast_op_lt:
464 Res = Builder.CreateICmpSLT(LHS, RHS);
465 break;
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000466 case isl_ast_op_ge:
467 Res = Builder.CreateICmpSGE(LHS, RHS);
468 break;
Tobias Grosserc967d8e2012-10-16 07:29:13 +0000469 case isl_ast_op_gt:
470 Res = Builder.CreateICmpSGT(LHS, RHS);
471 break;
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000472 }
473
474 isl_ast_expr_free(Expr);
475 return Res;
476}
477
478Value *IslExprBuilder::createOpBoolean(__isl_take isl_ast_expr *Expr) {
479 assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
480 "Expected an isl_ast_expr_op expression");
481
482 Value *LHS, *RHS, *Res;
483 isl_ast_op_type OpType;
484
485 OpType = isl_ast_expr_get_op_type(Expr);
486
487 assert((OpType == isl_ast_op_and || OpType == isl_ast_op_or) &&
488 "Unsupported isl_ast_op_type");
489
490 LHS = create(isl_ast_expr_get_op_arg(Expr, 0));
491 RHS = create(isl_ast_expr_get_op_arg(Expr, 1));
492
493 // Even though the isl pretty printer prints the expressions as 'exp && exp'
494 // or 'exp || exp', we actually code generate the bitwise expressions
495 // 'exp & exp' or 'exp | exp'. This forces the evaluation of both branches,
496 // but it is, due to the use of i1 types, otherwise equivalent. The reason
497 // to go for bitwise operations is, that we assume the reduced control flow
498 // will outweight the overhead introduced by evaluating unneeded expressions.
499 // The isl code generation currently does not take advantage of the fact that
500 // the expression after an '||' or '&&' is in some cases not evaluated.
501 // Evaluating it anyways does not cause any undefined behaviour.
502 //
503 // TODO: Document in isl itself, that the unconditionally evaluating the
504 // second part of '||' or '&&' expressions is safe.
505 assert(LHS->getType() == Builder.getInt1Ty() && "Expected i1 type");
506 assert(RHS->getType() == Builder.getInt1Ty() && "Expected i1 type");
507
508 switch (OpType) {
509 default:
510 llvm_unreachable("Unsupported boolean expression");
511 case isl_ast_op_and:
512 Res = Builder.CreateAnd(LHS, RHS);
513 break;
514 case isl_ast_op_or:
515 Res = Builder.CreateOr(LHS, RHS);
516 break;
517 }
518
519 isl_ast_expr_free(Expr);
520 return Res;
521}
522
523Value *IslExprBuilder::createOp(__isl_take isl_ast_expr *Expr) {
Tobias Grosserae2d83e2012-12-29 23:57:18 +0000524 assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
525 "Expression not of type isl_ast_expr_op");
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000526 switch (isl_ast_expr_get_op_type(Expr)) {
527 case isl_ast_op_error:
528 case isl_ast_op_cond:
529 case isl_ast_op_and_then:
530 case isl_ast_op_or_else:
531 case isl_ast_op_call:
Tobias Grossera38c9242014-01-26 19:36:28 +0000532 case isl_ast_op_member:
533 case isl_ast_op_access:
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000534 llvm_unreachable("Unsupported isl ast expression");
535 case isl_ast_op_max:
536 case isl_ast_op_min:
537 return createOpNAry(Expr);
538 case isl_ast_op_add:
539 case isl_ast_op_sub:
540 case isl_ast_op_mul:
541 case isl_ast_op_div:
542 case isl_ast_op_fdiv_q: // Round towards -infty
543 case isl_ast_op_pdiv_q: // Dividend is non-negative
544 case isl_ast_op_pdiv_r: // Dividend is non-negative
545 return createOpBin(Expr);
546 case isl_ast_op_minus:
547 return createOpUnary(Expr);
548 case isl_ast_op_select:
549 return createOpSelect(Expr);
550 case isl_ast_op_and:
551 case isl_ast_op_or:
552 return createOpBoolean(Expr);
553 case isl_ast_op_eq:
554 case isl_ast_op_le:
Tobias Grosserc967d8e2012-10-16 07:29:13 +0000555 case isl_ast_op_lt:
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000556 case isl_ast_op_ge:
Tobias Grosserc967d8e2012-10-16 07:29:13 +0000557 case isl_ast_op_gt:
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000558 return createOpICmp(Expr);
559 }
560
561 llvm_unreachable("Unsupported isl_ast_expr_op kind.");
562}
563
564Value *IslExprBuilder::createId(__isl_take isl_ast_expr *Expr) {
Tobias Grosserae2d83e2012-12-29 23:57:18 +0000565 assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_id &&
566 "Expression not of type isl_ast_expr_ident");
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000567
568 isl_id *Id;
569 Value *V;
570
571 Id = isl_ast_expr_get_id(Expr);
572
573 assert(IDToValue.count(Id) && "Identifier not found");
574
575 V = IDToValue[Id];
576
577 isl_id_free(Id);
578 isl_ast_expr_free(Expr);
579
580 return V;
581}
582
583IntegerType *IslExprBuilder::getType(__isl_keep isl_ast_expr *Expr) {
584 // XXX: We assume i64 is large enough. This is often true, but in general
585 // incorrect. Also, on 32bit architectures, it would be beneficial to
586 // use a smaller type. We can and should directly derive this information
587 // during code generation.
588 return IntegerType::get(Builder.getContext(), 64);
589}
590
591Value *IslExprBuilder::createInt(__isl_take isl_ast_expr *Expr) {
Tobias Grosserae2d83e2012-12-29 23:57:18 +0000592 assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_int &&
593 "Expression not of type isl_ast_expr_int");
Tobias Grosseredab1352013-06-21 06:41:31 +0000594 isl_val *Val;
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000595 Value *V;
596 APInt APValue;
597 IntegerType *T;
598
Tobias Grosseredab1352013-06-21 06:41:31 +0000599 Val = isl_ast_expr_get_val(Expr);
600 APValue = APIntFromVal(Val);
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000601 T = getType(Expr);
602 APValue = APValue.sextOrSelf(T->getBitWidth());
603 V = ConstantInt::get(T, APValue);
604
605 isl_ast_expr_free(Expr);
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000606 return V;
607}
608
609Value *IslExprBuilder::create(__isl_take isl_ast_expr *Expr) {
610 switch (isl_ast_expr_get_type(Expr)) {
611 case isl_ast_expr_error:
612 llvm_unreachable("Code generation error");
613 case isl_ast_expr_op:
614 return createOp(Expr);
615 case isl_ast_expr_id:
616 return createId(Expr);
617 case isl_ast_expr_int:
618 return createInt(Expr);
619 }
620
621 llvm_unreachable("Unexpected enum value");
622}
623
624class IslNodeBuilder {
625public:
Tobias Grosser37c9b8e2014-03-04 14:59:00 +0000626 IslNodeBuilder(PollyIRBuilder &Builder, LoopAnnotator &Annotator, Pass *P)
Tobias Grosser34c87872014-04-22 16:39:41 +0000627 : Builder(Builder), Annotator(Annotator), ExprBuilder(Builder, IDToValue),
628 P(P) {}
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000629
630 void addParameters(__isl_take isl_set *Context);
631 void create(__isl_take isl_ast_node *Node);
Tobias Grosser54ee0ba2013-11-17 03:18:25 +0000632 IslExprBuilder &getExprBuilder() { return ExprBuilder; }
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000633
634private:
Tobias Grosser5103ba72014-03-04 14:58:49 +0000635 PollyIRBuilder &Builder;
Tobias Grosser37c9b8e2014-03-04 14:59:00 +0000636 LoopAnnotator &Annotator;
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000637 IslExprBuilder ExprBuilder;
638 Pass *P;
639
640 // This maps an isl_id* to the Value* it has in the generated program. For now
641 // on, the only isl_ids that are stored here are the newly calculated loop
642 // ivs.
Tobias Grosserc14582f2013-02-05 18:01:29 +0000643 std::map<isl_id *, Value *> IDToValue;
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000644
645 // Extract the upper bound of this loop
646 //
647 // The isl code generation can generate arbitrary expressions to check if the
648 // upper bound of a loop is reached, but it provides an option to enforce
649 // 'atomic' upper bounds. An 'atomic upper bound is always of the form
650 // iv <= expr, where expr is an (arbitrary) expression not containing iv.
651 //
652 // This function extracts 'atomic' upper bounds. Polly, in general, requires
653 // atomic upper bounds for the following reasons:
654 //
655 // 1. An atomic upper bound is loop invariant
656 //
657 // It must not be calculated at each loop iteration and can often even be
658 // hoisted out further by the loop invariant code motion.
659 //
660 // 2. OpenMP needs a loop invarient upper bound to calculate the number
661 // of loop iterations.
662 //
663 // 3. With the existing code, upper bounds have been easier to implement.
Tobias Grossere602a072013-05-07 07:30:56 +0000664 __isl_give isl_ast_expr *getUpperBound(__isl_keep isl_ast_node *For,
665 CmpInst::Predicate &Predicate);
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000666
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000667 unsigned getNumberOfIterations(__isl_keep isl_ast_node *For);
668
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000669 void createFor(__isl_take isl_ast_node *For);
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000670 void createForVector(__isl_take isl_ast_node *For, int VectorWidth);
671 void createForSequential(__isl_take isl_ast_node *For);
Tobias Grosserce67a042014-07-02 16:26:47 +0000672
673 /// Generate LLVM-IR that computes the values of the original induction
674 /// variables in function of the newly generated loop induction variables.
675 ///
676 /// Example:
677 ///
678 /// // Original
679 /// for i
680 /// for j
681 /// S(i)
682 ///
683 /// Schedule: [i,j] -> [i+j, j]
684 ///
685 /// // New
686 /// for c0
687 /// for c1
688 /// S(c0 - c1, c1)
689 ///
690 /// Assuming the original code consists of two loops which are
691 /// transformed according to a schedule [i,j] -> [c0=i+j,c1=j]. The resulting
692 /// ast models the original statement as a call expression where each argument
693 /// is an expression that computes the old induction variables from the new
694 /// ones, ordered such that the first argument computes the value of induction
695 /// variable that was outermost in the original code.
696 ///
697 /// @param Expr The call expression that represents the statement.
698 /// @param Stmt The statement that is called.
699 /// @param VMap The value map into which the mapping from the old induction
700 /// variable to the new one is inserted. This mapping is used
701 /// for the classical code generation (not scev-based) and
702 /// gives an explicit mapping from an original, materialized
703 /// induction variable. It consequently can only be expressed
704 /// if there was an explicit induction variable.
705 /// @param LTS The loop to SCEV map in which the mapping from the original
706 /// loop to a SCEV representing the new loop iv is added. This
707 /// mapping does not require an explicit induction variable.
708 /// Instead, we think in terms of an implicit induction variable
709 /// that counts the number of times a loop is executed. For each
710 /// original loop this count, expressed in function of the new
711 /// induction variables, is added to the LTS map.
712 void createSubstitutions(__isl_take isl_ast_expr *Expr, ScopStmt *Stmt,
Sebastian Pop9d10fff2013-02-15 20:55:59 +0000713 ValueMapT &VMap, LoopToScevMapT &LTS);
Tobias Grosserce67a042014-07-02 16:26:47 +0000714 void createSubstitutionsVector(__isl_take isl_ast_expr *Expr, ScopStmt *Stmt,
715 VectorValueMapT &VMap,
Tobias Grossere602a072013-05-07 07:30:56 +0000716 std::vector<LoopToScevMapT> &VLTS,
717 std::vector<Value *> &IVS,
718 __isl_take isl_id *IteratorID);
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000719 void createIf(__isl_take isl_ast_node *If);
Tobias Grossere602a072013-05-07 07:30:56 +0000720 void createUserVector(__isl_take isl_ast_node *User,
721 std::vector<Value *> &IVS,
722 __isl_take isl_id *IteratorID,
723 __isl_take isl_union_map *Schedule);
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000724 void createUser(__isl_take isl_ast_node *User);
725 void createBlock(__isl_take isl_ast_node *Block);
726};
727
Tobias Grossere602a072013-05-07 07:30:56 +0000728__isl_give isl_ast_expr *
729IslNodeBuilder::getUpperBound(__isl_keep isl_ast_node *For,
730 ICmpInst::Predicate &Predicate) {
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000731 isl_id *UBID, *IteratorID;
732 isl_ast_expr *Cond, *Iterator, *UB, *Arg0;
Tobias Grosserc967d8e2012-10-16 07:29:13 +0000733 isl_ast_op_type Type;
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000734
735 Cond = isl_ast_node_for_get_cond(For);
736 Iterator = isl_ast_node_for_get_iterator(For);
Tobias Grosserc967d8e2012-10-16 07:29:13 +0000737 Type = isl_ast_expr_get_op_type(Cond);
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000738
Tobias Grosserae2d83e2012-12-29 23:57:18 +0000739 assert(isl_ast_expr_get_type(Cond) == isl_ast_expr_op &&
740 "conditional expression is not an atomic upper bound");
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000741
Tobias Grosserc967d8e2012-10-16 07:29:13 +0000742 switch (Type) {
Tobias Grosserc14582f2013-02-05 18:01:29 +0000743 case isl_ast_op_le:
744 Predicate = ICmpInst::ICMP_SLE;
745 break;
746 case isl_ast_op_lt:
747 Predicate = ICmpInst::ICMP_SLT;
748 break;
749 default:
750 llvm_unreachable("Unexpected comparision type in loop conditon");
Tobias Grosserc967d8e2012-10-16 07:29:13 +0000751 }
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000752
753 Arg0 = isl_ast_expr_get_op_arg(Cond, 0);
754
Tobias Grosserae2d83e2012-12-29 23:57:18 +0000755 assert(isl_ast_expr_get_type(Arg0) == isl_ast_expr_id &&
756 "conditional expression is not an atomic upper bound");
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000757
758 UBID = isl_ast_expr_get_id(Arg0);
759
Tobias Grosserae2d83e2012-12-29 23:57:18 +0000760 assert(isl_ast_expr_get_type(Iterator) == isl_ast_expr_id &&
761 "Could not get the iterator");
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000762
763 IteratorID = isl_ast_expr_get_id(Iterator);
764
Tobias Grosserae2d83e2012-12-29 23:57:18 +0000765 assert(UBID == IteratorID &&
766 "conditional expression is not an atomic upper bound");
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000767
768 UB = isl_ast_expr_get_op_arg(Cond, 1);
769
770 isl_ast_expr_free(Cond);
771 isl_ast_expr_free(Iterator);
772 isl_ast_expr_free(Arg0);
773 isl_id_free(IteratorID);
774 isl_id_free(UBID);
775
776 return UB;
777}
778
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000779unsigned IslNodeBuilder::getNumberOfIterations(__isl_keep isl_ast_node *For) {
780 isl_id *Annotation = isl_ast_node_get_annotation(For);
781 if (!Annotation)
782 return -1;
783
Tobias Grosserc14582f2013-02-05 18:01:29 +0000784 struct IslAstUser *Info = (struct IslAstUser *)isl_id_get_user(Annotation);
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000785 if (!Info) {
786 isl_id_free(Annotation);
787 return -1;
788 }
789
790 isl_union_map *Schedule = isl_ast_build_get_schedule(Info->Context);
791 isl_set *LoopDomain = isl_set_from_union_set(isl_union_map_range(Schedule));
792 isl_id_free(Annotation);
Sebastian Pop2aa5c242012-12-18 08:56:51 +0000793 int NumberOfIterations = polly::getNumberOfIterations(LoopDomain);
794 if (NumberOfIterations == -1)
795 return -1;
796 return NumberOfIterations + 1;
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000797}
798
Tobias Grossere602a072013-05-07 07:30:56 +0000799void IslNodeBuilder::createUserVector(__isl_take isl_ast_node *User,
800 std::vector<Value *> &IVS,
801 __isl_take isl_id *IteratorID,
802 __isl_take isl_union_map *Schedule) {
Tobias Grosserce67a042014-07-02 16:26:47 +0000803 isl_ast_expr *Expr = isl_ast_node_user_get_expr(User);
804 isl_ast_expr *StmtExpr = isl_ast_expr_get_op_arg(Expr, 0);
805 isl_id *Id = isl_ast_expr_get_id(StmtExpr);
806 isl_ast_expr_free(StmtExpr);
Tobias Grosserc14582f2013-02-05 18:01:29 +0000807 ScopStmt *Stmt = (ScopStmt *)isl_id_get_user(Id);
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000808 VectorValueMapT VectorMap(IVS.size());
Sebastian Pop9d10fff2013-02-15 20:55:59 +0000809 std::vector<LoopToScevMapT> VLTS(IVS.size());
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000810
811 isl_union_set *Domain = isl_union_set_from_set(Stmt->getDomain());
812 Schedule = isl_union_map_intersect_domain(Schedule, Domain);
813 isl_map *S = isl_map_from_union_map(Schedule);
814
Tobias Grosserce67a042014-07-02 16:26:47 +0000815 createSubstitutionsVector(Expr, Stmt, VectorMap, VLTS, IVS, IteratorID);
Sebastian Pop9d10fff2013-02-15 20:55:59 +0000816 VectorBlockGenerator::generate(Builder, *Stmt, VectorMap, VLTS, S, P);
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000817
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000818 isl_map_free(S);
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000819 isl_id_free(Id);
820 isl_ast_node_free(User);
821}
822
Tobias Grossere602a072013-05-07 07:30:56 +0000823void IslNodeBuilder::createForVector(__isl_take isl_ast_node *For,
824 int VectorWidth) {
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000825 isl_ast_node *Body = isl_ast_node_for_get_body(For);
826 isl_ast_expr *Init = isl_ast_node_for_get_init(For);
827 isl_ast_expr *Inc = isl_ast_node_for_get_inc(For);
828 isl_ast_expr *Iterator = isl_ast_node_for_get_iterator(For);
829 isl_id *IteratorID = isl_ast_expr_get_id(Iterator);
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000830
831 Value *ValueLB = ExprBuilder.create(Init);
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000832 Value *ValueInc = ExprBuilder.create(Inc);
833
834 Type *MaxType = ExprBuilder.getType(Iterator);
835 MaxType = ExprBuilder.getWidestType(MaxType, ValueLB->getType());
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000836 MaxType = ExprBuilder.getWidestType(MaxType, ValueInc->getType());
837
838 if (MaxType != ValueLB->getType())
839 ValueLB = Builder.CreateSExt(ValueLB, MaxType);
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000840 if (MaxType != ValueInc->getType())
841 ValueInc = Builder.CreateSExt(ValueInc, MaxType);
842
Tobias Grosserc14582f2013-02-05 18:01:29 +0000843 std::vector<Value *> IVS(VectorWidth);
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000844 IVS[0] = ValueLB;
845
846 for (int i = 1; i < VectorWidth; i++)
Tobias Grosserc14582f2013-02-05 18:01:29 +0000847 IVS[i] = Builder.CreateAdd(IVS[i - 1], ValueInc, "p_vector_iv");
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000848
849 isl_id *Annotation = isl_ast_node_get_annotation(For);
850 assert(Annotation && "For statement is not annotated");
851
Tobias Grosserc14582f2013-02-05 18:01:29 +0000852 struct IslAstUser *Info = (struct IslAstUser *)isl_id_get_user(Annotation);
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000853 assert(Info && "For statement annotation does not contain info");
854
855 isl_union_map *Schedule = isl_ast_build_get_schedule(Info->Context);
856 assert(Schedule && "For statement annotation does not contain its schedule");
857
858 IDToValue[IteratorID] = ValueLB;
859
860 switch (isl_ast_node_get_type(Body)) {
861 case isl_ast_node_user:
862 createUserVector(Body, IVS, isl_id_copy(IteratorID),
863 isl_union_map_copy(Schedule));
864 break;
865 case isl_ast_node_block: {
866 isl_ast_node_list *List = isl_ast_node_block_get_children(Body);
867
868 for (int i = 0; i < isl_ast_node_list_n_ast_node(List); ++i)
869 createUserVector(isl_ast_node_list_get_ast_node(List, i), IVS,
Tobias Grosser1bb59b02012-12-29 23:47:38 +0000870 isl_id_copy(IteratorID), isl_union_map_copy(Schedule));
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000871
872 isl_ast_node_free(Body);
873 isl_ast_node_list_free(List);
874 break;
875 }
876 default:
877 isl_ast_node_dump(Body);
878 llvm_unreachable("Unhandled isl_ast_node in vectorizer");
879 }
880
881 IDToValue.erase(IteratorID);
882 isl_id_free(IteratorID);
883 isl_id_free(Annotation);
884 isl_union_map_free(Schedule);
885
886 isl_ast_node_free(For);
887 isl_ast_expr_free(Iterator);
888}
889
890void IslNodeBuilder::createForSequential(__isl_take isl_ast_node *For) {
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000891 isl_ast_node *Body;
892 isl_ast_expr *Init, *Inc, *Iterator, *UB;
893 isl_id *IteratorID;
894 Value *ValueLB, *ValueUB, *ValueInc;
895 Type *MaxType;
Tobias Grosser5db6ffd2013-05-16 06:40:06 +0000896 BasicBlock *ExitBlock;
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000897 Value *IV;
Tobias Grosserc967d8e2012-10-16 07:29:13 +0000898 CmpInst::Predicate Predicate;
Tobias Grosser37c9b8e2014-03-04 14:59:00 +0000899 bool Parallel;
900
901 Parallel = isInnermostParallel(For);
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000902
903 Body = isl_ast_node_for_get_body(For);
904
905 // isl_ast_node_for_is_degenerate(For)
906 //
907 // TODO: For degenerated loops we could generate a plain assignment.
908 // However, for now we just reuse the logic for normal loops, which will
909 // create a loop with a single iteration.
910
911 Init = isl_ast_node_for_get_init(For);
912 Inc = isl_ast_node_for_get_inc(For);
913 Iterator = isl_ast_node_for_get_iterator(For);
914 IteratorID = isl_ast_expr_get_id(Iterator);
Tobias Grosserc967d8e2012-10-16 07:29:13 +0000915 UB = getUpperBound(For, Predicate);
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000916
917 ValueLB = ExprBuilder.create(Init);
918 ValueUB = ExprBuilder.create(UB);
919 ValueInc = ExprBuilder.create(Inc);
920
921 MaxType = ExprBuilder.getType(Iterator);
922 MaxType = ExprBuilder.getWidestType(MaxType, ValueLB->getType());
923 MaxType = ExprBuilder.getWidestType(MaxType, ValueUB->getType());
924 MaxType = ExprBuilder.getWidestType(MaxType, ValueInc->getType());
925
926 if (MaxType != ValueLB->getType())
927 ValueLB = Builder.CreateSExt(ValueLB, MaxType);
928 if (MaxType != ValueUB->getType())
929 ValueUB = Builder.CreateSExt(ValueUB, MaxType);
930 if (MaxType != ValueInc->getType())
931 ValueInc = Builder.CreateSExt(ValueInc, MaxType);
932
Tobias Grosser37c9b8e2014-03-04 14:59:00 +0000933 IV = createLoop(ValueLB, ValueUB, ValueInc, Builder, P, ExitBlock, Predicate,
934 &Annotator, Parallel);
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000935 IDToValue[IteratorID] = IV;
936
937 create(Body);
938
Tobias Grosser37c9b8e2014-03-04 14:59:00 +0000939 Annotator.End();
940
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000941 IDToValue.erase(IteratorID);
942
Tobias Grosser5db6ffd2013-05-16 06:40:06 +0000943 Builder.SetInsertPoint(ExitBlock->begin());
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000944
945 isl_ast_node_free(For);
946 isl_ast_expr_free(Iterator);
947 isl_id_free(IteratorID);
948}
949
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000950void IslNodeBuilder::createFor(__isl_take isl_ast_node *For) {
951 bool Vector = PollyVectorizerChoice != VECTORIZER_NONE;
952
953 if (Vector && isInnermostParallel(For)) {
954 int VectorWidth = getNumberOfIterations(For);
955 if (1 < VectorWidth && VectorWidth <= 16) {
956 createForVector(For, VectorWidth);
957 return;
958 }
959 }
960 createForSequential(For);
961}
962
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000963void IslNodeBuilder::createIf(__isl_take isl_ast_node *If) {
964 isl_ast_expr *Cond = isl_ast_node_if_get_cond(If);
965
966 Function *F = Builder.GetInsertBlock()->getParent();
967 LLVMContext &Context = F->getContext();
968
Tobias Grosserc14582f2013-02-05 18:01:29 +0000969 BasicBlock *CondBB =
970 SplitBlock(Builder.GetInsertBlock(), Builder.GetInsertPoint(), P);
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000971 CondBB->setName("polly.cond");
972 BasicBlock *MergeBB = SplitBlock(CondBB, CondBB->begin(), P);
973 MergeBB->setName("polly.merge");
974 BasicBlock *ThenBB = BasicBlock::Create(Context, "polly.then", F);
975 BasicBlock *ElseBB = BasicBlock::Create(Context, "polly.else", F);
976
Tobias Grosser42aff302014-01-13 22:29:56 +0000977 DominatorTree &DT = P->getAnalysis<DominatorTreeWrapperPass>().getDomTree();
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000978 DT.addNewBlock(ThenBB, CondBB);
979 DT.addNewBlock(ElseBB, CondBB);
980 DT.changeImmediateDominator(MergeBB, CondBB);
981
Tobias Grosser3081b0f2013-05-16 06:40:24 +0000982 LoopInfo &LI = P->getAnalysis<LoopInfo>();
983 Loop *L = LI.getLoopFor(CondBB);
984 if (L) {
985 L->addBasicBlockToLoop(ThenBB, LI.getBase());
986 L->addBasicBlockToLoop(ElseBB, LI.getBase());
987 }
988
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000989 CondBB->getTerminator()->eraseFromParent();
990
991 Builder.SetInsertPoint(CondBB);
992 Value *Predicate = ExprBuilder.create(Cond);
993 Builder.CreateCondBr(Predicate, ThenBB, ElseBB);
994 Builder.SetInsertPoint(ThenBB);
995 Builder.CreateBr(MergeBB);
996 Builder.SetInsertPoint(ElseBB);
997 Builder.CreateBr(MergeBB);
998 Builder.SetInsertPoint(ThenBB->begin());
999
1000 create(isl_ast_node_if_get_then(If));
1001
1002 Builder.SetInsertPoint(ElseBB->begin());
1003
1004 if (isl_ast_node_if_has_else(If))
1005 create(isl_ast_node_if_get_else(If));
1006
1007 Builder.SetInsertPoint(MergeBB->begin());
1008
1009 isl_ast_node_free(If);
1010}
1011
Tobias Grosserce67a042014-07-02 16:26:47 +00001012void IslNodeBuilder::createSubstitutions(isl_ast_expr *Expr, ScopStmt *Stmt,
1013 ValueMapT &VMap, LoopToScevMapT &LTS) {
1014 assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
1015 "Expression of type 'op' expected");
1016 assert(isl_ast_expr_get_op_type(Expr) == isl_ast_op_call &&
1017 "Opertation of type 'call' expected");
1018 for (int i = 0; i < isl_ast_expr_get_op_n_arg(Expr) - 1; ++i) {
1019 isl_ast_expr *SubExpr;
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001020 Value *V;
1021
Tobias Grosserce67a042014-07-02 16:26:47 +00001022 SubExpr = isl_ast_expr_get_op_arg(Expr, i + 1);
1023 V = ExprBuilder.create(SubExpr);
Sebastian Pope039bb12013-03-18 19:09:49 +00001024 ScalarEvolution *SE = Stmt->getParent()->getSE();
1025 LTS[Stmt->getLoopForDimension(i)] = SE->getUnknown(V);
1026
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001027 // CreateIntCast can introduce trunc expressions. This is correct, as the
1028 // result will always fit into the type of the original induction variable
1029 // (because we calculate a value of the original induction variable).
Sebastian Pope039bb12013-03-18 19:09:49 +00001030 const Value *OldIV = Stmt->getInductionVariableForDimension(i);
1031 if (OldIV) {
1032 V = Builder.CreateIntCast(V, OldIV->getType(), true);
1033 VMap[OldIV] = V;
1034 }
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001035 }
1036
Tobias Grosserce67a042014-07-02 16:26:47 +00001037 isl_ast_expr_free(Expr);
Sebastian Pop04c4ce32012-12-18 07:46:13 +00001038}
1039
Tobias Grosserc14582f2013-02-05 18:01:29 +00001040void IslNodeBuilder::createSubstitutionsVector(
Tobias Grosserce67a042014-07-02 16:26:47 +00001041 __isl_take isl_ast_expr *Expr, ScopStmt *Stmt, VectorValueMapT &VMap,
1042 std::vector<LoopToScevMapT> &VLTS, std::vector<Value *> &IVS,
1043 __isl_take isl_id *IteratorID) {
Sebastian Pop04c4ce32012-12-18 07:46:13 +00001044 int i = 0;
1045
1046 Value *OldValue = IDToValue[IteratorID];
Tobias Grosser91f5b262014-06-04 08:06:40 +00001047 for (Value *IV : IVS) {
1048 IDToValue[IteratorID] = IV;
Tobias Grosserce67a042014-07-02 16:26:47 +00001049 createSubstitutions(isl_ast_expr_copy(Expr), Stmt, VMap[i], VLTS[i]);
Sebastian Pop04c4ce32012-12-18 07:46:13 +00001050 i++;
1051 }
1052
1053 IDToValue[IteratorID] = OldValue;
1054 isl_id_free(IteratorID);
Tobias Grosserce67a042014-07-02 16:26:47 +00001055 isl_ast_expr_free(Expr);
Sebastian Pop04c4ce32012-12-18 07:46:13 +00001056}
1057
1058void IslNodeBuilder::createUser(__isl_take isl_ast_node *User) {
1059 ValueMapT VMap;
Sebastian Pop9d10fff2013-02-15 20:55:59 +00001060 LoopToScevMapT LTS;
Tobias Grosserce67a042014-07-02 16:26:47 +00001061 isl_id *Id;
Sebastian Pop04c4ce32012-12-18 07:46:13 +00001062 ScopStmt *Stmt;
1063
Tobias Grosserce67a042014-07-02 16:26:47 +00001064 isl_ast_expr *Expr = isl_ast_node_user_get_expr(User);
1065 isl_ast_expr *StmtExpr = isl_ast_expr_get_op_arg(Expr, 0);
1066 Id = isl_ast_expr_get_id(StmtExpr);
1067 isl_ast_expr_free(StmtExpr);
Sebastian Pop04c4ce32012-12-18 07:46:13 +00001068
Tobias Grosserc14582f2013-02-05 18:01:29 +00001069 Stmt = (ScopStmt *)isl_id_get_user(Id);
Tobias Grosserce67a042014-07-02 16:26:47 +00001070 createSubstitutions(Expr, Stmt, VMap, LTS);
Sebastian Pop9d10fff2013-02-15 20:55:59 +00001071 BlockGenerator::generate(Builder, *Stmt, VMap, LTS, P);
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001072
1073 isl_ast_node_free(User);
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001074 isl_id_free(Id);
1075}
1076
1077void IslNodeBuilder::createBlock(__isl_take isl_ast_node *Block) {
1078 isl_ast_node_list *List = isl_ast_node_block_get_children(Block);
1079
1080 for (int i = 0; i < isl_ast_node_list_n_ast_node(List); ++i)
1081 create(isl_ast_node_list_get_ast_node(List, i));
1082
1083 isl_ast_node_free(Block);
1084 isl_ast_node_list_free(List);
1085}
1086
1087void IslNodeBuilder::create(__isl_take isl_ast_node *Node) {
1088 switch (isl_ast_node_get_type(Node)) {
1089 case isl_ast_node_error:
1090 llvm_unreachable("code generation error");
1091 case isl_ast_node_for:
1092 createFor(Node);
1093 return;
1094 case isl_ast_node_if:
1095 createIf(Node);
1096 return;
1097 case isl_ast_node_user:
1098 createUser(Node);
1099 return;
1100 case isl_ast_node_block:
1101 createBlock(Node);
1102 return;
1103 }
1104
1105 llvm_unreachable("Unknown isl_ast_node type");
1106}
1107
1108void IslNodeBuilder::addParameters(__isl_take isl_set *Context) {
1109 SCEVExpander Rewriter(P->getAnalysis<ScalarEvolution>(), "polly");
1110
1111 for (unsigned i = 0; i < isl_set_dim(Context, isl_dim_param); ++i) {
1112 isl_id *Id;
1113 const SCEV *Scev;
1114 IntegerType *T;
1115 Instruction *InsertLocation;
1116
1117 Id = isl_set_get_dim_id(Context, isl_dim_param, i);
Tobias Grosserc14582f2013-02-05 18:01:29 +00001118 Scev = (const SCEV *)isl_id_get_user(Id);
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001119 T = dyn_cast<IntegerType>(Scev->getType());
1120 InsertLocation = --(Builder.GetInsertBlock()->end());
1121 Value *V = Rewriter.expandCodeFor(Scev, T, InsertLocation);
1122 IDToValue[Id] = V;
1123
1124 isl_id_free(Id);
1125 }
1126
1127 isl_set_free(Context);
1128}
1129
1130namespace {
1131class IslCodeGeneration : public ScopPass {
Tobias Grosser1bb59b02012-12-29 23:47:38 +00001132public:
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001133 static char ID;
1134
1135 IslCodeGeneration() : ScopPass(ID) {}
1136
1137 bool runOnScop(Scop &S) {
1138 IslAstInfo &AstInfo = getAnalysis<IslAstInfo>();
Tobias Grosser0ee50f62013-04-10 06:55:31 +00001139
Tobias Grossere602a072013-05-07 07:30:56 +00001140 assert(!S.getRegion().isTopLevelRegion() &&
1141 "Top level regions are not supported");
Tobias Grosser0ee50f62013-04-10 06:55:31 +00001142
Tobias Grosser8edce4e2013-04-16 08:04:42 +00001143 simplifyRegion(&S, this);
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001144
1145 BasicBlock *StartBlock = executeScopConditionally(S, this);
1146 isl_ast_node *Ast = AstInfo.getAst();
Tobias Grosser37c9b8e2014-03-04 14:59:00 +00001147 LoopAnnotator Annotator;
1148 PollyIRBuilder Builder(StartBlock->getContext(), llvm::ConstantFolder(),
1149 polly::IRInserter(Annotator));
1150 Builder.SetInsertPoint(StartBlock->begin());
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001151
Tobias Grosser37c9b8e2014-03-04 14:59:00 +00001152 IslNodeBuilder NodeBuilder(Builder, Annotator, this);
Tobias Grosser54ee0ba2013-11-17 03:18:25 +00001153
Tobias Grosser5e6813d2014-07-02 17:47:48 +00001154 Builder.SetInsertPoint(StartBlock->getSinglePredecessor()->begin());
1155 NodeBuilder.addParameters(S.getContext());
Tobias Grosser54ee0ba2013-11-17 03:18:25 +00001156 // Build condition that evaluates at run-time if all assumptions taken
1157 // for the scop hold. If we detect some assumptions do not hold, the
1158 // original code is executed.
1159 Value *V = NodeBuilder.getExprBuilder().create(AstInfo.getRunCondition());
1160 Value *Zero = ConstantInt::get(V->getType(), 0);
1161 V = Builder.CreateICmp(CmpInst::ICMP_NE, Zero, V);
1162 BasicBlock *PrevBB = StartBlock->getUniquePredecessor();
1163 BranchInst *Branch = dyn_cast<BranchInst>(PrevBB->getTerminator());
1164 Branch->setCondition(V);
Tobias Grosser5e6813d2014-07-02 17:47:48 +00001165 Builder.SetInsertPoint(StartBlock->begin());
Tobias Grosser54ee0ba2013-11-17 03:18:25 +00001166
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001167 NodeBuilder.create(Ast);
1168 return true;
1169 }
1170
Tobias Grosserc14582f2013-02-05 18:01:29 +00001171 virtual void printScop(raw_ostream &OS) const {}
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001172
1173 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
Tobias Grosser42aff302014-01-13 22:29:56 +00001174 AU.addRequired<DominatorTreeWrapperPass>();
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001175 AU.addRequired<IslAstInfo>();
1176 AU.addRequired<RegionInfo>();
1177 AU.addRequired<ScalarEvolution>();
1178 AU.addRequired<ScopDetection>();
1179 AU.addRequired<ScopInfo>();
Tobias Grosserecfe21b2013-03-20 18:03:18 +00001180 AU.addRequired<LoopInfo>();
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001181
1182 AU.addPreserved<Dependences>();
1183
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001184 AU.addPreserved<LoopInfo>();
Tobias Grosser42aff302014-01-13 22:29:56 +00001185 AU.addPreserved<DominatorTreeWrapperPass>();
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001186 AU.addPreserved<IslAstInfo>();
1187 AU.addPreserved<ScopDetection>();
1188 AU.addPreserved<ScalarEvolution>();
1189
1190 // FIXME: We do not yet add regions for the newly generated code to the
1191 // region tree.
1192 AU.addPreserved<RegionInfo>();
1193 AU.addPreserved<TempScopInfo>();
1194 AU.addPreserved<ScopInfo>();
1195 AU.addPreservedID(IndependentBlocksID);
1196 }
1197};
1198}
1199
1200char IslCodeGeneration::ID = 1;
1201
Tobias Grosser7242ad92013-02-22 08:07:06 +00001202Pass *polly::createIslCodeGenerationPass() { return new IslCodeGeneration(); }
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001203
Tobias Grosser7242ad92013-02-22 08:07:06 +00001204INITIALIZE_PASS_BEGIN(IslCodeGeneration, "polly-codegen-isl",
1205 "Polly - Create LLVM-IR from SCoPs", false, false);
1206INITIALIZE_PASS_DEPENDENCY(Dependences);
Tobias Grosser42aff302014-01-13 22:29:56 +00001207INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass);
Tobias Grosser7242ad92013-02-22 08:07:06 +00001208INITIALIZE_PASS_DEPENDENCY(LoopInfo);
1209INITIALIZE_PASS_DEPENDENCY(RegionInfo);
1210INITIALIZE_PASS_DEPENDENCY(ScalarEvolution);
1211INITIALIZE_PASS_DEPENDENCY(ScopDetection);
1212INITIALIZE_PASS_END(IslCodeGeneration, "polly-codegen-isl",
1213 "Polly - Create LLVM-IR from SCoPs", false, false)