blob: fd038b9fc9cffd743948ea778128bf837bd2351d [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 Grosser8a5bc6e2012-10-02 19:50:43 +000057/// @brief Insert function calls that print certain LLVM values at run time.
58///
59/// This class inserts libc function calls to print certain LLVM values at
60/// run time.
61class RuntimeDebugBuilder {
62public:
Tobias Grosser5103ba72014-03-04 14:58:49 +000063 RuntimeDebugBuilder(PollyIRBuilder &Builder) : Builder(Builder) {}
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +000064
65 /// @brief Print a string to stdout.
66 ///
67 /// @param String The string to print.
68 void createStrPrinter(std::string String);
69
70 /// @brief Print an integer value to stdout.
71 ///
72 /// @param V The value to print.
73 void createIntPrinter(Value *V);
74
75private:
Tobias Grosser5103ba72014-03-04 14:58:49 +000076 PollyIRBuilder &Builder;
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +000077
78 /// @brief Add a call to the fflush function with no file pointer given.
79 ///
80 /// This call will flush all opened file pointers including stdout and stderr.
81 void createFlush();
82
83 /// @brief Get a reference to the 'printf' function.
84 ///
85 /// If the current module does not yet contain a reference to printf, we
86 /// insert a reference to it. Otherwise the existing reference is returned.
87 Function *getPrintF();
88};
89
90Function *RuntimeDebugBuilder::getPrintF() {
91 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
92 const char *Name = "printf";
93 Function *F = M->getFunction(Name);
94
95 if (!F) {
96 GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
Tobias Grosserc14582f2013-02-05 18:01:29 +000097 FunctionType *Ty =
98 FunctionType::get(Builder.getInt32Ty(), Builder.getInt8PtrTy(), true);
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +000099 F = Function::Create(Ty, Linkage, Name, M);
100 }
101
102 return F;
103}
104
105void RuntimeDebugBuilder::createFlush() {
106 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
107 const char *Name = "fflush";
108 Function *F = M->getFunction(Name);
109
110 if (!F) {
111 GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
Tobias Grosserc14582f2013-02-05 18:01:29 +0000112 FunctionType *Ty =
113 FunctionType::get(Builder.getInt32Ty(), Builder.getInt8PtrTy(), false);
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000114 F = Function::Create(Ty, Linkage, Name, M);
115 }
116
117 Builder.CreateCall(F, Constant::getNullValue(Builder.getInt8PtrTy()));
118}
119
120void RuntimeDebugBuilder::createStrPrinter(std::string String) {
121 Function *F = getPrintF();
122 Value *StringValue = Builder.CreateGlobalStringPtr(String);
123 Builder.CreateCall(F, StringValue);
124
125 createFlush();
126}
127
128void RuntimeDebugBuilder::createIntPrinter(Value *V) {
129 IntegerType *Ty = dyn_cast<IntegerType>(V->getType());
Tobias Grosser58032cb2013-06-23 01:29:29 +0000130 (void)Ty;
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000131 assert(Ty && Ty->getBitWidth() == 64 &&
132 "Cannot insert printer for this type.");
133
134 Function *F = getPrintF();
135 Value *String = Builder.CreateGlobalStringPtr("%ld");
136 Builder.CreateCall2(F, String, V);
137 createFlush();
138}
139
Tobias Grosser9818bc82014-04-22 14:26:51 +0000140/// @brief LLVM-IR generator for isl_ast_expr[essions]
141///
142/// This generator generates LLVM-IR that performs the computation described by
143/// an isl_ast_expr[ession].
144///
145/// Example:
146///
147/// An isl_ast_expr[ession] can look like this:
148///
149/// (N + M) + 10
150///
151/// The IslExprBuilder could create the following LLVM-IR:
152///
153/// %tmp1 = add nsw i64 %N
154/// %tmp2 = add nsw i64 %tmp1, %M
155/// %tmp3 = add nsw i64 %tmp2, 10
156///
157/// The implementation of this class is mostly a mapping from isl_ast_expr
158/// constructs to the corresponding LLVM-IR constructs.
159///
160/// The following decisions may need some explanation:
161///
162/// 1) Which data-type to choose
163///
164/// isl_ast_expr[essions] are untyped expressions that assume arbitrary
165/// precision integer computations. LLVM-IR instead has fixed size integers.
166/// When lowering to LLVM-IR we need to chose both the size of the data type and
167/// the sign of the operations we use.
168///
169/// At the moment, we hardcode i64 bit signed computations. Our experience has
170/// shown that 64 bit are generally large enough for the loop bounds that appear
171/// in the wild. Signed computations are needed, as loop bounds may become
172/// negative.
173///
174/// FIXME: Hardcoding sizes can cause issues:
175///
176/// a) Certain run-time checks that we may want to generate can involve the
177/// size of the data types the computation is performed on. When code
178/// generating these run-time checks to isl_ast_expr[essions], the
179/// resulting computation may require more than 64 bit.
180///
181/// b) On embedded systems and especially for high-level-synthesis 64 bit
182/// computations are very costly.
183///
184/// The right approach is to compute the minimal necessary bitwidth and
185/// signedness for each subexpression during in the isl AST generation and
186/// to use this information in our IslAstGenerator. Preliminary patches are
187/// available, but have not been committed yet.
188///
189/// 2) We always flag computations with 'nsw'
190///
191/// As isl_ast_expr[essions] assume arbitrary precision, no wrapping should
192/// ever occur in the generated LLVM-IR (assuming the data type chosen is large
193/// enough).
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000194class IslExprBuilder {
195public:
Tobias Grosser9818bc82014-04-22 14:26:51 +0000196 /// @brief Construct an IslExprBuilder.
197 ///
198 /// @param Builder The IRBuilder used to construct the isl_ast_expr[ession].
199 /// The insert location of this IRBuilder defines WHERE the
200 /// corresponding LLVM-IR is generated.
201 ///
202 /// @param IDToValue The isl_ast_expr[ession] may reference parameters or
203 /// variables (identified by an isl_id). The IDTOValue map
204 /// specifies the LLVM-IR Values that correspond to these
205 /// parameters and variables.
Tobias Grosser5103ba72014-03-04 14:58:49 +0000206 IslExprBuilder(PollyIRBuilder &Builder,
Tobias Grosser9818bc82014-04-22 14:26:51 +0000207 std::map<isl_id *, Value *> &IDToValue)
Tobias Grosser7242ad92013-02-22 08:07:06 +0000208 : Builder(Builder), IDToValue(IDToValue) {}
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000209
Tobias Grosser9818bc82014-04-22 14:26:51 +0000210 /// @brief Create LLVM-IR for an isl_ast_expr[ession].
211 ///
212 /// @param Expr The ast expression for which we generate LLVM-IR.
213 ///
214 /// @return The llvm::Value* containing the result of the computation.
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000215 Value *create(__isl_take isl_ast_expr *Expr);
Tobias Grosser9818bc82014-04-22 14:26:51 +0000216
217 /// @brief Return the largest of two types.
218 ///
219 /// @param T1 The first type.
220 /// @param T2 The second type.
221 ///
222 /// @return The largest of the two types.
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000223 Type *getWidestType(Type *T1, Type *T2);
Tobias Grosser9818bc82014-04-22 14:26:51 +0000224
225 /// @brief Return the type with which this expression should be computed.
226 ///
227 /// The type needs to be large enough to hold all possible input and all
228 /// possible output values.
229 ///
230 /// @param Expr The expression for which to find the type.
231 /// @return The type with which the expression should be computed.
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000232 IntegerType *getType(__isl_keep isl_ast_expr *Expr);
233
234private:
Tobias Grosser5103ba72014-03-04 14:58:49 +0000235 PollyIRBuilder &Builder;
Tobias Grosserc14582f2013-02-05 18:01:29 +0000236 std::map<isl_id *, Value *> &IDToValue;
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000237
238 Value *createOp(__isl_take isl_ast_expr *Expr);
239 Value *createOpUnary(__isl_take isl_ast_expr *Expr);
240 Value *createOpBin(__isl_take isl_ast_expr *Expr);
241 Value *createOpNAry(__isl_take isl_ast_expr *Expr);
242 Value *createOpSelect(__isl_take isl_ast_expr *Expr);
243 Value *createOpICmp(__isl_take isl_ast_expr *Expr);
244 Value *createOpBoolean(__isl_take isl_ast_expr *Expr);
245 Value *createId(__isl_take isl_ast_expr *Expr);
246 Value *createInt(__isl_take isl_ast_expr *Expr);
247};
248
249Type *IslExprBuilder::getWidestType(Type *T1, Type *T2) {
250 assert(isa<IntegerType>(T1) && isa<IntegerType>(T2));
251
252 if (T1->getPrimitiveSizeInBits() < T2->getPrimitiveSizeInBits())
253 return T2;
254 else
255 return T1;
256}
257
258Value *IslExprBuilder::createOpUnary(__isl_take isl_ast_expr *Expr) {
Tobias Grosserae2d83e2012-12-29 23:57:18 +0000259 assert(isl_ast_expr_get_op_type(Expr) == isl_ast_op_minus &&
260 "Unsupported unary operation");
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000261
262 Value *V;
263 Type *MaxType = getType(Expr);
264
265 V = create(isl_ast_expr_get_op_arg(Expr, 0));
266 MaxType = getWidestType(MaxType, V->getType());
267
268 if (MaxType != V->getType())
269 V = Builder.CreateSExt(V, MaxType);
270
271 isl_ast_expr_free(Expr);
272 return Builder.CreateNSWNeg(V);
273}
274
275Value *IslExprBuilder::createOpNAry(__isl_take isl_ast_expr *Expr) {
Tobias Grosserae2d83e2012-12-29 23:57:18 +0000276 assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
277 "isl ast expression not of type isl_ast_op");
278 assert(isl_ast_expr_get_op_n_arg(Expr) >= 2 &&
279 "We need at least two operands in an n-ary operation");
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000280
281 Value *V;
282
283 V = create(isl_ast_expr_get_op_arg(Expr, 0));
284
285 for (int i = 0; i < isl_ast_expr_get_op_n_arg(Expr); ++i) {
286 Value *OpV;
287 OpV = create(isl_ast_expr_get_op_arg(Expr, i));
288
289 Type *Ty = getWidestType(V->getType(), OpV->getType());
290
291 if (Ty != OpV->getType())
292 OpV = Builder.CreateSExt(OpV, Ty);
293
294 if (Ty != V->getType())
295 V = Builder.CreateSExt(V, Ty);
296
297 switch (isl_ast_expr_get_op_type(Expr)) {
298 default:
299 llvm_unreachable("This is no n-ary isl ast expression");
300
Tobias Grosserc14582f2013-02-05 18:01:29 +0000301 case isl_ast_op_max: {
302 Value *Cmp = Builder.CreateICmpSGT(V, OpV);
303 V = Builder.CreateSelect(Cmp, V, OpV);
304 continue;
305 }
306 case isl_ast_op_min: {
307 Value *Cmp = Builder.CreateICmpSLT(V, OpV);
308 V = Builder.CreateSelect(Cmp, V, OpV);
309 continue;
310 }
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000311 }
312 }
313
314 // TODO: We can truncate the result, if it fits into a smaller type. This can
315 // help in cases where we have larger operands (e.g. i67) but the result is
316 // known to fit into i64. Without the truncation, the larger i67 type may
317 // force all subsequent operations to be performed on a non-native type.
318 isl_ast_expr_free(Expr);
319 return V;
320}
321
322Value *IslExprBuilder::createOpBin(__isl_take isl_ast_expr *Expr) {
323 Value *LHS, *RHS, *Res;
324 Type *MaxType;
325 isl_ast_op_type OpType;
326
Tobias Grosserae2d83e2012-12-29 23:57:18 +0000327 assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
328 "isl ast expression not of type isl_ast_op");
329 assert(isl_ast_expr_get_op_n_arg(Expr) == 2 &&
330 "not a binary isl ast expression");
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000331
332 OpType = isl_ast_expr_get_op_type(Expr);
333
334 LHS = create(isl_ast_expr_get_op_arg(Expr, 0));
335 RHS = create(isl_ast_expr_get_op_arg(Expr, 1));
336
337 MaxType = LHS->getType();
338 MaxType = getWidestType(MaxType, RHS->getType());
339
340 // Take the result into account when calculating the widest type.
341 //
342 // For operations such as '+' the result may require a type larger than
343 // the type of the individual operands. For other operations such as '/', the
344 // result type cannot be larger than the type of the individual operand. isl
345 // does not calculate correct types for these operations and we consequently
346 // exclude those operations here.
Tobias Grosser1bb59b02012-12-29 23:47:38 +0000347 switch (OpType) {
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000348 case isl_ast_op_pdiv_q:
349 case isl_ast_op_pdiv_r:
350 case isl_ast_op_div:
351 case isl_ast_op_fdiv_q:
352 // Do nothing
353 break;
354 case isl_ast_op_add:
355 case isl_ast_op_sub:
356 case isl_ast_op_mul:
357 MaxType = getWidestType(MaxType, getType(Expr));
358 break;
359 default:
360 llvm_unreachable("This is no binary isl ast expression");
361 }
362
363 if (MaxType != RHS->getType())
364 RHS = Builder.CreateSExt(RHS, MaxType);
365
366 if (MaxType != LHS->getType())
367 LHS = Builder.CreateSExt(LHS, MaxType);
368
369 switch (OpType) {
370 default:
371 llvm_unreachable("This is no binary isl ast expression");
372 case isl_ast_op_add:
373 Res = Builder.CreateNSWAdd(LHS, RHS);
374 break;
375 case isl_ast_op_sub:
376 Res = Builder.CreateNSWSub(LHS, RHS);
377 break;
378 case isl_ast_op_mul:
379 Res = Builder.CreateNSWMul(LHS, RHS);
380 break;
381 case isl_ast_op_div:
382 case isl_ast_op_pdiv_q: // Dividend is non-negative
383 Res = Builder.CreateSDiv(LHS, RHS);
384 break;
Tobias Grosserc14582f2013-02-05 18:01:29 +0000385 case isl_ast_op_fdiv_q: { // Round towards -infty
386 // TODO: Review code and check that this calculation does not yield
387 // incorrect overflow in some bordercases.
388 //
389 // floord(n,d) ((n < 0) ? (n - d + 1) : n) / d
390 Value *One = ConstantInt::get(MaxType, 1);
391 Value *Zero = ConstantInt::get(MaxType, 0);
392 Value *Sum1 = Builder.CreateSub(LHS, RHS);
393 Value *Sum2 = Builder.CreateAdd(Sum1, One);
394 Value *isNegative = Builder.CreateICmpSLT(LHS, Zero);
395 Value *Dividend = Builder.CreateSelect(isNegative, Sum2, LHS);
396 Res = Builder.CreateSDiv(Dividend, RHS);
397 break;
398 }
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000399 case isl_ast_op_pdiv_r: // Dividend is non-negative
400 Res = Builder.CreateSRem(LHS, RHS);
401 break;
402 }
403
404 // TODO: We can truncate the result, if it fits into a smaller type. This can
405 // help in cases where we have larger operands (e.g. i67) but the result is
406 // known to fit into i64. Without the truncation, the larger i67 type may
407 // force all subsequent operations to be performed on a non-native type.
408 isl_ast_expr_free(Expr);
409 return Res;
410}
411
412Value *IslExprBuilder::createOpSelect(__isl_take isl_ast_expr *Expr) {
Tobias Grosserae2d83e2012-12-29 23:57:18 +0000413 assert(isl_ast_expr_get_op_type(Expr) == isl_ast_op_select &&
414 "Unsupported unary isl ast expression");
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000415 Value *LHS, *RHS, *Cond;
416 Type *MaxType = getType(Expr);
417
418 Cond = create(isl_ast_expr_get_op_arg(Expr, 0));
419
420 LHS = create(isl_ast_expr_get_op_arg(Expr, 1));
421 RHS = create(isl_ast_expr_get_op_arg(Expr, 2));
422
423 MaxType = getWidestType(MaxType, LHS->getType());
424 MaxType = getWidestType(MaxType, RHS->getType());
425
426 if (MaxType != RHS->getType())
427 RHS = Builder.CreateSExt(RHS, MaxType);
428
429 if (MaxType != LHS->getType())
430 LHS = Builder.CreateSExt(LHS, MaxType);
431
432 // TODO: Do we want to truncate the result?
433 isl_ast_expr_free(Expr);
434 return Builder.CreateSelect(Cond, LHS, RHS);
435}
436
437Value *IslExprBuilder::createOpICmp(__isl_take isl_ast_expr *Expr) {
438 assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
439 "Expected an isl_ast_expr_op expression");
440
441 Value *LHS, *RHS, *Res;
442
443 LHS = create(isl_ast_expr_get_op_arg(Expr, 0));
444 RHS = create(isl_ast_expr_get_op_arg(Expr, 1));
445
446 Type *MaxType = LHS->getType();
447 MaxType = getWidestType(MaxType, RHS->getType());
448
449 if (MaxType != RHS->getType())
450 RHS = Builder.CreateSExt(RHS, MaxType);
451
452 if (MaxType != LHS->getType())
453 LHS = Builder.CreateSExt(LHS, MaxType);
454
455 switch (isl_ast_expr_get_op_type(Expr)) {
456 default:
457 llvm_unreachable("Unsupported ICmp isl ast expression");
458 case isl_ast_op_eq:
459 Res = Builder.CreateICmpEQ(LHS, RHS);
460 break;
461 case isl_ast_op_le:
462 Res = Builder.CreateICmpSLE(LHS, RHS);
463 break;
Tobias Grosserc967d8e2012-10-16 07:29:13 +0000464 case isl_ast_op_lt:
465 Res = Builder.CreateICmpSLT(LHS, RHS);
466 break;
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000467 case isl_ast_op_ge:
468 Res = Builder.CreateICmpSGE(LHS, RHS);
469 break;
Tobias Grosserc967d8e2012-10-16 07:29:13 +0000470 case isl_ast_op_gt:
471 Res = Builder.CreateICmpSGT(LHS, RHS);
472 break;
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000473 }
474
475 isl_ast_expr_free(Expr);
476 return Res;
477}
478
479Value *IslExprBuilder::createOpBoolean(__isl_take isl_ast_expr *Expr) {
480 assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
481 "Expected an isl_ast_expr_op expression");
482
483 Value *LHS, *RHS, *Res;
484 isl_ast_op_type OpType;
485
486 OpType = isl_ast_expr_get_op_type(Expr);
487
488 assert((OpType == isl_ast_op_and || OpType == isl_ast_op_or) &&
489 "Unsupported isl_ast_op_type");
490
491 LHS = create(isl_ast_expr_get_op_arg(Expr, 0));
492 RHS = create(isl_ast_expr_get_op_arg(Expr, 1));
493
494 // Even though the isl pretty printer prints the expressions as 'exp && exp'
495 // or 'exp || exp', we actually code generate the bitwise expressions
496 // 'exp & exp' or 'exp | exp'. This forces the evaluation of both branches,
497 // but it is, due to the use of i1 types, otherwise equivalent. The reason
498 // to go for bitwise operations is, that we assume the reduced control flow
499 // will outweight the overhead introduced by evaluating unneeded expressions.
500 // The isl code generation currently does not take advantage of the fact that
501 // the expression after an '||' or '&&' is in some cases not evaluated.
502 // Evaluating it anyways does not cause any undefined behaviour.
503 //
504 // TODO: Document in isl itself, that the unconditionally evaluating the
505 // second part of '||' or '&&' expressions is safe.
506 assert(LHS->getType() == Builder.getInt1Ty() && "Expected i1 type");
507 assert(RHS->getType() == Builder.getInt1Ty() && "Expected i1 type");
508
509 switch (OpType) {
510 default:
511 llvm_unreachable("Unsupported boolean expression");
512 case isl_ast_op_and:
513 Res = Builder.CreateAnd(LHS, RHS);
514 break;
515 case isl_ast_op_or:
516 Res = Builder.CreateOr(LHS, RHS);
517 break;
518 }
519
520 isl_ast_expr_free(Expr);
521 return Res;
522}
523
524Value *IslExprBuilder::createOp(__isl_take isl_ast_expr *Expr) {
Tobias Grosserae2d83e2012-12-29 23:57:18 +0000525 assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
526 "Expression not of type isl_ast_expr_op");
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000527 switch (isl_ast_expr_get_op_type(Expr)) {
528 case isl_ast_op_error:
529 case isl_ast_op_cond:
530 case isl_ast_op_and_then:
531 case isl_ast_op_or_else:
532 case isl_ast_op_call:
Tobias Grossera38c9242014-01-26 19:36:28 +0000533 case isl_ast_op_member:
534 case isl_ast_op_access:
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000535 llvm_unreachable("Unsupported isl ast expression");
536 case isl_ast_op_max:
537 case isl_ast_op_min:
538 return createOpNAry(Expr);
539 case isl_ast_op_add:
540 case isl_ast_op_sub:
541 case isl_ast_op_mul:
542 case isl_ast_op_div:
543 case isl_ast_op_fdiv_q: // Round towards -infty
544 case isl_ast_op_pdiv_q: // Dividend is non-negative
545 case isl_ast_op_pdiv_r: // Dividend is non-negative
546 return createOpBin(Expr);
547 case isl_ast_op_minus:
548 return createOpUnary(Expr);
549 case isl_ast_op_select:
550 return createOpSelect(Expr);
551 case isl_ast_op_and:
552 case isl_ast_op_or:
553 return createOpBoolean(Expr);
554 case isl_ast_op_eq:
555 case isl_ast_op_le:
Tobias Grosserc967d8e2012-10-16 07:29:13 +0000556 case isl_ast_op_lt:
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000557 case isl_ast_op_ge:
Tobias Grosserc967d8e2012-10-16 07:29:13 +0000558 case isl_ast_op_gt:
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000559 return createOpICmp(Expr);
560 }
561
562 llvm_unreachable("Unsupported isl_ast_expr_op kind.");
563}
564
565Value *IslExprBuilder::createId(__isl_take isl_ast_expr *Expr) {
Tobias Grosserae2d83e2012-12-29 23:57:18 +0000566 assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_id &&
567 "Expression not of type isl_ast_expr_ident");
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000568
569 isl_id *Id;
570 Value *V;
571
572 Id = isl_ast_expr_get_id(Expr);
573
574 assert(IDToValue.count(Id) && "Identifier not found");
575
576 V = IDToValue[Id];
577
578 isl_id_free(Id);
579 isl_ast_expr_free(Expr);
580
581 return V;
582}
583
584IntegerType *IslExprBuilder::getType(__isl_keep isl_ast_expr *Expr) {
585 // XXX: We assume i64 is large enough. This is often true, but in general
586 // incorrect. Also, on 32bit architectures, it would be beneficial to
587 // use a smaller type. We can and should directly derive this information
588 // during code generation.
589 return IntegerType::get(Builder.getContext(), 64);
590}
591
592Value *IslExprBuilder::createInt(__isl_take isl_ast_expr *Expr) {
Tobias Grosserae2d83e2012-12-29 23:57:18 +0000593 assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_int &&
594 "Expression not of type isl_ast_expr_int");
Tobias Grosseredab1352013-06-21 06:41:31 +0000595 isl_val *Val;
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000596 Value *V;
597 APInt APValue;
598 IntegerType *T;
599
Tobias Grosseredab1352013-06-21 06:41:31 +0000600 Val = isl_ast_expr_get_val(Expr);
601 APValue = APIntFromVal(Val);
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000602 T = getType(Expr);
603 APValue = APValue.sextOrSelf(T->getBitWidth());
604 V = ConstantInt::get(T, APValue);
605
606 isl_ast_expr_free(Expr);
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000607 return V;
608}
609
610Value *IslExprBuilder::create(__isl_take isl_ast_expr *Expr) {
611 switch (isl_ast_expr_get_type(Expr)) {
612 case isl_ast_expr_error:
613 llvm_unreachable("Code generation error");
614 case isl_ast_expr_op:
615 return createOp(Expr);
616 case isl_ast_expr_id:
617 return createId(Expr);
618 case isl_ast_expr_int:
619 return createInt(Expr);
620 }
621
622 llvm_unreachable("Unexpected enum value");
623}
624
625class IslNodeBuilder {
626public:
Tobias Grosser37c9b8e2014-03-04 14:59:00 +0000627 IslNodeBuilder(PollyIRBuilder &Builder, LoopAnnotator &Annotator, Pass *P)
Tobias Grosser34c87872014-04-22 16:39:41 +0000628 : Builder(Builder), Annotator(Annotator), ExprBuilder(Builder, IDToValue),
629 P(P) {}
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000630
631 void addParameters(__isl_take isl_set *Context);
632 void create(__isl_take isl_ast_node *Node);
Tobias Grosser54ee0ba2013-11-17 03:18:25 +0000633 IslExprBuilder &getExprBuilder() { return ExprBuilder; }
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000634
635private:
Tobias Grosser5103ba72014-03-04 14:58:49 +0000636 PollyIRBuilder &Builder;
Tobias Grosser37c9b8e2014-03-04 14:59:00 +0000637 LoopAnnotator &Annotator;
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000638 IslExprBuilder ExprBuilder;
639 Pass *P;
640
641 // This maps an isl_id* to the Value* it has in the generated program. For now
642 // on, the only isl_ids that are stored here are the newly calculated loop
643 // ivs.
Tobias Grosserc14582f2013-02-05 18:01:29 +0000644 std::map<isl_id *, Value *> IDToValue;
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000645
646 // Extract the upper bound of this loop
647 //
648 // The isl code generation can generate arbitrary expressions to check if the
649 // upper bound of a loop is reached, but it provides an option to enforce
650 // 'atomic' upper bounds. An 'atomic upper bound is always of the form
651 // iv <= expr, where expr is an (arbitrary) expression not containing iv.
652 //
653 // This function extracts 'atomic' upper bounds. Polly, in general, requires
654 // atomic upper bounds for the following reasons:
655 //
656 // 1. An atomic upper bound is loop invariant
657 //
658 // It must not be calculated at each loop iteration and can often even be
659 // hoisted out further by the loop invariant code motion.
660 //
661 // 2. OpenMP needs a loop invarient upper bound to calculate the number
662 // of loop iterations.
663 //
664 // 3. With the existing code, upper bounds have been easier to implement.
Tobias Grossere602a072013-05-07 07:30:56 +0000665 __isl_give isl_ast_expr *getUpperBound(__isl_keep isl_ast_node *For,
666 CmpInst::Predicate &Predicate);
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000667
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000668 unsigned getNumberOfIterations(__isl_keep isl_ast_node *For);
669
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000670 void createFor(__isl_take isl_ast_node *For);
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000671 void createForVector(__isl_take isl_ast_node *For, int VectorWidth);
672 void createForSequential(__isl_take isl_ast_node *For);
Tobias Grosserce67a042014-07-02 16:26:47 +0000673
674 /// Generate LLVM-IR that computes the values of the original induction
675 /// variables in function of the newly generated loop induction variables.
676 ///
677 /// Example:
678 ///
679 /// // Original
680 /// for i
681 /// for j
682 /// S(i)
683 ///
684 /// Schedule: [i,j] -> [i+j, j]
685 ///
686 /// // New
687 /// for c0
688 /// for c1
689 /// S(c0 - c1, c1)
690 ///
691 /// Assuming the original code consists of two loops which are
692 /// transformed according to a schedule [i,j] -> [c0=i+j,c1=j]. The resulting
693 /// ast models the original statement as a call expression where each argument
694 /// is an expression that computes the old induction variables from the new
695 /// ones, ordered such that the first argument computes the value of induction
696 /// variable that was outermost in the original code.
697 ///
698 /// @param Expr The call expression that represents the statement.
699 /// @param Stmt The statement that is called.
700 /// @param VMap The value map into which the mapping from the old induction
701 /// variable to the new one is inserted. This mapping is used
702 /// for the classical code generation (not scev-based) and
703 /// gives an explicit mapping from an original, materialized
704 /// induction variable. It consequently can only be expressed
705 /// if there was an explicit induction variable.
706 /// @param LTS The loop to SCEV map in which the mapping from the original
707 /// loop to a SCEV representing the new loop iv is added. This
708 /// mapping does not require an explicit induction variable.
709 /// Instead, we think in terms of an implicit induction variable
710 /// that counts the number of times a loop is executed. For each
711 /// original loop this count, expressed in function of the new
712 /// induction variables, is added to the LTS map.
713 void createSubstitutions(__isl_take isl_ast_expr *Expr, ScopStmt *Stmt,
Sebastian Pop9d10fff2013-02-15 20:55:59 +0000714 ValueMapT &VMap, LoopToScevMapT &LTS);
Tobias Grosserce67a042014-07-02 16:26:47 +0000715 void createSubstitutionsVector(__isl_take isl_ast_expr *Expr, ScopStmt *Stmt,
716 VectorValueMapT &VMap,
Tobias Grossere602a072013-05-07 07:30:56 +0000717 std::vector<LoopToScevMapT> &VLTS,
718 std::vector<Value *> &IVS,
719 __isl_take isl_id *IteratorID);
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000720 void createIf(__isl_take isl_ast_node *If);
Tobias Grossere602a072013-05-07 07:30:56 +0000721 void createUserVector(__isl_take isl_ast_node *User,
722 std::vector<Value *> &IVS,
723 __isl_take isl_id *IteratorID,
724 __isl_take isl_union_map *Schedule);
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000725 void createUser(__isl_take isl_ast_node *User);
726 void createBlock(__isl_take isl_ast_node *Block);
727};
728
Tobias Grossere602a072013-05-07 07:30:56 +0000729__isl_give isl_ast_expr *
730IslNodeBuilder::getUpperBound(__isl_keep isl_ast_node *For,
731 ICmpInst::Predicate &Predicate) {
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000732 isl_id *UBID, *IteratorID;
733 isl_ast_expr *Cond, *Iterator, *UB, *Arg0;
Tobias Grosserc967d8e2012-10-16 07:29:13 +0000734 isl_ast_op_type Type;
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000735
736 Cond = isl_ast_node_for_get_cond(For);
737 Iterator = isl_ast_node_for_get_iterator(For);
Tobias Grosserc967d8e2012-10-16 07:29:13 +0000738 Type = isl_ast_expr_get_op_type(Cond);
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000739
Tobias Grosserae2d83e2012-12-29 23:57:18 +0000740 assert(isl_ast_expr_get_type(Cond) == isl_ast_expr_op &&
741 "conditional expression is not an atomic upper bound");
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000742
Tobias Grosserc967d8e2012-10-16 07:29:13 +0000743 switch (Type) {
Tobias Grosserc14582f2013-02-05 18:01:29 +0000744 case isl_ast_op_le:
745 Predicate = ICmpInst::ICMP_SLE;
746 break;
747 case isl_ast_op_lt:
748 Predicate = ICmpInst::ICMP_SLT;
749 break;
750 default:
751 llvm_unreachable("Unexpected comparision type in loop conditon");
Tobias Grosserc967d8e2012-10-16 07:29:13 +0000752 }
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000753
754 Arg0 = isl_ast_expr_get_op_arg(Cond, 0);
755
Tobias Grosserae2d83e2012-12-29 23:57:18 +0000756 assert(isl_ast_expr_get_type(Arg0) == isl_ast_expr_id &&
757 "conditional expression is not an atomic upper bound");
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000758
759 UBID = isl_ast_expr_get_id(Arg0);
760
Tobias Grosserae2d83e2012-12-29 23:57:18 +0000761 assert(isl_ast_expr_get_type(Iterator) == isl_ast_expr_id &&
762 "Could not get the iterator");
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000763
764 IteratorID = isl_ast_expr_get_id(Iterator);
765
Tobias Grosserae2d83e2012-12-29 23:57:18 +0000766 assert(UBID == IteratorID &&
767 "conditional expression is not an atomic upper bound");
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000768
769 UB = isl_ast_expr_get_op_arg(Cond, 1);
770
771 isl_ast_expr_free(Cond);
772 isl_ast_expr_free(Iterator);
773 isl_ast_expr_free(Arg0);
774 isl_id_free(IteratorID);
775 isl_id_free(UBID);
776
777 return UB;
778}
779
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000780unsigned IslNodeBuilder::getNumberOfIterations(__isl_keep isl_ast_node *For) {
Johannes Doerfert94d90822014-07-23 20:26:25 +0000781 isl_union_map *Schedule = IslAstInfo::getSchedule(For);
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000782 isl_set *LoopDomain = isl_set_from_union_set(isl_union_map_range(Schedule));
Sebastian Pop2aa5c242012-12-18 08:56:51 +0000783 int NumberOfIterations = polly::getNumberOfIterations(LoopDomain);
784 if (NumberOfIterations == -1)
785 return -1;
786 return NumberOfIterations + 1;
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000787}
788
Tobias Grossere602a072013-05-07 07:30:56 +0000789void IslNodeBuilder::createUserVector(__isl_take isl_ast_node *User,
790 std::vector<Value *> &IVS,
791 __isl_take isl_id *IteratorID,
792 __isl_take isl_union_map *Schedule) {
Tobias Grosserce67a042014-07-02 16:26:47 +0000793 isl_ast_expr *Expr = isl_ast_node_user_get_expr(User);
794 isl_ast_expr *StmtExpr = isl_ast_expr_get_op_arg(Expr, 0);
795 isl_id *Id = isl_ast_expr_get_id(StmtExpr);
796 isl_ast_expr_free(StmtExpr);
Tobias Grosserc14582f2013-02-05 18:01:29 +0000797 ScopStmt *Stmt = (ScopStmt *)isl_id_get_user(Id);
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000798 VectorValueMapT VectorMap(IVS.size());
Sebastian Pop9d10fff2013-02-15 20:55:59 +0000799 std::vector<LoopToScevMapT> VLTS(IVS.size());
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000800
801 isl_union_set *Domain = isl_union_set_from_set(Stmt->getDomain());
802 Schedule = isl_union_map_intersect_domain(Schedule, Domain);
803 isl_map *S = isl_map_from_union_map(Schedule);
804
Tobias Grosserce67a042014-07-02 16:26:47 +0000805 createSubstitutionsVector(Expr, Stmt, VectorMap, VLTS, IVS, IteratorID);
Sebastian Pop9d10fff2013-02-15 20:55:59 +0000806 VectorBlockGenerator::generate(Builder, *Stmt, VectorMap, VLTS, S, P);
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000807
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000808 isl_map_free(S);
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000809 isl_id_free(Id);
810 isl_ast_node_free(User);
811}
812
Tobias Grossere602a072013-05-07 07:30:56 +0000813void IslNodeBuilder::createForVector(__isl_take isl_ast_node *For,
814 int VectorWidth) {
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000815 isl_ast_node *Body = isl_ast_node_for_get_body(For);
816 isl_ast_expr *Init = isl_ast_node_for_get_init(For);
817 isl_ast_expr *Inc = isl_ast_node_for_get_inc(For);
818 isl_ast_expr *Iterator = isl_ast_node_for_get_iterator(For);
819 isl_id *IteratorID = isl_ast_expr_get_id(Iterator);
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000820
821 Value *ValueLB = ExprBuilder.create(Init);
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000822 Value *ValueInc = ExprBuilder.create(Inc);
823
824 Type *MaxType = ExprBuilder.getType(Iterator);
825 MaxType = ExprBuilder.getWidestType(MaxType, ValueLB->getType());
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000826 MaxType = ExprBuilder.getWidestType(MaxType, ValueInc->getType());
827
828 if (MaxType != ValueLB->getType())
829 ValueLB = Builder.CreateSExt(ValueLB, MaxType);
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000830 if (MaxType != ValueInc->getType())
831 ValueInc = Builder.CreateSExt(ValueInc, MaxType);
832
Tobias Grosserc14582f2013-02-05 18:01:29 +0000833 std::vector<Value *> IVS(VectorWidth);
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000834 IVS[0] = ValueLB;
835
836 for (int i = 1; i < VectorWidth; i++)
Tobias Grosserc14582f2013-02-05 18:01:29 +0000837 IVS[i] = Builder.CreateAdd(IVS[i - 1], ValueInc, "p_vector_iv");
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000838
Johannes Doerfert94d90822014-07-23 20:26:25 +0000839 isl_union_map *Schedule = IslAstInfo::getSchedule(For);
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000840 assert(Schedule && "For statement annotation does not contain its schedule");
841
842 IDToValue[IteratorID] = ValueLB;
843
844 switch (isl_ast_node_get_type(Body)) {
845 case isl_ast_node_user:
846 createUserVector(Body, IVS, isl_id_copy(IteratorID),
847 isl_union_map_copy(Schedule));
848 break;
849 case isl_ast_node_block: {
850 isl_ast_node_list *List = isl_ast_node_block_get_children(Body);
851
852 for (int i = 0; i < isl_ast_node_list_n_ast_node(List); ++i)
853 createUserVector(isl_ast_node_list_get_ast_node(List, i), IVS,
Tobias Grosser1bb59b02012-12-29 23:47:38 +0000854 isl_id_copy(IteratorID), isl_union_map_copy(Schedule));
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000855
856 isl_ast_node_free(Body);
857 isl_ast_node_list_free(List);
858 break;
859 }
860 default:
861 isl_ast_node_dump(Body);
862 llvm_unreachable("Unhandled isl_ast_node in vectorizer");
863 }
864
865 IDToValue.erase(IteratorID);
866 isl_id_free(IteratorID);
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000867 isl_union_map_free(Schedule);
868
869 isl_ast_node_free(For);
870 isl_ast_expr_free(Iterator);
871}
872
873void IslNodeBuilder::createForSequential(__isl_take isl_ast_node *For) {
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000874 isl_ast_node *Body;
875 isl_ast_expr *Init, *Inc, *Iterator, *UB;
876 isl_id *IteratorID;
877 Value *ValueLB, *ValueUB, *ValueInc;
878 Type *MaxType;
Tobias Grosser5db6ffd2013-05-16 06:40:06 +0000879 BasicBlock *ExitBlock;
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000880 Value *IV;
Tobias Grosserc967d8e2012-10-16 07:29:13 +0000881 CmpInst::Predicate Predicate;
Tobias Grosser37c9b8e2014-03-04 14:59:00 +0000882 bool Parallel;
883
Johannes Doerfert6e819052014-07-17 16:11:28 +0000884 Parallel = IslAstInfo::isInnermostParallel(For);
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000885
886 Body = isl_ast_node_for_get_body(For);
887
888 // isl_ast_node_for_is_degenerate(For)
889 //
890 // TODO: For degenerated loops we could generate a plain assignment.
891 // However, for now we just reuse the logic for normal loops, which will
892 // create a loop with a single iteration.
893
894 Init = isl_ast_node_for_get_init(For);
895 Inc = isl_ast_node_for_get_inc(For);
896 Iterator = isl_ast_node_for_get_iterator(For);
897 IteratorID = isl_ast_expr_get_id(Iterator);
Tobias Grosserc967d8e2012-10-16 07:29:13 +0000898 UB = getUpperBound(For, Predicate);
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000899
900 ValueLB = ExprBuilder.create(Init);
901 ValueUB = ExprBuilder.create(UB);
902 ValueInc = ExprBuilder.create(Inc);
903
904 MaxType = ExprBuilder.getType(Iterator);
905 MaxType = ExprBuilder.getWidestType(MaxType, ValueLB->getType());
906 MaxType = ExprBuilder.getWidestType(MaxType, ValueUB->getType());
907 MaxType = ExprBuilder.getWidestType(MaxType, ValueInc->getType());
908
909 if (MaxType != ValueLB->getType())
910 ValueLB = Builder.CreateSExt(ValueLB, MaxType);
911 if (MaxType != ValueUB->getType())
912 ValueUB = Builder.CreateSExt(ValueUB, MaxType);
913 if (MaxType != ValueInc->getType())
914 ValueInc = Builder.CreateSExt(ValueInc, MaxType);
915
Tobias Grosser37c9b8e2014-03-04 14:59:00 +0000916 IV = createLoop(ValueLB, ValueUB, ValueInc, Builder, P, ExitBlock, Predicate,
917 &Annotator, Parallel);
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000918 IDToValue[IteratorID] = IV;
919
920 create(Body);
921
Tobias Grosser37c9b8e2014-03-04 14:59:00 +0000922 Annotator.End();
923
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000924 IDToValue.erase(IteratorID);
925
Tobias Grosser5db6ffd2013-05-16 06:40:06 +0000926 Builder.SetInsertPoint(ExitBlock->begin());
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000927
928 isl_ast_node_free(For);
929 isl_ast_expr_free(Iterator);
930 isl_id_free(IteratorID);
931}
932
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000933void IslNodeBuilder::createFor(__isl_take isl_ast_node *For) {
934 bool Vector = PollyVectorizerChoice != VECTORIZER_NONE;
935
Johannes Doerfert6e819052014-07-17 16:11:28 +0000936 if (Vector && IslAstInfo::isInnermostParallel(For)) {
Sebastian Pop04c4ce32012-12-18 07:46:13 +0000937 int VectorWidth = getNumberOfIterations(For);
938 if (1 < VectorWidth && VectorWidth <= 16) {
939 createForVector(For, VectorWidth);
940 return;
941 }
942 }
943 createForSequential(For);
944}
945
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000946void IslNodeBuilder::createIf(__isl_take isl_ast_node *If) {
947 isl_ast_expr *Cond = isl_ast_node_if_get_cond(If);
948
949 Function *F = Builder.GetInsertBlock()->getParent();
950 LLVMContext &Context = F->getContext();
951
Tobias Grosserc14582f2013-02-05 18:01:29 +0000952 BasicBlock *CondBB =
953 SplitBlock(Builder.GetInsertBlock(), Builder.GetInsertPoint(), P);
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000954 CondBB->setName("polly.cond");
955 BasicBlock *MergeBB = SplitBlock(CondBB, CondBB->begin(), P);
956 MergeBB->setName("polly.merge");
957 BasicBlock *ThenBB = BasicBlock::Create(Context, "polly.then", F);
958 BasicBlock *ElseBB = BasicBlock::Create(Context, "polly.else", F);
959
Tobias Grosser42aff302014-01-13 22:29:56 +0000960 DominatorTree &DT = P->getAnalysis<DominatorTreeWrapperPass>().getDomTree();
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000961 DT.addNewBlock(ThenBB, CondBB);
962 DT.addNewBlock(ElseBB, CondBB);
963 DT.changeImmediateDominator(MergeBB, CondBB);
964
Tobias Grosser3081b0f2013-05-16 06:40:24 +0000965 LoopInfo &LI = P->getAnalysis<LoopInfo>();
966 Loop *L = LI.getLoopFor(CondBB);
967 if (L) {
968 L->addBasicBlockToLoop(ThenBB, LI.getBase());
969 L->addBasicBlockToLoop(ElseBB, LI.getBase());
970 }
971
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +0000972 CondBB->getTerminator()->eraseFromParent();
973
974 Builder.SetInsertPoint(CondBB);
975 Value *Predicate = ExprBuilder.create(Cond);
976 Builder.CreateCondBr(Predicate, ThenBB, ElseBB);
977 Builder.SetInsertPoint(ThenBB);
978 Builder.CreateBr(MergeBB);
979 Builder.SetInsertPoint(ElseBB);
980 Builder.CreateBr(MergeBB);
981 Builder.SetInsertPoint(ThenBB->begin());
982
983 create(isl_ast_node_if_get_then(If));
984
985 Builder.SetInsertPoint(ElseBB->begin());
986
987 if (isl_ast_node_if_has_else(If))
988 create(isl_ast_node_if_get_else(If));
989
990 Builder.SetInsertPoint(MergeBB->begin());
991
992 isl_ast_node_free(If);
993}
994
Tobias Grosserce67a042014-07-02 16:26:47 +0000995void IslNodeBuilder::createSubstitutions(isl_ast_expr *Expr, ScopStmt *Stmt,
996 ValueMapT &VMap, LoopToScevMapT &LTS) {
997 assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
998 "Expression of type 'op' expected");
999 assert(isl_ast_expr_get_op_type(Expr) == isl_ast_op_call &&
1000 "Opertation of type 'call' expected");
1001 for (int i = 0; i < isl_ast_expr_get_op_n_arg(Expr) - 1; ++i) {
1002 isl_ast_expr *SubExpr;
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001003 Value *V;
1004
Tobias Grosserce67a042014-07-02 16:26:47 +00001005 SubExpr = isl_ast_expr_get_op_arg(Expr, i + 1);
1006 V = ExprBuilder.create(SubExpr);
Sebastian Pope039bb12013-03-18 19:09:49 +00001007 ScalarEvolution *SE = Stmt->getParent()->getSE();
1008 LTS[Stmt->getLoopForDimension(i)] = SE->getUnknown(V);
1009
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001010 // CreateIntCast can introduce trunc expressions. This is correct, as the
1011 // result will always fit into the type of the original induction variable
1012 // (because we calculate a value of the original induction variable).
Sebastian Pope039bb12013-03-18 19:09:49 +00001013 const Value *OldIV = Stmt->getInductionVariableForDimension(i);
1014 if (OldIV) {
1015 V = Builder.CreateIntCast(V, OldIV->getType(), true);
1016 VMap[OldIV] = V;
1017 }
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001018 }
1019
Tobias Grosserce67a042014-07-02 16:26:47 +00001020 isl_ast_expr_free(Expr);
Sebastian Pop04c4ce32012-12-18 07:46:13 +00001021}
1022
Tobias Grosserc14582f2013-02-05 18:01:29 +00001023void IslNodeBuilder::createSubstitutionsVector(
Tobias Grosserce67a042014-07-02 16:26:47 +00001024 __isl_take isl_ast_expr *Expr, ScopStmt *Stmt, VectorValueMapT &VMap,
1025 std::vector<LoopToScevMapT> &VLTS, std::vector<Value *> &IVS,
1026 __isl_take isl_id *IteratorID) {
Sebastian Pop04c4ce32012-12-18 07:46:13 +00001027 int i = 0;
1028
1029 Value *OldValue = IDToValue[IteratorID];
Tobias Grosser91f5b262014-06-04 08:06:40 +00001030 for (Value *IV : IVS) {
1031 IDToValue[IteratorID] = IV;
Tobias Grosserce67a042014-07-02 16:26:47 +00001032 createSubstitutions(isl_ast_expr_copy(Expr), Stmt, VMap[i], VLTS[i]);
Sebastian Pop04c4ce32012-12-18 07:46:13 +00001033 i++;
1034 }
1035
1036 IDToValue[IteratorID] = OldValue;
1037 isl_id_free(IteratorID);
Tobias Grosserce67a042014-07-02 16:26:47 +00001038 isl_ast_expr_free(Expr);
Sebastian Pop04c4ce32012-12-18 07:46:13 +00001039}
1040
1041void IslNodeBuilder::createUser(__isl_take isl_ast_node *User) {
1042 ValueMapT VMap;
Sebastian Pop9d10fff2013-02-15 20:55:59 +00001043 LoopToScevMapT LTS;
Tobias Grosserce67a042014-07-02 16:26:47 +00001044 isl_id *Id;
Sebastian Pop04c4ce32012-12-18 07:46:13 +00001045 ScopStmt *Stmt;
1046
Tobias Grosserce67a042014-07-02 16:26:47 +00001047 isl_ast_expr *Expr = isl_ast_node_user_get_expr(User);
1048 isl_ast_expr *StmtExpr = isl_ast_expr_get_op_arg(Expr, 0);
1049 Id = isl_ast_expr_get_id(StmtExpr);
1050 isl_ast_expr_free(StmtExpr);
Sebastian Pop04c4ce32012-12-18 07:46:13 +00001051
Tobias Grosserc14582f2013-02-05 18:01:29 +00001052 Stmt = (ScopStmt *)isl_id_get_user(Id);
Tobias Grosserce67a042014-07-02 16:26:47 +00001053 createSubstitutions(Expr, Stmt, VMap, LTS);
Sebastian Pop9d10fff2013-02-15 20:55:59 +00001054 BlockGenerator::generate(Builder, *Stmt, VMap, LTS, P);
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001055
1056 isl_ast_node_free(User);
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001057 isl_id_free(Id);
1058}
1059
1060void IslNodeBuilder::createBlock(__isl_take isl_ast_node *Block) {
1061 isl_ast_node_list *List = isl_ast_node_block_get_children(Block);
1062
1063 for (int i = 0; i < isl_ast_node_list_n_ast_node(List); ++i)
1064 create(isl_ast_node_list_get_ast_node(List, i));
1065
1066 isl_ast_node_free(Block);
1067 isl_ast_node_list_free(List);
1068}
1069
1070void IslNodeBuilder::create(__isl_take isl_ast_node *Node) {
1071 switch (isl_ast_node_get_type(Node)) {
1072 case isl_ast_node_error:
1073 llvm_unreachable("code generation error");
1074 case isl_ast_node_for:
1075 createFor(Node);
1076 return;
1077 case isl_ast_node_if:
1078 createIf(Node);
1079 return;
1080 case isl_ast_node_user:
1081 createUser(Node);
1082 return;
1083 case isl_ast_node_block:
1084 createBlock(Node);
1085 return;
1086 }
1087
1088 llvm_unreachable("Unknown isl_ast_node type");
1089}
1090
1091void IslNodeBuilder::addParameters(__isl_take isl_set *Context) {
1092 SCEVExpander Rewriter(P->getAnalysis<ScalarEvolution>(), "polly");
1093
1094 for (unsigned i = 0; i < isl_set_dim(Context, isl_dim_param); ++i) {
1095 isl_id *Id;
1096 const SCEV *Scev;
1097 IntegerType *T;
1098 Instruction *InsertLocation;
1099
1100 Id = isl_set_get_dim_id(Context, isl_dim_param, i);
Tobias Grosserc14582f2013-02-05 18:01:29 +00001101 Scev = (const SCEV *)isl_id_get_user(Id);
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001102 T = dyn_cast<IntegerType>(Scev->getType());
1103 InsertLocation = --(Builder.GetInsertBlock()->end());
1104 Value *V = Rewriter.expandCodeFor(Scev, T, InsertLocation);
1105 IDToValue[Id] = V;
1106
1107 isl_id_free(Id);
1108 }
1109
1110 isl_set_free(Context);
1111}
1112
1113namespace {
1114class IslCodeGeneration : public ScopPass {
Tobias Grosser1bb59b02012-12-29 23:47:38 +00001115public:
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001116 static char ID;
1117
1118 IslCodeGeneration() : ScopPass(ID) {}
1119
1120 bool runOnScop(Scop &S) {
1121 IslAstInfo &AstInfo = getAnalysis<IslAstInfo>();
Tobias Grosser0ee50f62013-04-10 06:55:31 +00001122
Tobias Grossere602a072013-05-07 07:30:56 +00001123 assert(!S.getRegion().isTopLevelRegion() &&
1124 "Top level regions are not supported");
Tobias Grosser0ee50f62013-04-10 06:55:31 +00001125
Tobias Grosser8edce4e2013-04-16 08:04:42 +00001126 simplifyRegion(&S, this);
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001127
1128 BasicBlock *StartBlock = executeScopConditionally(S, this);
1129 isl_ast_node *Ast = AstInfo.getAst();
Tobias Grosser37c9b8e2014-03-04 14:59:00 +00001130 LoopAnnotator Annotator;
1131 PollyIRBuilder Builder(StartBlock->getContext(), llvm::ConstantFolder(),
1132 polly::IRInserter(Annotator));
1133 Builder.SetInsertPoint(StartBlock->begin());
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001134
Tobias Grosser37c9b8e2014-03-04 14:59:00 +00001135 IslNodeBuilder NodeBuilder(Builder, Annotator, this);
Tobias Grosser54ee0ba2013-11-17 03:18:25 +00001136
Tobias Grosser5e6813d2014-07-02 17:47:48 +00001137 Builder.SetInsertPoint(StartBlock->getSinglePredecessor()->begin());
1138 NodeBuilder.addParameters(S.getContext());
Tobias Grosser54ee0ba2013-11-17 03:18:25 +00001139 // Build condition that evaluates at run-time if all assumptions taken
1140 // for the scop hold. If we detect some assumptions do not hold, the
1141 // original code is executed.
1142 Value *V = NodeBuilder.getExprBuilder().create(AstInfo.getRunCondition());
1143 Value *Zero = ConstantInt::get(V->getType(), 0);
1144 V = Builder.CreateICmp(CmpInst::ICMP_NE, Zero, V);
1145 BasicBlock *PrevBB = StartBlock->getUniquePredecessor();
1146 BranchInst *Branch = dyn_cast<BranchInst>(PrevBB->getTerminator());
1147 Branch->setCondition(V);
Tobias Grosser5e6813d2014-07-02 17:47:48 +00001148 Builder.SetInsertPoint(StartBlock->begin());
Tobias Grosser54ee0ba2013-11-17 03:18:25 +00001149
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001150 NodeBuilder.create(Ast);
1151 return true;
1152 }
1153
Tobias Grosserc14582f2013-02-05 18:01:29 +00001154 virtual void printScop(raw_ostream &OS) const {}
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001155
1156 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
Tobias Grosser42aff302014-01-13 22:29:56 +00001157 AU.addRequired<DominatorTreeWrapperPass>();
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001158 AU.addRequired<IslAstInfo>();
Matt Arsenault8ca36812014-07-19 18:40:17 +00001159 AU.addRequired<RegionInfoPass>();
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001160 AU.addRequired<ScalarEvolution>();
1161 AU.addRequired<ScopDetection>();
1162 AU.addRequired<ScopInfo>();
Tobias Grosserecfe21b2013-03-20 18:03:18 +00001163 AU.addRequired<LoopInfo>();
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001164
1165 AU.addPreserved<Dependences>();
1166
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001167 AU.addPreserved<LoopInfo>();
Tobias Grosser42aff302014-01-13 22:29:56 +00001168 AU.addPreserved<DominatorTreeWrapperPass>();
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001169 AU.addPreserved<IslAstInfo>();
1170 AU.addPreserved<ScopDetection>();
1171 AU.addPreserved<ScalarEvolution>();
1172
1173 // FIXME: We do not yet add regions for the newly generated code to the
1174 // region tree.
Matt Arsenault8ca36812014-07-19 18:40:17 +00001175 AU.addPreserved<RegionInfoPass>();
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001176 AU.addPreserved<TempScopInfo>();
1177 AU.addPreserved<ScopInfo>();
1178 AU.addPreservedID(IndependentBlocksID);
1179 }
1180};
1181}
1182
1183char IslCodeGeneration::ID = 1;
1184
Tobias Grosser7242ad92013-02-22 08:07:06 +00001185Pass *polly::createIslCodeGenerationPass() { return new IslCodeGeneration(); }
Tobias Grosser8a5bc6e2012-10-02 19:50:43 +00001186
Tobias Grosser7242ad92013-02-22 08:07:06 +00001187INITIALIZE_PASS_BEGIN(IslCodeGeneration, "polly-codegen-isl",
1188 "Polly - Create LLVM-IR from SCoPs", false, false);
1189INITIALIZE_PASS_DEPENDENCY(Dependences);
Tobias Grosser42aff302014-01-13 22:29:56 +00001190INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass);
Tobias Grosser7242ad92013-02-22 08:07:06 +00001191INITIALIZE_PASS_DEPENDENCY(LoopInfo);
Matt Arsenault8ca36812014-07-19 18:40:17 +00001192INITIALIZE_PASS_DEPENDENCY(RegionInfoPass);
Tobias Grosser7242ad92013-02-22 08:07:06 +00001193INITIALIZE_PASS_DEPENDENCY(ScalarEvolution);
1194INITIALIZE_PASS_DEPENDENCY(ScopDetection);
1195INITIALIZE_PASS_END(IslCodeGeneration, "polly-codegen-isl",
1196 "Polly - Create LLVM-IR from SCoPs", false, false)