blob: 943360db5b23d7fbf491179f04853265ac8cfe93 [file] [log] [blame]
Tobias Grosser75805372011-04-29 06:27:02 +00001//===------ CodeGeneration.cpp - Code generate the Scops. -----------------===//
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 CodeGeneration pass takes a Scop created by ScopInfo and translates it
11// back to LLVM-IR using Cloog.
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. Cloog is used to generate an abstract syntax tree (clast) that
16// reflects the updated execution order. This clast is used to create new
17// LLVM-IR that is computational equivalent to the original control flow region,
18// but executes its code in the new execution order defined by the changed
19// scattering.
20//
21//===----------------------------------------------------------------------===//
22
23#define DEBUG_TYPE "polly-codegen"
24
Tobias Grosser75805372011-04-29 06:27:02 +000025#include "polly/Cloog.h"
Tobias Grosser67707b72011-10-23 20:59:40 +000026#include "polly/CodeGeneration.h"
Tobias Grosser75805372011-04-29 06:27:02 +000027#include "polly/Dependences.h"
Tobias Grosserbda1f8f2012-02-01 14:23:29 +000028#include "polly/LinkAllPasses.h"
Tobias Grosser75805372011-04-29 06:27:02 +000029#include "polly/ScopInfo.h"
30#include "polly/TempScopInfo.h"
Tobias Grosserbda1f8f2012-02-01 14:23:29 +000031#include "polly/Support/GICHelper.h"
32
33#include "llvm/Module.h"
34#include "llvm/ADT/SetVector.h"
35#include "llvm/Analysis/LoopInfo.h"
36#include "llvm/Analysis/ScalarEvolutionExpander.h"
Tobias Grosser75805372011-04-29 06:27:02 +000037#include "llvm/Support/CommandLine.h"
38#include "llvm/Support/Debug.h"
39#include "llvm/Support/IRBuilder.h"
Tobias Grosser75805372011-04-29 06:27:02 +000040#include "llvm/Target/TargetData.h"
Tobias Grosserbda1f8f2012-02-01 14:23:29 +000041#include "llvm/Transforms/Utils/BasicBlockUtils.h"
Tobias Grosser75805372011-04-29 06:27:02 +000042
43#define CLOOG_INT_GMP 1
44#include "cloog/cloog.h"
45#include "cloog/isl/cloog.h"
46
Raghesh Aloora71989c2011-12-28 02:48:26 +000047#include "isl/aff.h"
48
Tobias Grosser75805372011-04-29 06:27:02 +000049#include <vector>
50#include <utility>
51
52using namespace polly;
53using namespace llvm;
54
55struct isl_set;
56
57namespace polly {
58
Tobias Grosser67707b72011-10-23 20:59:40 +000059bool EnablePollyVector;
60
61static cl::opt<bool, true>
Tobias Grosser75805372011-04-29 06:27:02 +000062Vector("enable-polly-vector",
63 cl::desc("Enable polly vector code generation"), cl::Hidden,
Tobias Grosser67707b72011-10-23 20:59:40 +000064 cl::location(EnablePollyVector), cl::init(false));
Tobias Grosser75805372011-04-29 06:27:02 +000065
66static cl::opt<bool>
67OpenMP("enable-polly-openmp",
68 cl::desc("Generate OpenMP parallel code"), cl::Hidden,
69 cl::value_desc("OpenMP code generation enabled if true"),
70 cl::init(false));
71
72static cl::opt<bool>
73AtLeastOnce("enable-polly-atLeastOnce",
74 cl::desc("Give polly the hint, that every loop is executed at least"
75 "once"), cl::Hidden,
76 cl::value_desc("OpenMP code generation enabled if true"),
77 cl::init(false));
78
79static cl::opt<bool>
80Aligned("enable-polly-aligned",
81 cl::desc("Assumed aligned memory accesses."), cl::Hidden,
82 cl::value_desc("OpenMP code generation enabled if true"),
83 cl::init(false));
84
Tobias Grosser75805372011-04-29 06:27:02 +000085typedef DenseMap<const Value*, Value*> ValueMapT;
86typedef DenseMap<const char*, Value*> CharMapT;
87typedef std::vector<ValueMapT> VectorValueMapT;
Raghesh Aloora71989c2011-12-28 02:48:26 +000088typedef struct {
Raghesh Aloora71989c2011-12-28 02:48:26 +000089 Value *Result;
90 IRBuilder<> *Builder;
91}IslPwAffUserInfo;
Tobias Grosser75805372011-04-29 06:27:02 +000092
93// Create a new loop.
94//
95// @param Builder The builder used to create the loop. It also defines the
96// place where to create the loop.
97// @param UB The upper bound of the loop iv.
98// @param Stride The number by which the loop iv is incremented after every
99// iteration.
Tobias Grosser0ac92142012-02-14 14:02:27 +0000100static Value *createLoop(IRBuilder<> *Builder, Value *LB, Value *UB,
101 APInt Stride, DominatorTree *DT, Pass *P,
102 BasicBlock **AfterBlock) {
Tobias Grosser75805372011-04-29 06:27:02 +0000103 Function *F = Builder->GetInsertBlock()->getParent();
104 LLVMContext &Context = F->getContext();
105
106 BasicBlock *PreheaderBB = Builder->GetInsertBlock();
107 BasicBlock *HeaderBB = BasicBlock::Create(Context, "polly.loop_header", F);
108 BasicBlock *BodyBB = BasicBlock::Create(Context, "polly.loop_body", F);
Tobias Grosser0ac92142012-02-14 14:02:27 +0000109 BasicBlock *AfterBB = SplitBlock(PreheaderBB, Builder->GetInsertPoint()++, P);
110 AfterBB->setName("polly.loop_after");
Tobias Grosser75805372011-04-29 06:27:02 +0000111
Tobias Grosser0ac92142012-02-14 14:02:27 +0000112 PreheaderBB->getTerminator()->setSuccessor(0, HeaderBB);
Tobias Grosser75805372011-04-29 06:27:02 +0000113 DT->addNewBlock(HeaderBB, PreheaderBB);
114
Tobias Grosser75805372011-04-29 06:27:02 +0000115 Builder->SetInsertPoint(HeaderBB);
116
117 // Use the type of upper and lower bound.
118 assert(LB->getType() == UB->getType()
119 && "Different types for upper and lower bound.");
120
Tobias Grosser55927aa2011-07-18 09:53:32 +0000121 IntegerType *LoopIVType = dyn_cast<IntegerType>(UB->getType());
Tobias Grosser75805372011-04-29 06:27:02 +0000122 assert(LoopIVType && "UB is not integer?");
123
124 // IV
Tobias Grosser0ac92142012-02-14 14:02:27 +0000125 PHINode *IV = Builder->CreatePHI(LoopIVType, 2, "polly.loopiv");
Tobias Grosser75805372011-04-29 06:27:02 +0000126 IV->addIncoming(LB, PreheaderBB);
127
128 // IV increment.
129 Value *StrideValue = ConstantInt::get(LoopIVType,
130 Stride.zext(LoopIVType->getBitWidth()));
Tobias Grosser0ac92142012-02-14 14:02:27 +0000131 Value *IncrementedIV = Builder->CreateAdd(IV, StrideValue,
132 "polly.next_loopiv");
Tobias Grosser75805372011-04-29 06:27:02 +0000133
134 // Exit condition.
Tobias Grosser0ac92142012-02-14 14:02:27 +0000135 Value *CMP;
Tobias Grosser75805372011-04-29 06:27:02 +0000136 if (AtLeastOnce) { // At least on iteration.
137 UB = Builder->CreateAdd(UB, Builder->getInt64(1));
Tobias Grosser0ac92142012-02-14 14:02:27 +0000138 CMP = Builder->CreateICmpNE(IV, UB);
Tobias Grosser75805372011-04-29 06:27:02 +0000139 } else { // Maybe not executed at all.
Tobias Grosser0ac92142012-02-14 14:02:27 +0000140 CMP = Builder->CreateICmpSLE(IV, UB);
Tobias Grosser75805372011-04-29 06:27:02 +0000141 }
Tobias Grosser0ac92142012-02-14 14:02:27 +0000142
143 Builder->CreateCondBr(CMP, BodyBB, AfterBB);
Tobias Grosser75805372011-04-29 06:27:02 +0000144 DT->addNewBlock(BodyBB, HeaderBB);
Tobias Grosser75805372011-04-29 06:27:02 +0000145
146 Builder->SetInsertPoint(BodyBB);
Tobias Grosser0ac92142012-02-14 14:02:27 +0000147 Builder->CreateBr(HeaderBB);
148 IV->addIncoming(IncrementedIV, BodyBB);
149 DT->changeImmediateDominator(AfterBB, HeaderBB);
150
151 Builder->SetInsertPoint(BodyBB->begin());
152 *AfterBlock = AfterBB;
153
154 return IV;
Tobias Grosser75805372011-04-29 06:27:02 +0000155}
156
Tobias Grosser642c4112012-03-02 11:27:25 +0000157class IslGenerator;
158
159class IslGenerator {
160public:
161 IslGenerator(IRBuilder<> &Builder) : Builder(Builder) {}
162 Value *generateIslInt(__isl_take isl_int Int);
163 Value *generateIslAff(__isl_take isl_aff *Aff);
164 Value *generateIslPwAff(__isl_take isl_pw_aff *PwAff);
165
166private:
167 typedef struct {
168 Value *Result;
169 class IslGenerator *Generator;
170 } IslGenInfo;
171
172 IRBuilder<> &Builder;
173 static int mergeIslAffValues(__isl_take isl_set *Set,
174 __isl_take isl_aff *Aff, void *User);
175};
176
177Value *IslGenerator::generateIslInt(isl_int Int) {
178 mpz_t IntMPZ;
179 mpz_init(IntMPZ);
180 isl_int_get_gmp(Int, IntMPZ);
181 Value *IntValue = Builder.getInt(APInt_from_MPZ(IntMPZ));
182 mpz_clear(IntMPZ);
183 return IntValue;
184}
185
186Value *IslGenerator::generateIslAff(__isl_take isl_aff *Aff) {
187 assert(isl_aff_is_cst(Aff) && "Only constant access functions supported");
188 Value *ConstValue;
189 isl_int ConstIsl;
190
191 isl_int_init(ConstIsl);
192 isl_aff_get_constant(Aff, &ConstIsl);
193 ConstValue = generateIslInt(ConstIsl);
194
195 isl_int_clear(ConstIsl);
196 isl_aff_free(Aff);
197
198 return ConstValue;
199}
200
201int IslGenerator::mergeIslAffValues(__isl_take isl_set *Set,
202 __isl_take isl_aff *Aff, void *User) {
203 IslGenInfo *GenInfo = (IslGenInfo *)User;
204
205 assert((GenInfo->Result == NULL) && "Result is already set."
206 "Currently only single isl_aff is supported");
207 assert(isl_set_plain_is_universe(Set)
208 && "Code generation failed because the set is not universe");
209
210 GenInfo->Result = GenInfo->Generator->generateIslAff(Aff);
211
212 isl_set_free(Set);
213 return 0;
214}
215
216Value *IslGenerator::generateIslPwAff(__isl_take isl_pw_aff *PwAff) {
217 IslGenInfo User;
218 User.Result = NULL;
219 User.Generator = this;
220 isl_pw_aff_foreach_piece(PwAff, mergeIslAffValues, &User);
221 assert(User.Result && "Code generation for isl_pw_aff failed");
222
223 isl_pw_aff_free(PwAff);
224 return User.Result;
225}
226
Tobias Grosser75805372011-04-29 06:27:02 +0000227class BlockGenerator {
Tobias Grosserc941ede2012-03-02 11:26:49 +0000228public:
Tobias Grosserc941ede2012-03-02 11:26:49 +0000229 static void generate(IRBuilder<> &B, ValueMapT &ValueMap,
Tobias Grosser80998e72012-03-02 11:27:28 +0000230 ScopStmt &Stmt, __isl_keep isl_set *Domain, Pass *P) {
231 BlockGenerator Generator(B, ValueMap, Stmt, Domain, P);
Tobias Grosser8412cda2012-03-02 11:26:55 +0000232 Generator.copyBB();
Tobias Grosserc941ede2012-03-02 11:26:49 +0000233 }
234
Tobias Grosser80998e72012-03-02 11:27:28 +0000235protected:
Tobias Grosser75805372011-04-29 06:27:02 +0000236 IRBuilder<> &Builder;
237 ValueMapT &VMap;
Tobias Grosser75805372011-04-29 06:27:02 +0000238 Scop &S;
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000239 ScopStmt &Statement;
240 isl_set *ScatteringDomain;
Tobias Grosser8412cda2012-03-02 11:26:55 +0000241 Pass *P;
Tobias Grosser75805372011-04-29 06:27:02 +0000242
Tobias Grosser80998e72012-03-02 11:27:28 +0000243 BlockGenerator(IRBuilder<> &B, ValueMapT &vmap, ScopStmt &Stmt,
244 __isl_keep isl_set *Domain, Pass *p);
Tobias Grosser75805372011-04-29 06:27:02 +0000245
Tobias Grosser80998e72012-03-02 11:27:28 +0000246 Value *getOperand(const Value *oldOperand, ValueMapT &BBMap);
Tobias Grosser75805372011-04-29 06:27:02 +0000247
Tobias Grosser80998e72012-03-02 11:27:28 +0000248 void copyInstScalar(const Instruction *Inst, ValueMapT &BBMap);
Tobias Grosser75805372011-04-29 06:27:02 +0000249
Raghesh Aloor129e8672011-08-15 02:33:39 +0000250 /// @brief Get the memory access offset to be added to the base address
Tobias Grosser80998e72012-03-02 11:27:28 +0000251 std::vector<Value*> getMemoryAccessIndex(__isl_keep isl_map *AccessRelation,
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000252 Value *BaseAddress);
Raghesh Aloor129e8672011-08-15 02:33:39 +0000253
Raghesh Aloor62b13122011-08-03 17:02:50 +0000254 /// @brief Get the new operand address according to the changed access in
255 /// JSCOP file.
Raghesh Aloor46eceba2011-12-09 14:27:17 +0000256 Value *getNewAccessOperand(__isl_keep isl_map *NewAccessRelation,
257 Value *BaseAddress, const Value *OldOperand,
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000258 ValueMapT &BBMap);
Raghesh Aloor62b13122011-08-03 17:02:50 +0000259
260 /// @brief Generate the operand address
261 Value *generateLocationAccessed(const Instruction *Inst,
Tobias Grosser80998e72012-03-02 11:27:28 +0000262 const Value *Pointer, ValueMapT &BBMap);
Raghesh Aloor129e8672011-08-15 02:33:39 +0000263
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000264 Value *generateScalarLoad(const LoadInst *load, ValueMapT &BBMap);
Tobias Grosser75805372011-04-29 06:27:02 +0000265
Tobias Grosser80998e72012-03-02 11:27:28 +0000266 void copyInstruction(const Instruction *Inst, ValueMapT &ScalarMap);
Tobias Grosser75805372011-04-29 06:27:02 +0000267
Tobias Grosser8412cda2012-03-02 11:26:55 +0000268 void copyBB();
Tobias Grosser75805372011-04-29 06:27:02 +0000269};
270
Tobias Grosser80998e72012-03-02 11:27:28 +0000271BlockGenerator::BlockGenerator(IRBuilder<> &B, ValueMapT &vmap, ScopStmt &Stmt,
272 __isl_keep isl_set *domain, Pass *P) :
273 Builder(B), VMap(vmap), S(*Stmt.getParent()), Statement(Stmt),
274 ScatteringDomain(domain), P(P) {}
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000275
Tobias Grosser80998e72012-03-02 11:27:28 +0000276Value *BlockGenerator::getOperand(const Value *OldOperand, ValueMapT &BBMap) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000277 const Instruction *OpInst = dyn_cast<Instruction>(OldOperand);
278
279 if (!OpInst)
280 return const_cast<Value*>(OldOperand);
281
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000282 // IVS and Parameters.
283 if (VMap.count(OldOperand)) {
284 Value *NewOperand = VMap[OldOperand];
285
286 // Insert a cast if types are different
287 if (OldOperand->getType()->getScalarSizeInBits()
288 < NewOperand->getType()->getScalarSizeInBits())
289 NewOperand = Builder.CreateTruncOrBitCast(NewOperand,
290 OldOperand->getType());
291
292 return NewOperand;
293 }
294
295 // Instructions calculated in the current BB.
296 if (BBMap.count(OldOperand)) {
297 return BBMap[OldOperand];
298 }
299
300 // Ignore instructions that are referencing ops in the old BB. These
301 // instructions are unused. They where replace by new ones during
302 // createIndependentBlocks().
Tobias Grosser44d16952012-03-02 11:27:21 +0000303 if (S.getRegion().contains(OpInst->getParent()))
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000304 return NULL;
305
306 return const_cast<Value*>(OldOperand);
307}
308
Tobias Grosser80998e72012-03-02 11:27:28 +0000309void BlockGenerator::copyInstScalar(const Instruction *Inst, ValueMapT &BBMap) {
310 Instruction *NewInst = Inst->clone();
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000311
Tobias Grosser80998e72012-03-02 11:27:28 +0000312 // Replace old operands with the new ones.
313 for (Instruction::const_op_iterator OI = Inst->op_begin(),
314 OE = Inst->op_end(); OI != OE; ++OI) {
315 Value *OldOperand = *OI;
316 Value *NewOperand = getOperand(OldOperand, BBMap);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000317
Tobias Grosser80998e72012-03-02 11:27:28 +0000318 if (!NewOperand) {
319 assert(!isa<StoreInst>(NewInst)
320 && "Store instructions are always needed!");
321 delete NewInst;
322 return;
323 }
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000324
Tobias Grosser80998e72012-03-02 11:27:28 +0000325 NewInst->replaceUsesOfWith(OldOperand, NewOperand);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000326 }
327
Tobias Grosser80998e72012-03-02 11:27:28 +0000328 Builder.Insert(NewInst);
329 BBMap[Inst] = NewInst;
330
331 if (!NewInst->getType()->isVoidTy())
332 NewInst->setName("p_" + Inst->getName());
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000333}
334
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000335std::vector <Value*> BlockGenerator::getMemoryAccessIndex(
336 __isl_keep isl_map *AccessRelation, Value *BaseAddress) {
337 assert((isl_map_dim(AccessRelation, isl_dim_out) == 1)
338 && "Only single dimensional access functions supported");
339
340 isl_pw_aff *PwAff = isl_map_dim_max(isl_map_copy(AccessRelation), 0);
Tobias Grosser642c4112012-03-02 11:27:25 +0000341 IslGenerator IslGen(Builder);
342 Value *OffsetValue = IslGen.generateIslPwAff(PwAff);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000343
344 PointerType *BaseAddressType = dyn_cast<PointerType>(
345 BaseAddress->getType());
346 Type *ArrayTy = BaseAddressType->getElementType();
347 Type *ArrayElementType = dyn_cast<ArrayType>(ArrayTy)->getElementType();
348 OffsetValue = Builder.CreateSExtOrBitCast(OffsetValue, ArrayElementType);
349
350 std::vector<Value*> IndexArray;
351 Value *NullValue = Constant::getNullValue(ArrayElementType);
352 IndexArray.push_back(NullValue);
353 IndexArray.push_back(OffsetValue);
354 return IndexArray;
355}
356
357Value *BlockGenerator::getNewAccessOperand(
358 __isl_keep isl_map *NewAccessRelation, Value *BaseAddress, const Value
359 *OldOperand, ValueMapT &BBMap) {
360 std::vector<Value*> IndexArray = getMemoryAccessIndex(NewAccessRelation,
361 BaseAddress);
362 Value *NewOperand = Builder.CreateGEP(BaseAddress, IndexArray,
363 "p_newarrayidx_");
364 return NewOperand;
365}
366
367Value *BlockGenerator::generateLocationAccessed(const Instruction *Inst,
368 const Value *Pointer,
369 ValueMapT &BBMap ) {
370 MemoryAccess &Access = Statement.getAccessFor(Inst);
371 isl_map *CurrentAccessRelation = Access.getAccessRelation();
372 isl_map *NewAccessRelation = Access.getNewAccessRelation();
373
374 assert(isl_map_has_equal_space(CurrentAccessRelation, NewAccessRelation)
375 && "Current and new access function use different spaces");
376
377 Value *NewPointer;
378
379 if (!NewAccessRelation) {
380 NewPointer = getOperand(Pointer, BBMap);
381 } else {
382 Value *BaseAddress = const_cast<Value*>(Access.getBaseAddr());
383 NewPointer = getNewAccessOperand(NewAccessRelation, BaseAddress, Pointer,
384 BBMap);
385 }
386
387 isl_map_free(CurrentAccessRelation);
388 isl_map_free(NewAccessRelation);
389 return NewPointer;
390}
391
392Value *BlockGenerator::generateScalarLoad(const LoadInst *Load,
393 ValueMapT &BBMap) {
394 const Value *Pointer = Load->getPointerOperand();
395 const Instruction *Inst = dyn_cast<Instruction>(Load);
396 Value *NewPointer = generateLocationAccessed(Inst, Pointer, BBMap);
397 Value *ScalarLoad = Builder.CreateLoad(NewPointer,
398 Load->getName() + "_p_scalar_");
399 return ScalarLoad;
400}
401
Tobias Grosser80998e72012-03-02 11:27:28 +0000402void BlockGenerator::copyInstruction(const Instruction *Inst,
403 ValueMapT &ScalarMap) {
404 // Terminator instructions control the control flow. They are explicitly
405 // expressed in the clast and do not need to be copied.
406 if (Inst->isTerminator())
407 return;
408
409 if (const LoadInst *Load = dyn_cast<LoadInst>(Inst)) {
410 ScalarMap[Load] = generateScalarLoad(Load, ScalarMap);
411 return;
412 }
413
414 copyInstScalar(Inst, ScalarMap);
415}
416
417
418void BlockGenerator::copyBB() {
419 BasicBlock *BB = Statement.getBasicBlock();
420 BasicBlock *CopyBB = SplitBlock(Builder.GetInsertBlock(),
421 Builder.GetInsertPoint(), P);
422 CopyBB->setName("polly.stmt." + BB->getName());
423 Builder.SetInsertPoint(CopyBB->begin());
424
425 ValueMapT ScalarBlockMap;
426
427 for (BasicBlock::const_iterator II = BB->begin(), IE = BB->end(); II != IE;
428 ++II)
429 copyInstruction(II, ScalarBlockMap);
430}
431
432class VectorBlockGenerator : BlockGenerator {
433public:
434 static void generate(IRBuilder<> &B, ValueMapT &ValueMap,
435 VectorValueMapT &VectorMaps, ScopStmt &Stmt,
436 __isl_keep isl_set *Domain, Pass *P) {
437 VectorBlockGenerator Generator(B, ValueMap, VectorMaps, Stmt, Domain, P);
438 Generator.copyBB();
439 }
440
441private:
442 VectorValueMapT &ValueMaps;
443
444 VectorBlockGenerator(IRBuilder<> &B, ValueMapT &vmap, VectorValueMapT &vmaps,
445 ScopStmt &Stmt, __isl_keep isl_set *domain, Pass *p);
446
447 int getVectorWidth();
448
449 Value *makeVectorOperand(Value *Operand);
450
451 Value *getOperand(const Value *oldOperand, ValueMapT &BBMap,
452 ValueMapT *VectorMap = 0);
453
454 Type *getVectorPtrTy(const Value *V, int Width);
455
456 /// @brief Load a vector from a set of adjacent scalars
457 ///
458 /// In case a set of scalars is known to be next to each other in memory,
459 /// create a vector load that loads those scalars
460 ///
461 /// %vector_ptr= bitcast double* %p to <4 x double>*
462 /// %vec_full = load <4 x double>* %vector_ptr
463 ///
464 Value *generateStrideOneLoad(const LoadInst *Load, ValueMapT &BBMap);
465
466 /// @brief Load a vector initialized from a single scalar in memory
467 ///
468 /// In case all elements of a vector are initialized to the same
469 /// scalar value, this value is loaded and shuffeled into all elements
470 /// of the vector.
471 ///
472 /// %splat_one = load <1 x double>* %p
473 /// %splat = shufflevector <1 x double> %splat_one, <1 x
474 /// double> %splat_one, <4 x i32> zeroinitializer
475 ///
476 Value *generateStrideZeroLoad(const LoadInst *Load, ValueMapT &BBMap);
477
478 /// @Load a vector from scalars distributed in memory
479 ///
480 /// In case some scalars a distributed randomly in memory. Create a vector
481 /// by loading each scalar and by inserting one after the other into the
482 /// vector.
483 ///
484 /// %scalar_1= load double* %p_1
485 /// %vec_1 = insertelement <2 x double> undef, double %scalar_1, i32 0
486 /// %scalar 2 = load double* %p_2
487 /// %vec_2 = insertelement <2 x double> %vec_1, double %scalar_1, i32 1
488 ///
489 Value *generateUnknownStrideLoad(const LoadInst *Load,
490 VectorValueMapT &ScalarMaps);
491
492
493 void generateLoad(const LoadInst *Load, ValueMapT &VectorMap,
494 VectorValueMapT &ScalarMaps);
495
496 void copyUnaryInst(const UnaryInstruction *Inst, ValueMapT &BBMap,
497 ValueMapT &VectorMap);
498
499 void copyBinaryInst(const BinaryOperator *Inst, ValueMapT &BBMap,
500 ValueMapT &VectorMap);
501
502 void copyStore(const StoreInst *Store, ValueMapT &BBMap,
503 ValueMapT &VectorMap, VectorValueMapT &ScalarMaps);
504
505 bool hasVectorOperands(const Instruction *Inst, ValueMapT &VectorMap);
506
507 void copyInstruction(const Instruction *Inst, ValueMapT &VectorMap,
508 VectorValueMapT &ScalarMaps);
509
510 // Insert a copy of a basic block in the newly generated code.
511 void copyBB();
512};
513
514VectorBlockGenerator::VectorBlockGenerator(IRBuilder<> &B, ValueMapT &vmap,
515 VectorValueMapT &vmaps, ScopStmt &Stmt,
516 __isl_keep isl_set *domain, Pass *P)
517 : BlockGenerator(B, vmap, Stmt, domain, P), ValueMaps(vmaps) {
518 assert(ValueMaps.size() > 1 && "Only one vector lane found");
519 }
520
521Value *VectorBlockGenerator::makeVectorOperand(Value *Operand) {
522 int VectorWidth = getVectorWidth();
523 if (Operand->getType()->isVectorTy())
524 return Operand;
525
Tobias Grosserf6beec62012-03-02 15:20:21 +0000526 Value *Vector = UndefValue::get(VectorType::get(Operand->getType(), 1));
Tobias Grosser80998e72012-03-02 11:27:28 +0000527 Vector = Builder.CreateInsertElement(Vector, Operand, Builder.getInt32(0));
Tobias Grosserf6beec62012-03-02 15:20:21 +0000528 Constant *SplatVector = ConstantVector::getSplat(VectorWidth,
529 Builder.getInt32(0));
Tobias Grosser80998e72012-03-02 11:27:28 +0000530 return Builder.CreateShuffleVector(Vector, Vector, SplatVector);
531}
532
533Value *VectorBlockGenerator::getOperand(const Value *OldOperand,
534 ValueMapT &BBMap,
535 ValueMapT *VectorMap) {
536 const Instruction *OpInst = dyn_cast<Instruction>(OldOperand);
537
538 if (!OpInst)
539 return const_cast<Value*>(OldOperand);
540
541 if (VectorMap && VectorMap->count(OldOperand))
542 return (*VectorMap)[OldOperand];
543
544 return BlockGenerator::getOperand(OldOperand, BBMap);
545}
546
547Type *VectorBlockGenerator::getVectorPtrTy(const Value *Val, int Width) {
548 PointerType *PointerTy = dyn_cast<PointerType>(Val->getType());
549 assert(PointerTy && "PointerType expected");
550
551 Type *ScalarType = PointerTy->getElementType();
552 VectorType *VectorType = VectorType::get(ScalarType, Width);
553
554 return PointerType::getUnqual(VectorType);
555}
556
557Value *VectorBlockGenerator::generateStrideOneLoad(const LoadInst *Load,
558 ValueMapT &BBMap) {
559 const Value *Pointer = Load->getPointerOperand();
560 Type *VectorPtrType = getVectorPtrTy(Pointer, getVectorWidth());
561 Value *NewPointer = getOperand(Pointer, BBMap);
562 Value *VectorPtr = Builder.CreateBitCast(NewPointer, VectorPtrType,
563 "vector_ptr");
564 LoadInst *VecLoad = Builder.CreateLoad(VectorPtr,
565 Load->getName() + "_p_vec_full");
566 if (!Aligned)
567 VecLoad->setAlignment(8);
568
569 return VecLoad;
570}
571
572Value *VectorBlockGenerator::generateStrideZeroLoad(const LoadInst *Load,
573 ValueMapT &BBMap) {
574 const Value *Pointer = Load->getPointerOperand();
575 Type *VectorPtrType = getVectorPtrTy(Pointer, 1);
576 Value *NewPointer = getOperand(Pointer, BBMap);
577 Value *VectorPtr = Builder.CreateBitCast(NewPointer, VectorPtrType,
578 Load->getName() + "_p_vec_p");
579 LoadInst *ScalarLoad= Builder.CreateLoad(VectorPtr,
580 Load->getName() + "_p_splat_one");
581
582 if (!Aligned)
583 ScalarLoad->setAlignment(8);
584
585 Constant *SplatVector =
586 Constant::getNullValue(VectorType::get(Builder.getInt32Ty(),
587 getVectorWidth()));
588
589 Value *VectorLoad = Builder.CreateShuffleVector(ScalarLoad, ScalarLoad,
590 SplatVector,
591 Load->getName()
592 + "_p_splat");
593 return VectorLoad;
594}
595
596Value *VectorBlockGenerator::generateUnknownStrideLoad(const LoadInst *Load,
597 VectorValueMapT &ScalarMaps) {
598 int VectorWidth = getVectorWidth();
599 const Value *Pointer = Load->getPointerOperand();
600 VectorType *VectorType = VectorType::get(
601 dyn_cast<PointerType>(Pointer->getType())->getElementType(), VectorWidth);
602
603 Value *Vector = UndefValue::get(VectorType);
604
605 for (int i = 0; i < VectorWidth; i++) {
606 Value *NewPointer = getOperand(Pointer, ScalarMaps[i]);
607 Value *ScalarLoad = Builder.CreateLoad(NewPointer,
608 Load->getName() + "_p_scalar_");
609 Vector = Builder.CreateInsertElement(Vector, ScalarLoad,
610 Builder.getInt32(i),
611 Load->getName() + "_p_vec_");
612 }
613
614 return Vector;
615}
616
617void VectorBlockGenerator::generateLoad(const LoadInst *Load,
618 ValueMapT &VectorMap,
619 VectorValueMapT &ScalarMaps) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000620 Value *NewLoad;
621
622 MemoryAccess &Access = Statement.getAccessFor(Load);
623
624 assert(ScatteringDomain && "No scattering domain available");
625
626 if (Access.isStrideZero(isl_set_copy(ScatteringDomain)))
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000627 NewLoad = generateStrideZeroLoad(Load, ScalarMaps[0]);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000628 else if (Access.isStrideOne(isl_set_copy(ScatteringDomain)))
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000629 NewLoad = generateStrideOneLoad(Load, ScalarMaps[0]);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000630 else
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000631 NewLoad = generateUnknownStrideLoad(Load, ScalarMaps);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000632
633 VectorMap[Load] = NewLoad;
634}
635
Tobias Grosser80998e72012-03-02 11:27:28 +0000636void VectorBlockGenerator::copyUnaryInst(const UnaryInstruction *Inst,
Tobias Grosser8b4bf8b2012-03-02 11:27:11 +0000637 ValueMapT &BBMap,
638 ValueMapT &VectorMap) {
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000639 int VectorWidth = getVectorWidth();
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000640 Value *NewOperand = getOperand(Inst->getOperand(0), BBMap, &VectorMap);
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000641 NewOperand = makeVectorOperand(NewOperand);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000642
643 assert(isa<CastInst>(Inst) && "Can not generate vector code for instruction");
644
645 const CastInst *Cast = dyn_cast<CastInst>(Inst);
646 VectorType *DestType = VectorType::get(Inst->getType(), VectorWidth);
647 VectorMap[Inst] = Builder.CreateCast(Cast->getOpcode(), NewOperand, DestType);
648}
649
Tobias Grosser80998e72012-03-02 11:27:28 +0000650void VectorBlockGenerator::copyBinaryInst(const BinaryOperator *Inst,
651 ValueMapT &BBMap,
652 ValueMapT &VectorMap) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000653 Value *OpZero = Inst->getOperand(0);
654 Value *OpOne = Inst->getOperand(1);
655
656 Value *NewOpZero, *NewOpOne;
657 NewOpZero = getOperand(OpZero, BBMap, &VectorMap);
658 NewOpOne = getOperand(OpOne, BBMap, &VectorMap);
659
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000660 NewOpZero = makeVectorOperand(NewOpZero);
661 NewOpOne = makeVectorOperand(NewOpOne);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000662
663 Value *NewInst = Builder.CreateBinOp(Inst->getOpcode(), NewOpZero,
664 NewOpOne,
665 Inst->getName() + "p_vec");
666 VectorMap[Inst] = NewInst;
667}
668
Tobias Grosser80998e72012-03-02 11:27:28 +0000669void VectorBlockGenerator::copyStore(const StoreInst *Store, ValueMapT &BBMap,
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000670 ValueMapT &VectorMap,
Tobias Grosser8927a442012-03-02 11:27:05 +0000671 VectorValueMapT &ScalarMaps) {
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000672 int VectorWidth = getVectorWidth();
673
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000674 MemoryAccess &Access = Statement.getAccessFor(Store);
675
676 assert(ScatteringDomain && "No scattering domain available");
677
678 const Value *Pointer = Store->getPointerOperand();
679 Value *Vector = getOperand(Store->getValueOperand(), BBMap, &VectorMap);
680
681 if (Access.isStrideOne(isl_set_copy(ScatteringDomain))) {
682 Type *VectorPtrType = getVectorPtrTy(Pointer, VectorWidth);
683 Value *NewPointer = getOperand(Pointer, BBMap, &VectorMap);
684
685 Value *VectorPtr = Builder.CreateBitCast(NewPointer, VectorPtrType,
686 "vector_ptr");
687 StoreInst *Store = Builder.CreateStore(Vector, VectorPtr);
688
689 if (!Aligned)
690 Store->setAlignment(8);
691 } else {
692 for (unsigned i = 0; i < ScalarMaps.size(); i++) {
693 Value *Scalar = Builder.CreateExtractElement(Vector,
694 Builder.getInt32(i));
695 Value *NewPointer = getOperand(Pointer, ScalarMaps[i]);
696 Builder.CreateStore(Scalar, NewPointer);
697 }
698 }
699}
700
Tobias Grosser80998e72012-03-02 11:27:28 +0000701bool VectorBlockGenerator::hasVectorOperands(const Instruction *Inst,
702 ValueMapT &VectorMap) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000703 for (Instruction::const_op_iterator OI = Inst->op_begin(),
704 OE = Inst->op_end(); OI != OE; ++OI)
705 if (VectorMap.count(*OI))
706 return true;
707 return false;
708}
709
Tobias Grosser80998e72012-03-02 11:27:28 +0000710int VectorBlockGenerator::getVectorWidth() {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000711 return ValueMaps.size();
712}
713
Tobias Grosser80998e72012-03-02 11:27:28 +0000714void VectorBlockGenerator::copyInstruction(const Instruction *Inst,
Tobias Grosser32152cb2012-03-02 11:27:18 +0000715 ValueMapT &VectorMap,
716 VectorValueMapT &ScalarMaps) {
Tobias Grosser80998e72012-03-02 11:27:28 +0000717 // Terminator instructions control the control flow. They are explicitly
718 // expressed in the clast and do not need to be copied.
719 if (Inst->isTerminator())
720 return;
721
Tobias Grosser32152cb2012-03-02 11:27:18 +0000722 if (const LoadInst *Load = dyn_cast<LoadInst>(Inst)) {
Tobias Grosser80998e72012-03-02 11:27:28 +0000723 generateLoad(Load, VectorMap, ScalarMaps);
Tobias Grosser32152cb2012-03-02 11:27:18 +0000724 return;
725 }
726
727 if (hasVectorOperands(Inst, VectorMap)) {
728 if (const StoreInst *Store = dyn_cast<StoreInst>(Inst)) {
Tobias Grosser80998e72012-03-02 11:27:28 +0000729 copyStore(Store, ScalarMaps[0], VectorMap, ScalarMaps);
Tobias Grosser32152cb2012-03-02 11:27:18 +0000730 return;
731 }
732
733 if (const UnaryInstruction *Unary = dyn_cast<UnaryInstruction>(Inst)) {
Tobias Grosser80998e72012-03-02 11:27:28 +0000734 copyUnaryInst(Unary, ScalarMaps[0], VectorMap);
Tobias Grosser32152cb2012-03-02 11:27:18 +0000735 return;
736 }
737
738 if (const BinaryOperator *Binary = dyn_cast<BinaryOperator>(Inst)) {
Tobias Grosser80998e72012-03-02 11:27:28 +0000739 copyBinaryInst(Binary, ScalarMaps[0], VectorMap);
Tobias Grosser32152cb2012-03-02 11:27:18 +0000740 return;
741 }
742
743 llvm_unreachable("Cannot issue vector code for this instruction");
744 }
745
746 for (int VectorLane = 0; VectorLane < getVectorWidth(); VectorLane++)
747 copyInstScalar(Inst, ScalarMaps[VectorLane]);
748}
749
Tobias Grosser80998e72012-03-02 11:27:28 +0000750void VectorBlockGenerator::copyBB() {
Tobias Grosser14bcbd52012-03-02 11:26:52 +0000751 BasicBlock *BB = Statement.getBasicBlock();
Tobias Grosser0ac92142012-02-14 14:02:27 +0000752 BasicBlock *CopyBB = SplitBlock(Builder.GetInsertBlock(),
753 Builder.GetInsertPoint(), P);
Tobias Grosserb61e6312012-02-15 09:58:46 +0000754 CopyBB->setName("polly.stmt." + BB->getName());
Tobias Grosser0ac92142012-02-14 14:02:27 +0000755 Builder.SetInsertPoint(CopyBB->begin());
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000756
757 // Create two maps that store the mapping from the original instructions of
758 // the old basic block to their copies in the new basic block. Those maps
759 // are basic block local.
760 //
761 // As vector code generation is supported there is one map for scalar values
762 // and one for vector values.
763 //
764 // In case we just do scalar code generation, the vectorMap is not used and
765 // the scalarMap has just one dimension, which contains the mapping.
766 //
767 // In case vector code generation is done, an instruction may either appear
768 // in the vector map once (as it is calculating >vectorwidth< values at a
769 // time. Or (if the values are calculated using scalar operations), it
770 // appears once in every dimension of the scalarMap.
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000771 VectorValueMapT ScalarBlockMap(getVectorWidth());
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000772 ValueMapT VectorBlockMap;
773
774 for (BasicBlock::const_iterator II = BB->begin(), IE = BB->end();
775 II != IE; ++II)
Tobias Grosserfc1153f2012-03-02 11:27:15 +0000776 copyInstruction(II, VectorBlockMap, ScalarBlockMap);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000777}
778
Tobias Grosser75805372011-04-29 06:27:02 +0000779/// Class to generate LLVM-IR that calculates the value of a clast_expr.
780class ClastExpCodeGen {
781 IRBuilder<> &Builder;
782 const CharMapT *IVS;
783
Tobias Grosserbb137e32012-01-24 16:42:28 +0000784 Value *codegen(const clast_name *e, Type *Ty);
785 Value *codegen(const clast_term *e, Type *Ty);
786 Value *codegen(const clast_binary *e, Type *Ty);
787 Value *codegen(const clast_reduction *r, Type *Ty);
Tobias Grosser75805372011-04-29 06:27:02 +0000788public:
789
790 // A generator for clast expressions.
791 //
792 // @param B The IRBuilder that defines where the code to calculate the
793 // clast expressions should be inserted.
794 // @param IVMAP A Map that translates strings describing the induction
795 // variables to the Values* that represent these variables
796 // on the LLVM side.
Tobias Grosserbb137e32012-01-24 16:42:28 +0000797 ClastExpCodeGen(IRBuilder<> &B, CharMapT *IVMap);
Tobias Grosser75805372011-04-29 06:27:02 +0000798
799 // Generates code to calculate a given clast expression.
800 //
801 // @param e The expression to calculate.
802 // @return The Value that holds the result.
Tobias Grosserbb137e32012-01-24 16:42:28 +0000803 Value *codegen(const clast_expr *e, Type *Ty);
Tobias Grosser75805372011-04-29 06:27:02 +0000804
805 // @brief Reset the CharMap.
806 //
807 // This function is called to reset the CharMap to new one, while generating
808 // OpenMP code.
Tobias Grosserbb137e32012-01-24 16:42:28 +0000809 void setIVS(CharMapT *IVSNew);
810};
811
812Value *ClastExpCodeGen::codegen(const clast_name *e, Type *Ty) {
813 CharMapT::const_iterator I = IVS->find(e->name);
814
815 assert(I != IVS->end() && "Clast name not found");
816
817 return Builder.CreateSExtOrBitCast(I->second, Ty);
818}
819
820Value *ClastExpCodeGen::codegen(const clast_term *e, Type *Ty) {
821 APInt a = APInt_from_MPZ(e->val);
822
823 Value *ConstOne = ConstantInt::get(Builder.getContext(), a);
824 ConstOne = Builder.CreateSExtOrBitCast(ConstOne, Ty);
825
826 if (!e->var)
827 return ConstOne;
828
829 Value *var = codegen(e->var, Ty);
830 return Builder.CreateMul(ConstOne, var);
831}
832
833Value *ClastExpCodeGen::codegen(const clast_binary *e, Type *Ty) {
834 Value *LHS = codegen(e->LHS, Ty);
835
836 APInt RHS_AP = APInt_from_MPZ(e->RHS);
837
838 Value *RHS = ConstantInt::get(Builder.getContext(), RHS_AP);
839 RHS = Builder.CreateSExtOrBitCast(RHS, Ty);
840
841 switch (e->type) {
842 case clast_bin_mod:
843 return Builder.CreateSRem(LHS, RHS);
844 case clast_bin_fdiv:
845 {
Tobias Grosser9a44b972012-02-16 14:13:19 +0000846 // floord(n,d) ((n < 0) ? (n - d + 1) : n) / d
Tobias Grosser906eafe2012-02-16 09:56:10 +0000847 Value *One = ConstantInt::get(Ty, 1);
848 Value *Zero = ConstantInt::get(Ty, 0);
Tobias Grosser9a44b972012-02-16 14:13:19 +0000849 Value *Sum1 = Builder.CreateSub(LHS, RHS);
850 Value *Sum2 = Builder.CreateAdd(Sum1, One);
851 Value *isNegative = Builder.CreateICmpSLT(LHS, Zero);
852 Value *Dividend = Builder.CreateSelect(isNegative, Sum2, LHS);
853 return Builder.CreateSDiv(Dividend, RHS);
Tobias Grosserbb137e32012-01-24 16:42:28 +0000854 }
855 case clast_bin_cdiv:
856 {
Tobias Grosser9a44b972012-02-16 14:13:19 +0000857 // ceild(n,d) ((n < 0) ? n : (n + d - 1)) / d
858 Value *One = ConstantInt::get(Ty, 1);
Tobias Grosser906eafe2012-02-16 09:56:10 +0000859 Value *Zero = ConstantInt::get(Ty, 0);
Tobias Grosser9a44b972012-02-16 14:13:19 +0000860 Value *Sum1 = Builder.CreateAdd(LHS, RHS);
861 Value *Sum2 = Builder.CreateSub(Sum1, One);
862 Value *isNegative = Builder.CreateICmpSLT(LHS, Zero);
863 Value *Dividend = Builder.CreateSelect(isNegative, LHS, Sum2);
864 return Builder.CreateSDiv(Dividend, RHS);
Tobias Grosserbb137e32012-01-24 16:42:28 +0000865 }
866 case clast_bin_div:
867 return Builder.CreateSDiv(LHS, RHS);
868 };
869
870 llvm_unreachable("Unknown clast binary expression type");
871}
872
873Value *ClastExpCodeGen::codegen(const clast_reduction *r, Type *Ty) {
874 assert(( r->type == clast_red_min
875 || r->type == clast_red_max
876 || r->type == clast_red_sum)
877 && "Clast reduction type not supported");
878 Value *old = codegen(r->elts[0], Ty);
879
880 for (int i=1; i < r->n; ++i) {
881 Value *exprValue = codegen(r->elts[i], Ty);
882
883 switch (r->type) {
884 case clast_red_min:
885 {
886 Value *cmp = Builder.CreateICmpSLT(old, exprValue);
887 old = Builder.CreateSelect(cmp, old, exprValue);
888 break;
889 }
890 case clast_red_max:
891 {
892 Value *cmp = Builder.CreateICmpSGT(old, exprValue);
893 old = Builder.CreateSelect(cmp, old, exprValue);
894 break;
895 }
896 case clast_red_sum:
897 old = Builder.CreateAdd(old, exprValue);
898 break;
Tobias Grosserbb137e32012-01-24 16:42:28 +0000899 }
Tobias Grosser75805372011-04-29 06:27:02 +0000900 }
901
Tobias Grosserbb137e32012-01-24 16:42:28 +0000902 return old;
903}
904
905ClastExpCodeGen::ClastExpCodeGen(IRBuilder<> &B, CharMapT *IVMap)
906 : Builder(B), IVS(IVMap) {}
907
908Value *ClastExpCodeGen::codegen(const clast_expr *e, Type *Ty) {
909 switch(e->type) {
910 case clast_expr_name:
911 return codegen((const clast_name *)e, Ty);
912 case clast_expr_term:
913 return codegen((const clast_term *)e, Ty);
914 case clast_expr_bin:
915 return codegen((const clast_binary *)e, Ty);
916 case clast_expr_red:
917 return codegen((const clast_reduction *)e, Ty);
918 }
919
920 llvm_unreachable("Unknown clast expression!");
921}
922
923void ClastExpCodeGen::setIVS(CharMapT *IVSNew) {
924 IVS = IVSNew;
925}
Tobias Grosser75805372011-04-29 06:27:02 +0000926
927class ClastStmtCodeGen {
928 // The Scop we code generate.
929 Scop *S;
930 ScalarEvolution &SE;
Tobias Grosser75805372011-04-29 06:27:02 +0000931 DominatorTree *DT;
Hongbin Zheng94c5df12011-05-06 02:38:20 +0000932 ScopDetection *SD;
Tobias Grosser75805372011-04-29 06:27:02 +0000933 Dependences *DP;
934 TargetData *TD;
Tobias Grosser0ac92142012-02-14 14:02:27 +0000935 Pass *P;
Tobias Grosser75805372011-04-29 06:27:02 +0000936
937 // The Builder specifies the current location to code generate at.
938 IRBuilder<> &Builder;
939
940 // Map the Values from the old code to their counterparts in the new code.
941 ValueMapT ValueMap;
942
943 // clastVars maps from the textual representation of a clast variable to its
944 // current *Value. clast variables are scheduling variables, original
945 // induction variables or parameters. They are used either in loop bounds or
946 // to define the statement instance that is executed.
947 //
948 // for (s = 0; s < n + 3; ++i)
949 // for (t = s; t < m; ++j)
950 // Stmt(i = s + 3 * m, j = t);
951 //
952 // {s,t,i,j,n,m} is the set of clast variables in this clast.
953 CharMapT *clastVars;
954
955 // Codegenerator for clast expressions.
956 ClastExpCodeGen ExpGen;
957
958 // Do we currently generate parallel code?
959 bool parallelCodeGeneration;
960
961 std::vector<std::string> parallelLoops;
962
963public:
964
Tobias Grosser9bc5eb082012-01-24 16:42:32 +0000965 const std::vector<std::string> &getParallelLoops();
Tobias Grosser75805372011-04-29 06:27:02 +0000966
967 protected:
Tobias Grosser9bc5eb082012-01-24 16:42:32 +0000968 void codegen(const clast_assignment *a);
Tobias Grosser75805372011-04-29 06:27:02 +0000969
970 void codegen(const clast_assignment *a, ScopStmt *Statement,
971 unsigned Dimension, int vectorDim,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +0000972 std::vector<ValueMapT> *VectorVMap = 0);
Tobias Grosser75805372011-04-29 06:27:02 +0000973
974 void codegenSubstitutions(const clast_stmt *Assignment,
975 ScopStmt *Statement, int vectorDim = 0,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +0000976 std::vector<ValueMapT> *VectorVMap = 0);
Tobias Grosser75805372011-04-29 06:27:02 +0000977
978 void codegen(const clast_user_stmt *u, std::vector<Value*> *IVS = NULL,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +0000979 const char *iterator = NULL, isl_set *scatteringDomain = 0);
Tobias Grosser75805372011-04-29 06:27:02 +0000980
Tobias Grosser9bc5eb082012-01-24 16:42:32 +0000981 void codegen(const clast_block *b);
Tobias Grosser75805372011-04-29 06:27:02 +0000982
983 /// @brief Create a classical sequential loop.
Tobias Grosser545bc312011-12-06 10:48:27 +0000984 void codegenForSequential(const clast_for *f, Value *LowerBound = 0,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +0000985 Value *UpperBound = 0);
Tobias Grosser75805372011-04-29 06:27:02 +0000986
Tobias Grosser75805372011-04-29 06:27:02 +0000987 /// @brief Add a new definition of an openmp subfunction.
Tobias Grosser9bc5eb082012-01-24 16:42:32 +0000988 Function *addOpenMPSubfunction(Module *M);
Tobias Grosser75805372011-04-29 06:27:02 +0000989
990 /// @brief Add values to the OpenMP structure.
991 ///
992 /// Create the subfunction structure and add the values from the list.
993 Value *addValuesToOpenMPStruct(SetVector<Value*> OMPDataVals,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +0000994 Function *SubFunction);
Tobias Grosser75805372011-04-29 06:27:02 +0000995
996 /// @brief Create OpenMP structure values.
997 ///
998 /// Create a list of values that has to be stored into the subfuncition
999 /// structure.
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001000 SetVector<Value*> createOpenMPStructValues();
Tobias Grosser75805372011-04-29 06:27:02 +00001001
1002 /// @brief Extract the values from the subfunction parameter.
1003 ///
1004 /// Extract the values from the subfunction parameter and update the clast
1005 /// variables to point to the new values.
1006 void extractValuesFromOpenMPStruct(CharMapT *clastVarsOMP,
1007 SetVector<Value*> OMPDataVals,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001008 Value *userContext);
Tobias Grosser75805372011-04-29 06:27:02 +00001009
1010 /// @brief Add body to the subfunction.
1011 void addOpenMPSubfunctionBody(Function *FN, const clast_for *f,
1012 Value *structData,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001013 SetVector<Value*> OMPDataVals);
Tobias Grosser75805372011-04-29 06:27:02 +00001014
1015 /// @brief Create an OpenMP parallel for loop.
1016 ///
1017 /// This loop reflects a loop as if it would have been created by an OpenMP
1018 /// statement.
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001019 void codegenForOpenMP(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +00001020
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001021 bool isInnermostLoop(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +00001022
1023 /// @brief Get the number of loop iterations for this loop.
1024 /// @param f The clast for loop to check.
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001025 int getNumberOfIterations(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +00001026
1027 /// @brief Create vector instructions for this loop.
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001028 void codegenForVector(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +00001029
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001030 void codegen(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +00001031
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001032 Value *codegen(const clast_equation *eq);
Tobias Grosser75805372011-04-29 06:27:02 +00001033
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001034 void codegen(const clast_guard *g);
Tobias Grosser75805372011-04-29 06:27:02 +00001035
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001036 void codegen(const clast_stmt *stmt);
Tobias Grosser75805372011-04-29 06:27:02 +00001037
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001038 void addParameters(const CloogNames *names);
Tobias Grosser75805372011-04-29 06:27:02 +00001039
1040 public:
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001041 void codegen(const clast_root *r);
Tobias Grosser75805372011-04-29 06:27:02 +00001042
1043 ClastStmtCodeGen(Scop *scop, ScalarEvolution &se, DominatorTree *dt,
Hongbin Zheng94c5df12011-05-06 02:38:20 +00001044 ScopDetection *sd, Dependences *dp, TargetData *td,
Tobias Grosser0ac92142012-02-14 14:02:27 +00001045 IRBuilder<> &B, Pass *P);
Tobias Grosser75805372011-04-29 06:27:02 +00001046};
1047}
1048
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001049const std::vector<std::string> &ClastStmtCodeGen::getParallelLoops() {
1050 return parallelLoops;
1051}
1052
1053void ClastStmtCodeGen::codegen(const clast_assignment *a) {
1054 Value *V= ExpGen.codegen(a->RHS, TD->getIntPtrType(Builder.getContext()));
1055 (*clastVars)[a->LHS] = V;
1056}
1057
1058void ClastStmtCodeGen::codegen(const clast_assignment *a, ScopStmt *Statement,
1059 unsigned Dimension, int vectorDim,
1060 std::vector<ValueMapT> *VectorVMap) {
1061 Value *RHS = ExpGen.codegen(a->RHS,
1062 TD->getIntPtrType(Builder.getContext()));
1063
1064 assert(!a->LHS && "Statement assignments do not have left hand side");
1065 const PHINode *PN;
1066 PN = Statement->getInductionVariableForDimension(Dimension);
1067 const Value *V = PN;
1068
1069 if (VectorVMap)
1070 (*VectorVMap)[vectorDim][V] = RHS;
1071
1072 ValueMap[V] = RHS;
1073}
1074
1075void ClastStmtCodeGen::codegenSubstitutions(const clast_stmt *Assignment,
1076 ScopStmt *Statement, int vectorDim,
1077 std::vector<ValueMapT> *VectorVMap) {
1078 int Dimension = 0;
1079
1080 while (Assignment) {
1081 assert(CLAST_STMT_IS_A(Assignment, stmt_ass)
1082 && "Substitions are expected to be assignments");
1083 codegen((const clast_assignment *)Assignment, Statement, Dimension,
1084 vectorDim, VectorVMap);
1085 Assignment = Assignment->next;
1086 Dimension++;
1087 }
1088}
1089
1090void ClastStmtCodeGen::codegen(const clast_user_stmt *u,
1091 std::vector<Value*> *IVS , const char *iterator,
Tobias Grosser14bcbd52012-03-02 11:26:52 +00001092 isl_set *Domain) {
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001093 ScopStmt *Statement = (ScopStmt *)u->statement->usr;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001094
1095 if (u->substitutions)
1096 codegenSubstitutions(u->substitutions, Statement);
1097
Tobias Grosser80998e72012-03-02 11:27:28 +00001098 int VectorDimensions = IVS ? IVS->size() : 1;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001099
Tobias Grosser80998e72012-03-02 11:27:28 +00001100 if (VectorDimensions == 1) {
1101 BlockGenerator::generate(Builder, ValueMap, *Statement, Domain, P);
1102 return;
1103 }
1104
1105 VectorValueMapT VectorMap(VectorDimensions);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001106
1107 if (IVS) {
1108 assert (u->substitutions && "Substitutions expected!");
1109 int i = 0;
1110 for (std::vector<Value*>::iterator II = IVS->begin(), IE = IVS->end();
1111 II != IE; ++II) {
1112 (*clastVars)[iterator] = *II;
Tobias Grosser14bcbd52012-03-02 11:26:52 +00001113 codegenSubstitutions(u->substitutions, Statement, i, &VectorMap);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001114 i++;
1115 }
1116 }
1117
Tobias Grosser80998e72012-03-02 11:27:28 +00001118 VectorBlockGenerator::generate(Builder, ValueMap, VectorMap, *Statement,
1119 Domain, P);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001120}
1121
1122void ClastStmtCodeGen::codegen(const clast_block *b) {
1123 if (b->body)
1124 codegen(b->body);
1125}
1126
1127void ClastStmtCodeGen::codegenForSequential(const clast_for *f,
1128 Value *LowerBound,
1129 Value *UpperBound) {
1130 APInt Stride;
Tobias Grosser0ac92142012-02-14 14:02:27 +00001131 BasicBlock *AfterBB;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001132 Type *IntPtrTy;
1133
1134 Stride = APInt_from_MPZ(f->stride);
1135 IntPtrTy = TD->getIntPtrType(Builder.getContext());
1136
1137 // The value of lowerbound and upperbound will be supplied, if this
1138 // function is called while generating OpenMP code. Otherwise get
1139 // the values.
1140 assert(!!LowerBound == !!UpperBound && "Either give both bounds or none");
1141
1142 if (LowerBound == 0) {
1143 LowerBound = ExpGen.codegen(f->LB, IntPtrTy);
1144 UpperBound = ExpGen.codegen(f->UB, IntPtrTy);
1145 }
1146
Tobias Grosser0ac92142012-02-14 14:02:27 +00001147 Value *IV = createLoop(&Builder, LowerBound, UpperBound, Stride, DT, P,
1148 &AfterBB);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001149
1150 // Add loop iv to symbols.
1151 (*clastVars)[f->iterator] = IV;
1152
1153 if (f->body)
1154 codegen(f->body);
1155
1156 // Loop is finished, so remove its iv from the live symbols.
1157 clastVars->erase(f->iterator);
Tobias Grosser0ac92142012-02-14 14:02:27 +00001158 Builder.SetInsertPoint(AfterBB->begin());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001159}
1160
1161Function *ClastStmtCodeGen::addOpenMPSubfunction(Module *M) {
1162 Function *F = Builder.GetInsertBlock()->getParent();
1163 std::vector<Type*> Arguments(1, Builder.getInt8PtrTy());
1164 FunctionType *FT = FunctionType::get(Builder.getVoidTy(), Arguments, false);
1165 Function *FN = Function::Create(FT, Function::InternalLinkage,
1166 F->getName() + ".omp_subfn", M);
1167 // Do not run any polly pass on the new function.
1168 SD->markFunctionAsInvalid(FN);
1169
1170 Function::arg_iterator AI = FN->arg_begin();
1171 AI->setName("omp.userContext");
1172
1173 return FN;
1174}
1175
1176Value *ClastStmtCodeGen::addValuesToOpenMPStruct(SetVector<Value*> OMPDataVals,
1177 Function *SubFunction) {
1178 std::vector<Type*> structMembers;
1179
1180 // Create the structure.
1181 for (unsigned i = 0; i < OMPDataVals.size(); i++)
1182 structMembers.push_back(OMPDataVals[i]->getType());
1183
1184 StructType *structTy = StructType::get(Builder.getContext(),
1185 structMembers);
1186 // Store the values into the structure.
1187 Value *structData = Builder.CreateAlloca(structTy, 0, "omp.userContext");
1188 for (unsigned i = 0; i < OMPDataVals.size(); i++) {
1189 Value *storeAddr = Builder.CreateStructGEP(structData, i);
1190 Builder.CreateStore(OMPDataVals[i], storeAddr);
1191 }
1192
1193 return structData;
1194}
1195
1196SetVector<Value*> ClastStmtCodeGen::createOpenMPStructValues() {
1197 SetVector<Value*> OMPDataVals;
1198
1199 // Push the clast variables available in the clastVars.
1200 for (CharMapT::iterator I = clastVars->begin(), E = clastVars->end();
1201 I != E; I++)
1202 OMPDataVals.insert(I->second);
1203
1204 // Push the base addresses of memory references.
1205 for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI) {
1206 ScopStmt *Stmt = *SI;
1207 for (SmallVector<MemoryAccess*, 8>::iterator I = Stmt->memacc_begin(),
1208 E = Stmt->memacc_end(); I != E; ++I) {
1209 Value *BaseAddr = const_cast<Value*>((*I)->getBaseAddr());
1210 OMPDataVals.insert((BaseAddr));
1211 }
1212 }
1213
1214 return OMPDataVals;
1215}
1216
1217void ClastStmtCodeGen::extractValuesFromOpenMPStruct(CharMapT *clastVarsOMP,
1218 SetVector<Value*> OMPDataVals, Value *userContext) {
1219 // Extract the clast variables.
1220 unsigned i = 0;
1221 for (CharMapT::iterator I = clastVars->begin(), E = clastVars->end();
1222 I != E; I++) {
1223 Value *loadAddr = Builder.CreateStructGEP(userContext, i);
1224 (*clastVarsOMP)[I->first] = Builder.CreateLoad(loadAddr);
1225 i++;
1226 }
1227
1228 // Extract the base addresses of memory references.
1229 for (unsigned j = i; j < OMPDataVals.size(); j++) {
1230 Value *loadAddr = Builder.CreateStructGEP(userContext, j);
1231 Value *baseAddr = OMPDataVals[j];
1232 ValueMap[baseAddr] = Builder.CreateLoad(loadAddr);
1233 }
1234}
1235
1236void ClastStmtCodeGen::addOpenMPSubfunctionBody(Function *FN,
1237 const clast_for *f,
1238 Value *structData,
1239 SetVector<Value*> OMPDataVals) {
1240 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
1241 LLVMContext &Context = FN->getContext();
1242 IntegerType *intPtrTy = TD->getIntPtrType(Context);
1243
1244 // Store the previous basic block.
Tobias Grosser0ac92142012-02-14 14:02:27 +00001245 BasicBlock::iterator PrevInsertPoint = Builder.GetInsertPoint();
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001246 BasicBlock *PrevBB = Builder.GetInsertBlock();
1247
1248 // Create basic blocks.
1249 BasicBlock *HeaderBB = BasicBlock::Create(Context, "omp.setup", FN);
1250 BasicBlock *ExitBB = BasicBlock::Create(Context, "omp.exit", FN);
1251 BasicBlock *checkNextBB = BasicBlock::Create(Context, "omp.checkNext", FN);
1252 BasicBlock *loadIVBoundsBB = BasicBlock::Create(Context, "omp.loadIVBounds",
1253 FN);
1254
1255 DT->addNewBlock(HeaderBB, PrevBB);
1256 DT->addNewBlock(ExitBB, HeaderBB);
1257 DT->addNewBlock(checkNextBB, HeaderBB);
1258 DT->addNewBlock(loadIVBoundsBB, HeaderBB);
1259
1260 // Fill up basic block HeaderBB.
1261 Builder.SetInsertPoint(HeaderBB);
1262 Value *lowerBoundPtr = Builder.CreateAlloca(intPtrTy, 0,
1263 "omp.lowerBoundPtr");
1264 Value *upperBoundPtr = Builder.CreateAlloca(intPtrTy, 0,
1265 "omp.upperBoundPtr");
1266 Value *userContext = Builder.CreateBitCast(FN->arg_begin(),
1267 structData->getType(),
1268 "omp.userContext");
1269
1270 CharMapT clastVarsOMP;
1271 extractValuesFromOpenMPStruct(&clastVarsOMP, OMPDataVals, userContext);
1272
1273 Builder.CreateBr(checkNextBB);
1274
1275 // Add code to check if another set of iterations will be executed.
1276 Builder.SetInsertPoint(checkNextBB);
1277 Function *runtimeNextFunction = M->getFunction("GOMP_loop_runtime_next");
1278 Value *ret1 = Builder.CreateCall2(runtimeNextFunction,
1279 lowerBoundPtr, upperBoundPtr);
1280 Value *hasNextSchedule = Builder.CreateTrunc(ret1, Builder.getInt1Ty(),
1281 "omp.hasNextScheduleBlock");
1282 Builder.CreateCondBr(hasNextSchedule, loadIVBoundsBB, ExitBB);
1283
1284 // Add code to to load the iv bounds for this set of iterations.
1285 Builder.SetInsertPoint(loadIVBoundsBB);
1286 Value *lowerBound = Builder.CreateLoad(lowerBoundPtr, "omp.lowerBound");
1287 Value *upperBound = Builder.CreateLoad(upperBoundPtr, "omp.upperBound");
1288
1289 // Subtract one as the upper bound provided by openmp is a < comparison
1290 // whereas the codegenForSequential function creates a <= comparison.
1291 upperBound = Builder.CreateSub(upperBound, ConstantInt::get(intPtrTy, 1),
1292 "omp.upperBoundAdjusted");
1293
1294 // Use clastVarsOMP during code generation of the OpenMP subfunction.
1295 CharMapT *oldClastVars = clastVars;
1296 clastVars = &clastVarsOMP;
1297 ExpGen.setIVS(&clastVarsOMP);
1298
Tobias Grosser0ac92142012-02-14 14:02:27 +00001299 Builder.CreateBr(checkNextBB);
1300 Builder.SetInsertPoint(--Builder.GetInsertPoint());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001301 codegenForSequential(f, lowerBound, upperBound);
1302
1303 // Restore the old clastVars.
1304 clastVars = oldClastVars;
1305 ExpGen.setIVS(oldClastVars);
1306
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001307 // Add code to terminate this openmp subfunction.
1308 Builder.SetInsertPoint(ExitBB);
1309 Function *endnowaitFunction = M->getFunction("GOMP_loop_end_nowait");
1310 Builder.CreateCall(endnowaitFunction);
1311 Builder.CreateRetVoid();
1312
Tobias Grosser0ac92142012-02-14 14:02:27 +00001313 // Restore the previous insert point.
1314 Builder.SetInsertPoint(PrevInsertPoint);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001315}
1316
Tobias Grosser415245d2012-03-02 15:20:17 +00001317void ClastStmtCodeGen::codegenForOpenMP(const clast_for *For) {
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001318 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
Tobias Grosser415245d2012-03-02 15:20:17 +00001319 IntegerType *IntPtrTy = TD->getIntPtrType(Builder.getContext());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001320
1321 Function *SubFunction = addOpenMPSubfunction(M);
1322 SetVector<Value*> OMPDataVals = createOpenMPStructValues();
Tobias Grosser415245d2012-03-02 15:20:17 +00001323 Value *StructData = addValuesToOpenMPStruct(OMPDataVals, SubFunction);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001324
Tobias Grosser415245d2012-03-02 15:20:17 +00001325 addOpenMPSubfunctionBody(SubFunction, For, StructData, OMPDataVals);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001326
1327 // Create call for GOMP_parallel_loop_runtime_start.
Tobias Grosser415245d2012-03-02 15:20:17 +00001328 Value *SubfunctionParam = Builder.CreateBitCast(StructData,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001329 Builder.getInt8PtrTy(),
1330 "omp_data");
1331
Tobias Grosser415245d2012-03-02 15:20:17 +00001332 Value *NumberOfThreads = Builder.getInt32(0);
1333 Value *LowerBound = ExpGen.codegen(For->LB, IntPtrTy);
1334 Value *UpperBound = ExpGen.codegen(For->UB, IntPtrTy);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001335
1336 // Add one as the upper bound provided by openmp is a < comparison
1337 // whereas the codegenForSequential function creates a <= comparison.
Tobias Grosser415245d2012-03-02 15:20:17 +00001338 UpperBound = Builder.CreateAdd(UpperBound, ConstantInt::get(IntPtrTy, 1));
1339 APInt APStride = APInt_from_MPZ(For->stride);
1340 Value *Stride = ConstantInt::get(IntPtrTy,
1341 APStride.zext(IntPtrTy->getBitWidth()));
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001342
Tobias Grosser415245d2012-03-02 15:20:17 +00001343 Value *Arguments[] = { SubFunction, SubfunctionParam, NumberOfThreads,
1344 LowerBound, UpperBound, Stride};
1345 Builder.CreateCall(M->getFunction("GOMP_parallel_loop_runtime_start"),
1346 Arguments);
1347 Builder.CreateCall(SubFunction, SubfunctionParam);
1348 Builder.CreateCall(M->getFunction("GOMP_parallel_end"));
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001349}
1350
1351bool ClastStmtCodeGen::isInnermostLoop(const clast_for *f) {
1352 const clast_stmt *stmt = f->body;
1353
1354 while (stmt) {
1355 if (!CLAST_STMT_IS_A(stmt, stmt_user))
1356 return false;
1357
1358 stmt = stmt->next;
1359 }
1360
1361 return true;
1362}
1363
1364int ClastStmtCodeGen::getNumberOfIterations(const clast_for *f) {
1365 isl_set *loopDomain = isl_set_copy(isl_set_from_cloog_domain(f->domain));
1366 isl_set *tmp = isl_set_copy(loopDomain);
1367
1368 // Calculate a map similar to the identity map, but with the last input
1369 // and output dimension not related.
1370 // [i0, i1, i2, i3] -> [i0, i1, i2, o0]
1371 isl_space *Space = isl_set_get_space(loopDomain);
1372 Space = isl_space_drop_outputs(Space,
1373 isl_set_dim(loopDomain, isl_dim_set) - 2, 1);
1374 Space = isl_space_map_from_set(Space);
1375 isl_map *identity = isl_map_identity(Space);
1376 identity = isl_map_add_dims(identity, isl_dim_in, 1);
1377 identity = isl_map_add_dims(identity, isl_dim_out, 1);
1378
1379 isl_map *map = isl_map_from_domain_and_range(tmp, loopDomain);
1380 map = isl_map_intersect(map, identity);
1381
1382 isl_map *lexmax = isl_map_lexmax(isl_map_copy(map));
1383 isl_map *lexmin = isl_map_lexmin(map);
1384 isl_map *sub = isl_map_sum(lexmax, isl_map_neg(lexmin));
1385
1386 isl_set *elements = isl_map_range(sub);
1387
1388 if (!isl_set_is_singleton(elements)) {
1389 isl_set_free(elements);
1390 return -1;
1391 }
1392
1393 isl_point *p = isl_set_sample_point(elements);
1394
1395 isl_int v;
1396 isl_int_init(v);
1397 isl_point_get_coordinate(p, isl_dim_set, isl_set_n_dim(loopDomain) - 1, &v);
1398 int numberIterations = isl_int_get_si(v);
1399 isl_int_clear(v);
1400 isl_point_free(p);
1401
1402 return (numberIterations) / isl_int_get_si(f->stride) + 1;
1403}
1404
1405void ClastStmtCodeGen::codegenForVector(const clast_for *f) {
1406 DEBUG(dbgs() << "Vectorizing loop '" << f->iterator << "'\n";);
1407 int vectorWidth = getNumberOfIterations(f);
1408
1409 Value *LB = ExpGen.codegen(f->LB,
1410 TD->getIntPtrType(Builder.getContext()));
1411
1412 APInt Stride = APInt_from_MPZ(f->stride);
1413 IntegerType *LoopIVType = dyn_cast<IntegerType>(LB->getType());
1414 Stride = Stride.zext(LoopIVType->getBitWidth());
1415 Value *StrideValue = ConstantInt::get(LoopIVType, Stride);
1416
1417 std::vector<Value*> IVS(vectorWidth);
1418 IVS[0] = LB;
1419
1420 for (int i = 1; i < vectorWidth; i++)
1421 IVS[i] = Builder.CreateAdd(IVS[i-1], StrideValue, "p_vector_iv");
1422
1423 isl_set *scatteringDomain =
1424 isl_set_copy(isl_set_from_cloog_domain(f->domain));
1425
1426 // Add loop iv to symbols.
1427 (*clastVars)[f->iterator] = LB;
1428
1429 const clast_stmt *stmt = f->body;
1430
1431 while (stmt) {
1432 codegen((const clast_user_stmt *)stmt, &IVS, f->iterator,
1433 scatteringDomain);
1434 stmt = stmt->next;
1435 }
1436
1437 // Loop is finished, so remove its iv from the live symbols.
1438 isl_set_free(scatteringDomain);
1439 clastVars->erase(f->iterator);
1440}
1441
1442void ClastStmtCodeGen::codegen(const clast_for *f) {
Tobias Grosserce3f5372012-03-02 11:26:42 +00001443 if ((Vector || OpenMP) && DP->isParallelFor(f)) {
1444 if (Vector && isInnermostLoop(f) && (-1 != getNumberOfIterations(f))
1445 && (getNumberOfIterations(f) <= 16)) {
1446 codegenForVector(f);
1447 return;
1448 }
1449
1450 if (OpenMP && !parallelCodeGeneration) {
1451 parallelCodeGeneration = true;
1452 parallelLoops.push_back(f->iterator);
1453 codegenForOpenMP(f);
1454 parallelCodeGeneration = false;
1455 return;
1456 }
1457 }
1458
1459 codegenForSequential(f);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001460}
1461
1462Value *ClastStmtCodeGen::codegen(const clast_equation *eq) {
1463 Value *LHS = ExpGen.codegen(eq->LHS,
1464 TD->getIntPtrType(Builder.getContext()));
1465 Value *RHS = ExpGen.codegen(eq->RHS,
1466 TD->getIntPtrType(Builder.getContext()));
1467 CmpInst::Predicate P;
1468
1469 if (eq->sign == 0)
1470 P = ICmpInst::ICMP_EQ;
1471 else if (eq->sign > 0)
1472 P = ICmpInst::ICMP_SGE;
1473 else
1474 P = ICmpInst::ICMP_SLE;
1475
1476 return Builder.CreateICmp(P, LHS, RHS);
1477}
1478
1479void ClastStmtCodeGen::codegen(const clast_guard *g) {
1480 Function *F = Builder.GetInsertBlock()->getParent();
1481 LLVMContext &Context = F->getContext();
Tobias Grosser0ac92142012-02-14 14:02:27 +00001482
1483 BasicBlock *CondBB = SplitBlock(Builder.GetInsertBlock(),
1484 Builder.GetInsertPoint(), P);
1485 CondBB->setName("polly.cond");
1486 BasicBlock *MergeBB = SplitBlock(CondBB, CondBB->begin(), P);
1487 MergeBB->setName("polly.merge");
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001488 BasicBlock *ThenBB = BasicBlock::Create(Context, "polly.then", F);
Tobias Grosser0ac92142012-02-14 14:02:27 +00001489
1490 DT->addNewBlock(ThenBB, CondBB);
1491 DT->changeImmediateDominator(MergeBB, CondBB);
1492
1493 CondBB->getTerminator()->eraseFromParent();
1494
1495 Builder.SetInsertPoint(CondBB);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001496
1497 Value *Predicate = codegen(&(g->eq[0]));
1498
1499 for (int i = 1; i < g->n; ++i) {
1500 Value *TmpPredicate = codegen(&(g->eq[i]));
1501 Predicate = Builder.CreateAnd(Predicate, TmpPredicate);
1502 }
1503
1504 Builder.CreateCondBr(Predicate, ThenBB, MergeBB);
1505 Builder.SetInsertPoint(ThenBB);
Tobias Grosser0ac92142012-02-14 14:02:27 +00001506 Builder.CreateBr(MergeBB);
1507 Builder.SetInsertPoint(ThenBB->begin());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001508
1509 codegen(g->then);
Tobias Grosser62a3c962012-02-16 09:56:21 +00001510
1511 Builder.SetInsertPoint(MergeBB->begin());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001512}
1513
1514void ClastStmtCodeGen::codegen(const clast_stmt *stmt) {
1515 if (CLAST_STMT_IS_A(stmt, stmt_root))
1516 assert(false && "No second root statement expected");
1517 else if (CLAST_STMT_IS_A(stmt, stmt_ass))
1518 codegen((const clast_assignment *)stmt);
1519 else if (CLAST_STMT_IS_A(stmt, stmt_user))
1520 codegen((const clast_user_stmt *)stmt);
1521 else if (CLAST_STMT_IS_A(stmt, stmt_block))
1522 codegen((const clast_block *)stmt);
1523 else if (CLAST_STMT_IS_A(stmt, stmt_for))
1524 codegen((const clast_for *)stmt);
1525 else if (CLAST_STMT_IS_A(stmt, stmt_guard))
1526 codegen((const clast_guard *)stmt);
1527
1528 if (stmt->next)
1529 codegen(stmt->next);
1530}
1531
1532void ClastStmtCodeGen::addParameters(const CloogNames *names) {
1533 SCEVExpander Rewriter(SE, "polly");
1534
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001535 int i = 0;
1536 for (Scop::param_iterator PI = S->param_begin(), PE = S->param_end();
1537 PI != PE; ++PI) {
1538 assert(i < names->nb_parameters && "Not enough parameter names");
1539
1540 const SCEV *Param = *PI;
1541 Type *Ty = Param->getType();
1542
1543 Instruction *insertLocation = --(Builder.GetInsertBlock()->end());
1544 Value *V = Rewriter.expandCodeFor(Param, Ty, insertLocation);
1545 (*clastVars)[names->parameters[i]] = V;
1546
1547 ++i;
1548 }
1549}
1550
1551void ClastStmtCodeGen::codegen(const clast_root *r) {
1552 clastVars = new CharMapT();
1553 addParameters(r->names);
1554 ExpGen.setIVS(clastVars);
1555
1556 parallelCodeGeneration = false;
1557
1558 const clast_stmt *stmt = (const clast_stmt*) r;
1559 if (stmt->next)
1560 codegen(stmt->next);
1561
1562 delete clastVars;
1563}
1564
1565ClastStmtCodeGen::ClastStmtCodeGen(Scop *scop, ScalarEvolution &se,
1566 DominatorTree *dt, ScopDetection *sd,
1567 Dependences *dp, TargetData *td,
Tobias Grosser0ac92142012-02-14 14:02:27 +00001568 IRBuilder<> &B, Pass *P) :
1569 S(scop), SE(se), DT(dt), SD(sd), DP(dp), TD(td), P(P), Builder(B),
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001570 ExpGen(Builder, NULL) {}
1571
Tobias Grosser75805372011-04-29 06:27:02 +00001572namespace {
1573class CodeGeneration : public ScopPass {
1574 Region *region;
1575 Scop *S;
1576 DominatorTree *DT;
1577 ScalarEvolution *SE;
1578 ScopDetection *SD;
Tobias Grosser75805372011-04-29 06:27:02 +00001579 TargetData *TD;
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001580 RegionInfo *RI;
Tobias Grosser75805372011-04-29 06:27:02 +00001581
1582 std::vector<std::string> parallelLoops;
1583
1584 public:
1585 static char ID;
1586
1587 CodeGeneration() : ScopPass(ID) {}
1588
Tobias Grosserb1c95992012-02-12 12:09:27 +00001589 // Add the declarations needed by the OpenMP function calls that we insert in
1590 // OpenMP mode.
1591 void addOpenMPDeclarations(Module *M)
Tobias Grosser75805372011-04-29 06:27:02 +00001592 {
Tobias Grosserd855cc52012-02-12 12:09:32 +00001593 IRBuilder<> Builder(M->getContext());
1594 IntegerType *LongTy = TD->getIntPtrType(M->getContext());
1595
1596 llvm::GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
Tobias Grosser75805372011-04-29 06:27:02 +00001597
1598 if (!M->getFunction("GOMP_parallel_end")) {
Tobias Grosserd855cc52012-02-12 12:09:32 +00001599 FunctionType *Ty = FunctionType::get(Builder.getVoidTy(), false);
1600 Function::Create(Ty, Linkage, "GOMP_parallel_end", M);
Tobias Grosser75805372011-04-29 06:27:02 +00001601 }
1602
1603 if (!M->getFunction("GOMP_parallel_loop_runtime_start")) {
Tobias Grosserd855cc52012-02-12 12:09:32 +00001604 Type *Params[] = {
1605 PointerType::getUnqual(FunctionType::get(Builder.getVoidTy(),
1606 Builder.getInt8PtrTy(),
1607 false)),
1608 Builder.getInt8PtrTy(),
1609 Builder.getInt32Ty(),
1610 LongTy,
1611 LongTy,
1612 LongTy,
1613 };
Tobias Grosser75805372011-04-29 06:27:02 +00001614
Tobias Grosserd855cc52012-02-12 12:09:32 +00001615 FunctionType *Ty = FunctionType::get(Builder.getVoidTy(), Params, false);
1616 Function::Create(Ty, Linkage, "GOMP_parallel_loop_runtime_start", M);
Tobias Grosser75805372011-04-29 06:27:02 +00001617 }
1618
1619 if (!M->getFunction("GOMP_loop_runtime_next")) {
Tobias Grosserd855cc52012-02-12 12:09:32 +00001620 PointerType *LongPtrTy = PointerType::getUnqual(LongTy);
1621 Type *Params[] = {
1622 LongPtrTy,
1623 LongPtrTy,
1624 };
Tobias Grosser75805372011-04-29 06:27:02 +00001625
Tobias Grosserd855cc52012-02-12 12:09:32 +00001626 FunctionType *Ty = FunctionType::get(Builder.getInt8Ty(), Params, false);
1627 Function::Create(Ty, Linkage, "GOMP_loop_runtime_next", M);
Tobias Grosser75805372011-04-29 06:27:02 +00001628 }
1629
1630 if (!M->getFunction("GOMP_loop_end_nowait")) {
Tobias Grosserd855cc52012-02-12 12:09:32 +00001631 FunctionType *Ty = FunctionType::get(Builder.getVoidTy(), false);
1632 Function::Create(Ty, Linkage, "GOMP_loop_end_nowait", M);
Tobias Grosser75805372011-04-29 06:27:02 +00001633 }
1634 }
1635
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001636 // Split the entry edge of the region and generate a new basic block on this
1637 // edge. This function also updates ScopInfo and RegionInfo.
1638 //
1639 // @param region The region where the entry edge will be splitted.
1640 BasicBlock *splitEdgeAdvanced(Region *region) {
1641 BasicBlock *newBlock;
1642 BasicBlock *splitBlock;
1643
1644 newBlock = SplitEdge(region->getEnteringBlock(), region->getEntry(), this);
1645
1646 if (DT->dominates(region->getEntry(), newBlock)) {
Tobias Grossercb47dfe2012-02-15 09:58:50 +00001647 BasicBlock *OldBlock = region->getEntry();
1648 std::string OldName = OldBlock->getName();
1649
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001650 // Update ScopInfo.
1651 for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI)
Tobias Grosserf12cea42012-02-15 09:58:53 +00001652 if ((*SI)->getBasicBlock() == OldBlock) {
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001653 (*SI)->setBasicBlock(newBlock);
1654 break;
1655 }
1656
1657 // Update RegionInfo.
Tobias Grossercb47dfe2012-02-15 09:58:50 +00001658 splitBlock = OldBlock;
1659 OldBlock->setName("polly.split");
1660 newBlock->setName(OldName);
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001661 region->replaceEntry(newBlock);
Tobias Grosser7a16c892011-05-14 19:01:55 +00001662 RI->setRegionFor(newBlock, region);
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001663 } else {
1664 RI->setRegionFor(newBlock, region->getParent());
1665 splitBlock = newBlock;
1666 }
1667
1668 return splitBlock;
1669 }
1670
1671 // Create a split block that branches either to the old code or to a new basic
1672 // block where the new code can be inserted.
1673 //
Tobias Grosserbd608a82012-02-12 12:09:41 +00001674 // @param Builder A builder that will be set to point to a basic block, where
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001675 // the new code can be generated.
1676 // @return The split basic block.
Tobias Grosserbd608a82012-02-12 12:09:41 +00001677 BasicBlock *addSplitAndStartBlock(IRBuilder<> *Builder) {
1678 BasicBlock *StartBlock, *SplitBlock;
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001679
Tobias Grosserbd608a82012-02-12 12:09:41 +00001680 SplitBlock = splitEdgeAdvanced(region);
1681 SplitBlock->setName("polly.split_new_and_old");
1682 Function *F = SplitBlock->getParent();
1683 StartBlock = BasicBlock::Create(F->getContext(), "polly.start", F);
1684 SplitBlock->getTerminator()->eraseFromParent();
1685 Builder->SetInsertPoint(SplitBlock);
1686 Builder->CreateCondBr(Builder->getTrue(), StartBlock, region->getEntry());
1687 DT->addNewBlock(StartBlock, SplitBlock);
1688 Builder->SetInsertPoint(StartBlock);
1689 return SplitBlock;
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001690 }
1691
1692 // Merge the control flow of the newly generated code with the existing code.
1693 //
Tobias Grosserbd608a82012-02-12 12:09:41 +00001694 // @param SplitBlock The basic block where the control flow was split between
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001695 // old and new version of the Scop.
Tobias Grosserbd608a82012-02-12 12:09:41 +00001696 // @param Builder An IRBuilder that points to the last instruction of the
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001697 // newly generated code.
Tobias Grosserbd608a82012-02-12 12:09:41 +00001698 void mergeControlFlow(BasicBlock *SplitBlock, IRBuilder<> *Builder) {
1699 BasicBlock *MergeBlock;
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001700 Region *R = region;
1701
1702 if (R->getExit()->getSinglePredecessor())
1703 // No splitEdge required. A block with a single predecessor cannot have
1704 // PHI nodes that would complicate life.
Tobias Grosserbd608a82012-02-12 12:09:41 +00001705 MergeBlock = R->getExit();
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001706 else {
Tobias Grosserbd608a82012-02-12 12:09:41 +00001707 MergeBlock = SplitEdge(R->getExitingBlock(), R->getExit(), this);
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001708 // SplitEdge will never split R->getExit(), as R->getExit() has more than
1709 // one predecessor. Hence, mergeBlock is always a newly generated block.
Tobias Grosserbd608a82012-02-12 12:09:41 +00001710 R->replaceExit(MergeBlock);
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001711 }
1712
Tobias Grosserbd608a82012-02-12 12:09:41 +00001713 Builder->CreateBr(MergeBlock);
Tobias Grosser8518bbe2012-02-12 12:09:46 +00001714 MergeBlock->setName("polly.merge_new_and_old");
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001715
Tobias Grosserbd608a82012-02-12 12:09:41 +00001716 if (DT->dominates(SplitBlock, MergeBlock))
1717 DT->changeImmediateDominator(MergeBlock, SplitBlock);
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001718 }
1719
Tobias Grosser75805372011-04-29 06:27:02 +00001720 bool runOnScop(Scop &scop) {
1721 S = &scop;
1722 region = &S->getRegion();
Tobias Grosser75805372011-04-29 06:27:02 +00001723 DT = &getAnalysis<DominatorTree>();
1724 Dependences *DP = &getAnalysis<Dependences>();
1725 SE = &getAnalysis<ScalarEvolution>();
Tobias Grosser75805372011-04-29 06:27:02 +00001726 SD = &getAnalysis<ScopDetection>();
1727 TD = &getAnalysis<TargetData>();
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001728 RI = &getAnalysis<RegionInfo>();
Tobias Grosser75805372011-04-29 06:27:02 +00001729
1730 parallelLoops.clear();
1731
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001732 assert(region->isSimple() && "Only simple regions are supported");
Tobias Grosser76d7c522011-05-14 19:01:37 +00001733
Tobias Grosserb1c95992012-02-12 12:09:27 +00001734 Module *M = region->getEntry()->getParent()->getParent();
1735
Tobias Grosserd855cc52012-02-12 12:09:32 +00001736 if (OpenMP) addOpenMPDeclarations(M);
Tobias Grosserb1c95992012-02-12 12:09:27 +00001737
Tobias Grosser5772e652012-02-01 14:23:33 +00001738 // In the CFG the optimized code of the SCoP is generated next to the
1739 // original code. Both the new and the original version of the code remain
1740 // in the CFG. A branch statement decides which version is executed.
1741 // For now, we always execute the new version (the old one is dead code
1742 // eliminated by the cleanup passes). In the future we may decide to execute
1743 // the new version only if certain run time checks succeed. This will be
1744 // useful to support constructs for which we cannot prove all assumptions at
1745 // compile time.
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001746 //
1747 // Before transformation:
1748 //
1749 // bb0
1750 // |
1751 // orig_scop
1752 // |
1753 // bb1
1754 //
1755 // After transformation:
1756 // bb0
1757 // |
1758 // polly.splitBlock
Tobias Grosser2bd3af12011-08-01 22:39:00 +00001759 // / \.
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001760 // | startBlock
1761 // | |
1762 // orig_scop new_scop
1763 // \ /
1764 // \ /
1765 // bb1 (joinBlock)
1766 IRBuilder<> builder(region->getEntry());
Tobias Grosser75805372011-04-29 06:27:02 +00001767
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001768 // The builder will be set to startBlock.
1769 BasicBlock *splitBlock = addSplitAndStartBlock(&builder);
Tobias Grosser0ac92142012-02-14 14:02:27 +00001770 BasicBlock *StartBlock = builder.GetInsertBlock();
Tobias Grosser75805372011-04-29 06:27:02 +00001771
Tobias Grosser0ac92142012-02-14 14:02:27 +00001772 mergeControlFlow(splitBlock, &builder);
1773 builder.SetInsertPoint(StartBlock->begin());
1774
1775 ClastStmtCodeGen CodeGen(S, *SE, DT, SD, DP, TD, builder, this);
Tobias Grosser3fdecae2011-05-14 19:02:39 +00001776 CloogInfo &C = getAnalysis<CloogInfo>();
1777 CodeGen.codegen(C.getClast());
Tobias Grosser75805372011-04-29 06:27:02 +00001778
Tobias Grosser75805372011-04-29 06:27:02 +00001779 parallelLoops.insert(parallelLoops.begin(),
1780 CodeGen.getParallelLoops().begin(),
1781 CodeGen.getParallelLoops().end());
1782
Tobias Grosserabb6dcd2011-05-14 19:02:34 +00001783 return true;
Tobias Grosser75805372011-04-29 06:27:02 +00001784 }
1785
1786 virtual void printScop(raw_ostream &OS) const {
1787 for (std::vector<std::string>::const_iterator PI = parallelLoops.begin(),
1788 PE = parallelLoops.end(); PI != PE; ++PI)
1789 OS << "Parallel loop with iterator '" << *PI << "' generated\n";
1790 }
1791
1792 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
1793 AU.addRequired<CloogInfo>();
1794 AU.addRequired<Dependences>();
1795 AU.addRequired<DominatorTree>();
Tobias Grosser75805372011-04-29 06:27:02 +00001796 AU.addRequired<RegionInfo>();
Tobias Grosser73600b82011-10-08 00:30:40 +00001797 AU.addRequired<ScalarEvolution>();
Tobias Grosser75805372011-04-29 06:27:02 +00001798 AU.addRequired<ScopDetection>();
1799 AU.addRequired<ScopInfo>();
1800 AU.addRequired<TargetData>();
1801
1802 AU.addPreserved<CloogInfo>();
1803 AU.addPreserved<Dependences>();
Tobias Grosser5d6eb862011-05-14 19:02:45 +00001804
Tobias Grosser4e3f9a42011-05-23 15:23:36 +00001805 // FIXME: We do not create LoopInfo for the newly generated loops.
Tobias Grosser75805372011-04-29 06:27:02 +00001806 AU.addPreserved<LoopInfo>();
1807 AU.addPreserved<DominatorTree>();
Tobias Grosser75805372011-04-29 06:27:02 +00001808 AU.addPreserved<ScopDetection>();
1809 AU.addPreserved<ScalarEvolution>();
Tobias Grosser5d6eb862011-05-14 19:02:45 +00001810
Tobias Grosser4e3f9a42011-05-23 15:23:36 +00001811 // FIXME: We do not yet add regions for the newly generated code to the
1812 // region tree.
Tobias Grosser75805372011-04-29 06:27:02 +00001813 AU.addPreserved<RegionInfo>();
1814 AU.addPreserved<TempScopInfo>();
1815 AU.addPreserved<ScopInfo>();
1816 AU.addPreservedID(IndependentBlocksID);
1817 }
1818};
1819}
1820
1821char CodeGeneration::ID = 1;
1822
Tobias Grosser73600b82011-10-08 00:30:40 +00001823INITIALIZE_PASS_BEGIN(CodeGeneration, "polly-codegen",
1824 "Polly - Create LLVM-IR form SCoPs", false, false)
1825INITIALIZE_PASS_DEPENDENCY(CloogInfo)
1826INITIALIZE_PASS_DEPENDENCY(Dependences)
1827INITIALIZE_PASS_DEPENDENCY(DominatorTree)
1828INITIALIZE_PASS_DEPENDENCY(RegionInfo)
1829INITIALIZE_PASS_DEPENDENCY(ScalarEvolution)
1830INITIALIZE_PASS_DEPENDENCY(ScopDetection)
1831INITIALIZE_PASS_DEPENDENCY(TargetData)
1832INITIALIZE_PASS_END(CodeGeneration, "polly-codegen",
1833 "Polly - Create LLVM-IR form SCoPs", false, false)
Tobias Grosser75805372011-04-29 06:27:02 +00001834
Tobias Grosser7ffe4e82011-11-17 12:56:10 +00001835Pass *polly::createCodeGenerationPass() {
Tobias Grosser75805372011-04-29 06:27:02 +00001836 return new CodeGeneration();
1837}