blob: 0179eeb37bff9c10397df704732afa10234afd68 [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 Grosser08a82382012-03-02 15:20:24 +0000229 static void generate(IRBuilder<> &B, ValueMapT &ValueMap, ScopStmt &Stmt,
230 Pass *P) {
231 BlockGenerator Generator(B, ValueMap, Stmt, 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;
Tobias Grosser08a82382012-03-02 15:20:24 +0000240
Tobias Grosser8412cda2012-03-02 11:26:55 +0000241 Pass *P;
Tobias Grosser75805372011-04-29 06:27:02 +0000242
Tobias Grosser08a82382012-03-02 15:20:24 +0000243 BlockGenerator(IRBuilder<> &B, ValueMapT &vmap, ScopStmt &Stmt, Pass *P);
Tobias Grosser75805372011-04-29 06:27:02 +0000244
Tobias Grosser80998e72012-03-02 11:27:28 +0000245 Value *getOperand(const Value *oldOperand, ValueMapT &BBMap);
Tobias Grosser75805372011-04-29 06:27:02 +0000246
Tobias Grosser80998e72012-03-02 11:27:28 +0000247 void copyInstScalar(const Instruction *Inst, ValueMapT &BBMap);
Tobias Grosser75805372011-04-29 06:27:02 +0000248
Raghesh Aloor129e8672011-08-15 02:33:39 +0000249 /// @brief Get the memory access offset to be added to the base address
Tobias Grosser80998e72012-03-02 11:27:28 +0000250 std::vector<Value*> getMemoryAccessIndex(__isl_keep isl_map *AccessRelation,
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000251 Value *BaseAddress);
Raghesh Aloor129e8672011-08-15 02:33:39 +0000252
Raghesh Aloor62b13122011-08-03 17:02:50 +0000253 /// @brief Get the new operand address according to the changed access in
254 /// JSCOP file.
Raghesh Aloor46eceba2011-12-09 14:27:17 +0000255 Value *getNewAccessOperand(__isl_keep isl_map *NewAccessRelation,
256 Value *BaseAddress, const Value *OldOperand,
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000257 ValueMapT &BBMap);
Raghesh Aloor62b13122011-08-03 17:02:50 +0000258
259 /// @brief Generate the operand address
260 Value *generateLocationAccessed(const Instruction *Inst,
Tobias Grosser80998e72012-03-02 11:27:28 +0000261 const Value *Pointer, ValueMapT &BBMap);
Raghesh Aloor129e8672011-08-15 02:33:39 +0000262
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000263 Value *generateScalarLoad(const LoadInst *load, ValueMapT &BBMap);
Tobias Grosser75805372011-04-29 06:27:02 +0000264
Tobias Grosser80998e72012-03-02 11:27:28 +0000265 void copyInstruction(const Instruction *Inst, ValueMapT &ScalarMap);
Tobias Grosser75805372011-04-29 06:27:02 +0000266
Tobias Grosser8412cda2012-03-02 11:26:55 +0000267 void copyBB();
Tobias Grosser75805372011-04-29 06:27:02 +0000268};
269
Tobias Grosser80998e72012-03-02 11:27:28 +0000270BlockGenerator::BlockGenerator(IRBuilder<> &B, ValueMapT &vmap, ScopStmt &Stmt,
Tobias Grosser08a82382012-03-02 15:20:24 +0000271 Pass *P) :
272 Builder(B), VMap(vmap), S(*Stmt.getParent()), Statement(Stmt), P(P) {}
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000273
Tobias Grosser80998e72012-03-02 11:27:28 +0000274Value *BlockGenerator::getOperand(const Value *OldOperand, ValueMapT &BBMap) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000275 const Instruction *OpInst = dyn_cast<Instruction>(OldOperand);
276
277 if (!OpInst)
278 return const_cast<Value*>(OldOperand);
279
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000280 // IVS and Parameters.
281 if (VMap.count(OldOperand)) {
282 Value *NewOperand = VMap[OldOperand];
283
284 // Insert a cast if types are different
285 if (OldOperand->getType()->getScalarSizeInBits()
286 < NewOperand->getType()->getScalarSizeInBits())
287 NewOperand = Builder.CreateTruncOrBitCast(NewOperand,
288 OldOperand->getType());
289
290 return NewOperand;
291 }
292
293 // Instructions calculated in the current BB.
294 if (BBMap.count(OldOperand)) {
295 return BBMap[OldOperand];
296 }
297
298 // Ignore instructions that are referencing ops in the old BB. These
299 // instructions are unused. They where replace by new ones during
300 // createIndependentBlocks().
Tobias Grosser44d16952012-03-02 11:27:21 +0000301 if (S.getRegion().contains(OpInst->getParent()))
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000302 return NULL;
303
304 return const_cast<Value*>(OldOperand);
305}
306
Tobias Grosser80998e72012-03-02 11:27:28 +0000307void BlockGenerator::copyInstScalar(const Instruction *Inst, ValueMapT &BBMap) {
308 Instruction *NewInst = Inst->clone();
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000309
Tobias Grosser80998e72012-03-02 11:27:28 +0000310 // Replace old operands with the new ones.
311 for (Instruction::const_op_iterator OI = Inst->op_begin(),
312 OE = Inst->op_end(); OI != OE; ++OI) {
313 Value *OldOperand = *OI;
314 Value *NewOperand = getOperand(OldOperand, BBMap);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000315
Tobias Grosser80998e72012-03-02 11:27:28 +0000316 if (!NewOperand) {
317 assert(!isa<StoreInst>(NewInst)
318 && "Store instructions are always needed!");
319 delete NewInst;
320 return;
321 }
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000322
Tobias Grosser80998e72012-03-02 11:27:28 +0000323 NewInst->replaceUsesOfWith(OldOperand, NewOperand);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000324 }
325
Tobias Grosser80998e72012-03-02 11:27:28 +0000326 Builder.Insert(NewInst);
327 BBMap[Inst] = NewInst;
328
329 if (!NewInst->getType()->isVoidTy())
330 NewInst->setName("p_" + Inst->getName());
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000331}
332
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000333std::vector <Value*> BlockGenerator::getMemoryAccessIndex(
334 __isl_keep isl_map *AccessRelation, Value *BaseAddress) {
335 assert((isl_map_dim(AccessRelation, isl_dim_out) == 1)
336 && "Only single dimensional access functions supported");
337
338 isl_pw_aff *PwAff = isl_map_dim_max(isl_map_copy(AccessRelation), 0);
Tobias Grosser642c4112012-03-02 11:27:25 +0000339 IslGenerator IslGen(Builder);
340 Value *OffsetValue = IslGen.generateIslPwAff(PwAff);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000341
342 PointerType *BaseAddressType = dyn_cast<PointerType>(
343 BaseAddress->getType());
344 Type *ArrayTy = BaseAddressType->getElementType();
345 Type *ArrayElementType = dyn_cast<ArrayType>(ArrayTy)->getElementType();
346 OffsetValue = Builder.CreateSExtOrBitCast(OffsetValue, ArrayElementType);
347
348 std::vector<Value*> IndexArray;
349 Value *NullValue = Constant::getNullValue(ArrayElementType);
350 IndexArray.push_back(NullValue);
351 IndexArray.push_back(OffsetValue);
352 return IndexArray;
353}
354
355Value *BlockGenerator::getNewAccessOperand(
356 __isl_keep isl_map *NewAccessRelation, Value *BaseAddress, const Value
357 *OldOperand, ValueMapT &BBMap) {
358 std::vector<Value*> IndexArray = getMemoryAccessIndex(NewAccessRelation,
359 BaseAddress);
360 Value *NewOperand = Builder.CreateGEP(BaseAddress, IndexArray,
361 "p_newarrayidx_");
362 return NewOperand;
363}
364
365Value *BlockGenerator::generateLocationAccessed(const Instruction *Inst,
366 const Value *Pointer,
367 ValueMapT &BBMap ) {
368 MemoryAccess &Access = Statement.getAccessFor(Inst);
369 isl_map *CurrentAccessRelation = Access.getAccessRelation();
370 isl_map *NewAccessRelation = Access.getNewAccessRelation();
371
372 assert(isl_map_has_equal_space(CurrentAccessRelation, NewAccessRelation)
373 && "Current and new access function use different spaces");
374
375 Value *NewPointer;
376
377 if (!NewAccessRelation) {
378 NewPointer = getOperand(Pointer, BBMap);
379 } else {
380 Value *BaseAddress = const_cast<Value*>(Access.getBaseAddr());
381 NewPointer = getNewAccessOperand(NewAccessRelation, BaseAddress, Pointer,
382 BBMap);
383 }
384
385 isl_map_free(CurrentAccessRelation);
386 isl_map_free(NewAccessRelation);
387 return NewPointer;
388}
389
390Value *BlockGenerator::generateScalarLoad(const LoadInst *Load,
391 ValueMapT &BBMap) {
392 const Value *Pointer = Load->getPointerOperand();
393 const Instruction *Inst = dyn_cast<Instruction>(Load);
394 Value *NewPointer = generateLocationAccessed(Inst, Pointer, BBMap);
395 Value *ScalarLoad = Builder.CreateLoad(NewPointer,
396 Load->getName() + "_p_scalar_");
397 return ScalarLoad;
398}
399
Tobias Grosser80998e72012-03-02 11:27:28 +0000400void BlockGenerator::copyInstruction(const Instruction *Inst,
401 ValueMapT &ScalarMap) {
402 // Terminator instructions control the control flow. They are explicitly
403 // expressed in the clast and do not need to be copied.
404 if (Inst->isTerminator())
405 return;
406
407 if (const LoadInst *Load = dyn_cast<LoadInst>(Inst)) {
408 ScalarMap[Load] = generateScalarLoad(Load, ScalarMap);
409 return;
410 }
411
412 copyInstScalar(Inst, ScalarMap);
413}
414
415
416void BlockGenerator::copyBB() {
417 BasicBlock *BB = Statement.getBasicBlock();
418 BasicBlock *CopyBB = SplitBlock(Builder.GetInsertBlock(),
419 Builder.GetInsertPoint(), P);
420 CopyBB->setName("polly.stmt." + BB->getName());
421 Builder.SetInsertPoint(CopyBB->begin());
422
423 ValueMapT ScalarBlockMap;
424
425 for (BasicBlock::const_iterator II = BB->begin(), IE = BB->end(); II != IE;
426 ++II)
427 copyInstruction(II, ScalarBlockMap);
428}
429
430class VectorBlockGenerator : BlockGenerator {
431public:
432 static void generate(IRBuilder<> &B, ValueMapT &ValueMap,
433 VectorValueMapT &VectorMaps, ScopStmt &Stmt,
434 __isl_keep isl_set *Domain, Pass *P) {
435 VectorBlockGenerator Generator(B, ValueMap, VectorMaps, Stmt, Domain, P);
436 Generator.copyBB();
437 }
438
439private:
440 VectorValueMapT &ValueMaps;
441
Tobias Grosser08a82382012-03-02 15:20:24 +0000442 isl_set *Domain;
443
Tobias Grosser80998e72012-03-02 11:27:28 +0000444 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,
Tobias Grosser08a82382012-03-02 15:20:24 +0000516 __isl_keep isl_set *Domain, Pass *P)
517 : BlockGenerator(B, vmap, Stmt, P), ValueMaps(vmaps), Domain(Domain) {
Tobias Grosser80998e72012-03-02 11:27:28 +0000518 assert(ValueMaps.size() > 1 && "Only one vector lane found");
Tobias Grosser08a82382012-03-02 15:20:24 +0000519 assert(Domain && "No statement domain provided");
Tobias Grosser80998e72012-03-02 11:27:28 +0000520 }
521
522Value *VectorBlockGenerator::makeVectorOperand(Value *Operand) {
523 int VectorWidth = getVectorWidth();
524 if (Operand->getType()->isVectorTy())
525 return Operand;
526
Tobias Grosserf6beec62012-03-02 15:20:21 +0000527 Value *Vector = UndefValue::get(VectorType::get(Operand->getType(), 1));
Tobias Grosser80998e72012-03-02 11:27:28 +0000528 Vector = Builder.CreateInsertElement(Vector, Operand, Builder.getInt32(0));
Tobias Grosserf6beec62012-03-02 15:20:21 +0000529 Constant *SplatVector = ConstantVector::getSplat(VectorWidth,
530 Builder.getInt32(0));
Tobias Grosser80998e72012-03-02 11:27:28 +0000531 return Builder.CreateShuffleVector(Vector, Vector, SplatVector);
532}
533
534Value *VectorBlockGenerator::getOperand(const Value *OldOperand,
535 ValueMapT &BBMap,
536 ValueMapT *VectorMap) {
537 const Instruction *OpInst = dyn_cast<Instruction>(OldOperand);
538
539 if (!OpInst)
540 return const_cast<Value*>(OldOperand);
541
542 if (VectorMap && VectorMap->count(OldOperand))
543 return (*VectorMap)[OldOperand];
544
545 return BlockGenerator::getOperand(OldOperand, BBMap);
546}
547
548Type *VectorBlockGenerator::getVectorPtrTy(const Value *Val, int Width) {
549 PointerType *PointerTy = dyn_cast<PointerType>(Val->getType());
550 assert(PointerTy && "PointerType expected");
551
552 Type *ScalarType = PointerTy->getElementType();
553 VectorType *VectorType = VectorType::get(ScalarType, Width);
554
555 return PointerType::getUnqual(VectorType);
556}
557
558Value *VectorBlockGenerator::generateStrideOneLoad(const LoadInst *Load,
559 ValueMapT &BBMap) {
560 const Value *Pointer = Load->getPointerOperand();
561 Type *VectorPtrType = getVectorPtrTy(Pointer, getVectorWidth());
562 Value *NewPointer = getOperand(Pointer, BBMap);
563 Value *VectorPtr = Builder.CreateBitCast(NewPointer, VectorPtrType,
564 "vector_ptr");
565 LoadInst *VecLoad = Builder.CreateLoad(VectorPtr,
566 Load->getName() + "_p_vec_full");
567 if (!Aligned)
568 VecLoad->setAlignment(8);
569
570 return VecLoad;
571}
572
573Value *VectorBlockGenerator::generateStrideZeroLoad(const LoadInst *Load,
574 ValueMapT &BBMap) {
575 const Value *Pointer = Load->getPointerOperand();
576 Type *VectorPtrType = getVectorPtrTy(Pointer, 1);
577 Value *NewPointer = getOperand(Pointer, BBMap);
578 Value *VectorPtr = Builder.CreateBitCast(NewPointer, VectorPtrType,
579 Load->getName() + "_p_vec_p");
580 LoadInst *ScalarLoad= Builder.CreateLoad(VectorPtr,
581 Load->getName() + "_p_splat_one");
582
583 if (!Aligned)
584 ScalarLoad->setAlignment(8);
585
586 Constant *SplatVector =
587 Constant::getNullValue(VectorType::get(Builder.getInt32Ty(),
588 getVectorWidth()));
589
590 Value *VectorLoad = Builder.CreateShuffleVector(ScalarLoad, ScalarLoad,
591 SplatVector,
592 Load->getName()
593 + "_p_splat");
594 return VectorLoad;
595}
596
597Value *VectorBlockGenerator::generateUnknownStrideLoad(const LoadInst *Load,
598 VectorValueMapT &ScalarMaps) {
599 int VectorWidth = getVectorWidth();
600 const Value *Pointer = Load->getPointerOperand();
601 VectorType *VectorType = VectorType::get(
602 dyn_cast<PointerType>(Pointer->getType())->getElementType(), VectorWidth);
603
604 Value *Vector = UndefValue::get(VectorType);
605
606 for (int i = 0; i < VectorWidth; i++) {
607 Value *NewPointer = getOperand(Pointer, ScalarMaps[i]);
608 Value *ScalarLoad = Builder.CreateLoad(NewPointer,
609 Load->getName() + "_p_scalar_");
610 Vector = Builder.CreateInsertElement(Vector, ScalarLoad,
611 Builder.getInt32(i),
612 Load->getName() + "_p_vec_");
613 }
614
615 return Vector;
616}
617
618void VectorBlockGenerator::generateLoad(const LoadInst *Load,
619 ValueMapT &VectorMap,
620 VectorValueMapT &ScalarMaps) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000621 Value *NewLoad;
622
623 MemoryAccess &Access = Statement.getAccessFor(Load);
624
Tobias Grosser08a82382012-03-02 15:20:24 +0000625 if (Access.isStrideZero(isl_set_copy(Domain)))
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000626 NewLoad = generateStrideZeroLoad(Load, ScalarMaps[0]);
Tobias Grosser08a82382012-03-02 15:20:24 +0000627 else if (Access.isStrideOne(isl_set_copy(Domain)))
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000628 NewLoad = generateStrideOneLoad(Load, ScalarMaps[0]);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000629 else
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000630 NewLoad = generateUnknownStrideLoad(Load, ScalarMaps);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000631
632 VectorMap[Load] = NewLoad;
633}
634
Tobias Grosser80998e72012-03-02 11:27:28 +0000635void VectorBlockGenerator::copyUnaryInst(const UnaryInstruction *Inst,
Tobias Grosser8b4bf8b2012-03-02 11:27:11 +0000636 ValueMapT &BBMap,
637 ValueMapT &VectorMap) {
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000638 int VectorWidth = getVectorWidth();
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000639 Value *NewOperand = getOperand(Inst->getOperand(0), BBMap, &VectorMap);
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000640 NewOperand = makeVectorOperand(NewOperand);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000641
642 assert(isa<CastInst>(Inst) && "Can not generate vector code for instruction");
643
644 const CastInst *Cast = dyn_cast<CastInst>(Inst);
645 VectorType *DestType = VectorType::get(Inst->getType(), VectorWidth);
646 VectorMap[Inst] = Builder.CreateCast(Cast->getOpcode(), NewOperand, DestType);
647}
648
Tobias Grosser80998e72012-03-02 11:27:28 +0000649void VectorBlockGenerator::copyBinaryInst(const BinaryOperator *Inst,
650 ValueMapT &BBMap,
651 ValueMapT &VectorMap) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000652 Value *OpZero = Inst->getOperand(0);
653 Value *OpOne = Inst->getOperand(1);
654
655 Value *NewOpZero, *NewOpOne;
656 NewOpZero = getOperand(OpZero, BBMap, &VectorMap);
657 NewOpOne = getOperand(OpOne, BBMap, &VectorMap);
658
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000659 NewOpZero = makeVectorOperand(NewOpZero);
660 NewOpOne = makeVectorOperand(NewOpOne);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000661
662 Value *NewInst = Builder.CreateBinOp(Inst->getOpcode(), NewOpZero,
663 NewOpOne,
664 Inst->getName() + "p_vec");
665 VectorMap[Inst] = NewInst;
666}
667
Tobias Grosser80998e72012-03-02 11:27:28 +0000668void VectorBlockGenerator::copyStore(const StoreInst *Store, ValueMapT &BBMap,
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000669 ValueMapT &VectorMap,
Tobias Grosser8927a442012-03-02 11:27:05 +0000670 VectorValueMapT &ScalarMaps) {
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000671 int VectorWidth = getVectorWidth();
672
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000673 MemoryAccess &Access = Statement.getAccessFor(Store);
674
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000675 const Value *Pointer = Store->getPointerOperand();
676 Value *Vector = getOperand(Store->getValueOperand(), BBMap, &VectorMap);
677
Tobias Grosser08a82382012-03-02 15:20:24 +0000678 if (Access.isStrideOne(isl_set_copy(Domain))) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000679 Type *VectorPtrType = getVectorPtrTy(Pointer, VectorWidth);
680 Value *NewPointer = getOperand(Pointer, BBMap, &VectorMap);
681
682 Value *VectorPtr = Builder.CreateBitCast(NewPointer, VectorPtrType,
683 "vector_ptr");
684 StoreInst *Store = Builder.CreateStore(Vector, VectorPtr);
685
686 if (!Aligned)
687 Store->setAlignment(8);
688 } else {
689 for (unsigned i = 0; i < ScalarMaps.size(); i++) {
690 Value *Scalar = Builder.CreateExtractElement(Vector,
691 Builder.getInt32(i));
692 Value *NewPointer = getOperand(Pointer, ScalarMaps[i]);
693 Builder.CreateStore(Scalar, NewPointer);
694 }
695 }
696}
697
Tobias Grosser80998e72012-03-02 11:27:28 +0000698bool VectorBlockGenerator::hasVectorOperands(const Instruction *Inst,
699 ValueMapT &VectorMap) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000700 for (Instruction::const_op_iterator OI = Inst->op_begin(),
701 OE = Inst->op_end(); OI != OE; ++OI)
702 if (VectorMap.count(*OI))
703 return true;
704 return false;
705}
706
Tobias Grosser80998e72012-03-02 11:27:28 +0000707int VectorBlockGenerator::getVectorWidth() {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000708 return ValueMaps.size();
709}
710
Tobias Grosser80998e72012-03-02 11:27:28 +0000711void VectorBlockGenerator::copyInstruction(const Instruction *Inst,
Tobias Grosser32152cb2012-03-02 11:27:18 +0000712 ValueMapT &VectorMap,
713 VectorValueMapT &ScalarMaps) {
Tobias Grosser80998e72012-03-02 11:27:28 +0000714 // Terminator instructions control the control flow. They are explicitly
715 // expressed in the clast and do not need to be copied.
716 if (Inst->isTerminator())
717 return;
718
Tobias Grosser32152cb2012-03-02 11:27:18 +0000719 if (const LoadInst *Load = dyn_cast<LoadInst>(Inst)) {
Tobias Grosser80998e72012-03-02 11:27:28 +0000720 generateLoad(Load, VectorMap, ScalarMaps);
Tobias Grosser32152cb2012-03-02 11:27:18 +0000721 return;
722 }
723
724 if (hasVectorOperands(Inst, VectorMap)) {
725 if (const StoreInst *Store = dyn_cast<StoreInst>(Inst)) {
Tobias Grosser80998e72012-03-02 11:27:28 +0000726 copyStore(Store, ScalarMaps[0], VectorMap, ScalarMaps);
Tobias Grosser32152cb2012-03-02 11:27:18 +0000727 return;
728 }
729
730 if (const UnaryInstruction *Unary = dyn_cast<UnaryInstruction>(Inst)) {
Tobias Grosser80998e72012-03-02 11:27:28 +0000731 copyUnaryInst(Unary, ScalarMaps[0], VectorMap);
Tobias Grosser32152cb2012-03-02 11:27:18 +0000732 return;
733 }
734
735 if (const BinaryOperator *Binary = dyn_cast<BinaryOperator>(Inst)) {
Tobias Grosser80998e72012-03-02 11:27:28 +0000736 copyBinaryInst(Binary, ScalarMaps[0], VectorMap);
Tobias Grosser32152cb2012-03-02 11:27:18 +0000737 return;
738 }
739
740 llvm_unreachable("Cannot issue vector code for this instruction");
741 }
742
743 for (int VectorLane = 0; VectorLane < getVectorWidth(); VectorLane++)
744 copyInstScalar(Inst, ScalarMaps[VectorLane]);
745}
746
Tobias Grosser80998e72012-03-02 11:27:28 +0000747void VectorBlockGenerator::copyBB() {
Tobias Grosser14bcbd52012-03-02 11:26:52 +0000748 BasicBlock *BB = Statement.getBasicBlock();
Tobias Grosser0ac92142012-02-14 14:02:27 +0000749 BasicBlock *CopyBB = SplitBlock(Builder.GetInsertBlock(),
750 Builder.GetInsertPoint(), P);
Tobias Grosserb61e6312012-02-15 09:58:46 +0000751 CopyBB->setName("polly.stmt." + BB->getName());
Tobias Grosser0ac92142012-02-14 14:02:27 +0000752 Builder.SetInsertPoint(CopyBB->begin());
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000753
754 // Create two maps that store the mapping from the original instructions of
755 // the old basic block to their copies in the new basic block. Those maps
756 // are basic block local.
757 //
758 // As vector code generation is supported there is one map for scalar values
759 // and one for vector values.
760 //
761 // In case we just do scalar code generation, the vectorMap is not used and
762 // the scalarMap has just one dimension, which contains the mapping.
763 //
764 // In case vector code generation is done, an instruction may either appear
765 // in the vector map once (as it is calculating >vectorwidth< values at a
766 // time. Or (if the values are calculated using scalar operations), it
767 // appears once in every dimension of the scalarMap.
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000768 VectorValueMapT ScalarBlockMap(getVectorWidth());
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000769 ValueMapT VectorBlockMap;
770
771 for (BasicBlock::const_iterator II = BB->begin(), IE = BB->end();
772 II != IE; ++II)
Tobias Grosserfc1153f2012-03-02 11:27:15 +0000773 copyInstruction(II, VectorBlockMap, ScalarBlockMap);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000774}
775
Tobias Grosser75805372011-04-29 06:27:02 +0000776/// Class to generate LLVM-IR that calculates the value of a clast_expr.
777class ClastExpCodeGen {
778 IRBuilder<> &Builder;
779 const CharMapT *IVS;
780
Tobias Grosserbb137e32012-01-24 16:42:28 +0000781 Value *codegen(const clast_name *e, Type *Ty);
782 Value *codegen(const clast_term *e, Type *Ty);
783 Value *codegen(const clast_binary *e, Type *Ty);
784 Value *codegen(const clast_reduction *r, Type *Ty);
Tobias Grosser75805372011-04-29 06:27:02 +0000785public:
786
787 // A generator for clast expressions.
788 //
789 // @param B The IRBuilder that defines where the code to calculate the
790 // clast expressions should be inserted.
791 // @param IVMAP A Map that translates strings describing the induction
792 // variables to the Values* that represent these variables
793 // on the LLVM side.
Tobias Grosserbb137e32012-01-24 16:42:28 +0000794 ClastExpCodeGen(IRBuilder<> &B, CharMapT *IVMap);
Tobias Grosser75805372011-04-29 06:27:02 +0000795
796 // Generates code to calculate a given clast expression.
797 //
798 // @param e The expression to calculate.
799 // @return The Value that holds the result.
Tobias Grosserbb137e32012-01-24 16:42:28 +0000800 Value *codegen(const clast_expr *e, Type *Ty);
Tobias Grosser75805372011-04-29 06:27:02 +0000801
802 // @brief Reset the CharMap.
803 //
804 // This function is called to reset the CharMap to new one, while generating
805 // OpenMP code.
Tobias Grosserbb137e32012-01-24 16:42:28 +0000806 void setIVS(CharMapT *IVSNew);
807};
808
809Value *ClastExpCodeGen::codegen(const clast_name *e, Type *Ty) {
810 CharMapT::const_iterator I = IVS->find(e->name);
811
812 assert(I != IVS->end() && "Clast name not found");
813
814 return Builder.CreateSExtOrBitCast(I->second, Ty);
815}
816
817Value *ClastExpCodeGen::codegen(const clast_term *e, Type *Ty) {
818 APInt a = APInt_from_MPZ(e->val);
819
820 Value *ConstOne = ConstantInt::get(Builder.getContext(), a);
821 ConstOne = Builder.CreateSExtOrBitCast(ConstOne, Ty);
822
823 if (!e->var)
824 return ConstOne;
825
826 Value *var = codegen(e->var, Ty);
827 return Builder.CreateMul(ConstOne, var);
828}
829
830Value *ClastExpCodeGen::codegen(const clast_binary *e, Type *Ty) {
831 Value *LHS = codegen(e->LHS, Ty);
832
833 APInt RHS_AP = APInt_from_MPZ(e->RHS);
834
835 Value *RHS = ConstantInt::get(Builder.getContext(), RHS_AP);
836 RHS = Builder.CreateSExtOrBitCast(RHS, Ty);
837
838 switch (e->type) {
839 case clast_bin_mod:
840 return Builder.CreateSRem(LHS, RHS);
841 case clast_bin_fdiv:
842 {
Tobias Grosser9a44b972012-02-16 14:13:19 +0000843 // floord(n,d) ((n < 0) ? (n - d + 1) : n) / d
Tobias Grosser906eafe2012-02-16 09:56:10 +0000844 Value *One = ConstantInt::get(Ty, 1);
845 Value *Zero = ConstantInt::get(Ty, 0);
Tobias Grosser9a44b972012-02-16 14:13:19 +0000846 Value *Sum1 = Builder.CreateSub(LHS, RHS);
847 Value *Sum2 = Builder.CreateAdd(Sum1, One);
848 Value *isNegative = Builder.CreateICmpSLT(LHS, Zero);
849 Value *Dividend = Builder.CreateSelect(isNegative, Sum2, LHS);
850 return Builder.CreateSDiv(Dividend, RHS);
Tobias Grosserbb137e32012-01-24 16:42:28 +0000851 }
852 case clast_bin_cdiv:
853 {
Tobias Grosser9a44b972012-02-16 14:13:19 +0000854 // ceild(n,d) ((n < 0) ? n : (n + d - 1)) / d
855 Value *One = ConstantInt::get(Ty, 1);
Tobias Grosser906eafe2012-02-16 09:56:10 +0000856 Value *Zero = ConstantInt::get(Ty, 0);
Tobias Grosser9a44b972012-02-16 14:13:19 +0000857 Value *Sum1 = Builder.CreateAdd(LHS, RHS);
858 Value *Sum2 = Builder.CreateSub(Sum1, One);
859 Value *isNegative = Builder.CreateICmpSLT(LHS, Zero);
860 Value *Dividend = Builder.CreateSelect(isNegative, LHS, Sum2);
861 return Builder.CreateSDiv(Dividend, RHS);
Tobias Grosserbb137e32012-01-24 16:42:28 +0000862 }
863 case clast_bin_div:
864 return Builder.CreateSDiv(LHS, RHS);
865 };
866
867 llvm_unreachable("Unknown clast binary expression type");
868}
869
870Value *ClastExpCodeGen::codegen(const clast_reduction *r, Type *Ty) {
871 assert(( r->type == clast_red_min
872 || r->type == clast_red_max
873 || r->type == clast_red_sum)
874 && "Clast reduction type not supported");
875 Value *old = codegen(r->elts[0], Ty);
876
877 for (int i=1; i < r->n; ++i) {
878 Value *exprValue = codegen(r->elts[i], Ty);
879
880 switch (r->type) {
881 case clast_red_min:
882 {
883 Value *cmp = Builder.CreateICmpSLT(old, exprValue);
884 old = Builder.CreateSelect(cmp, old, exprValue);
885 break;
886 }
887 case clast_red_max:
888 {
889 Value *cmp = Builder.CreateICmpSGT(old, exprValue);
890 old = Builder.CreateSelect(cmp, old, exprValue);
891 break;
892 }
893 case clast_red_sum:
894 old = Builder.CreateAdd(old, exprValue);
895 break;
Tobias Grosserbb137e32012-01-24 16:42:28 +0000896 }
Tobias Grosser75805372011-04-29 06:27:02 +0000897 }
898
Tobias Grosserbb137e32012-01-24 16:42:28 +0000899 return old;
900}
901
902ClastExpCodeGen::ClastExpCodeGen(IRBuilder<> &B, CharMapT *IVMap)
903 : Builder(B), IVS(IVMap) {}
904
905Value *ClastExpCodeGen::codegen(const clast_expr *e, Type *Ty) {
906 switch(e->type) {
907 case clast_expr_name:
908 return codegen((const clast_name *)e, Ty);
909 case clast_expr_term:
910 return codegen((const clast_term *)e, Ty);
911 case clast_expr_bin:
912 return codegen((const clast_binary *)e, Ty);
913 case clast_expr_red:
914 return codegen((const clast_reduction *)e, Ty);
915 }
916
917 llvm_unreachable("Unknown clast expression!");
918}
919
920void ClastExpCodeGen::setIVS(CharMapT *IVSNew) {
921 IVS = IVSNew;
922}
Tobias Grosser75805372011-04-29 06:27:02 +0000923
924class ClastStmtCodeGen {
925 // The Scop we code generate.
926 Scop *S;
927 ScalarEvolution &SE;
Tobias Grosser75805372011-04-29 06:27:02 +0000928 DominatorTree *DT;
Hongbin Zheng94c5df12011-05-06 02:38:20 +0000929 ScopDetection *SD;
Tobias Grosser75805372011-04-29 06:27:02 +0000930 Dependences *DP;
931 TargetData *TD;
Tobias Grosser0ac92142012-02-14 14:02:27 +0000932 Pass *P;
Tobias Grosser75805372011-04-29 06:27:02 +0000933
934 // The Builder specifies the current location to code generate at.
935 IRBuilder<> &Builder;
936
937 // Map the Values from the old code to their counterparts in the new code.
938 ValueMapT ValueMap;
939
940 // clastVars maps from the textual representation of a clast variable to its
941 // current *Value. clast variables are scheduling variables, original
942 // induction variables or parameters. They are used either in loop bounds or
943 // to define the statement instance that is executed.
944 //
945 // for (s = 0; s < n + 3; ++i)
946 // for (t = s; t < m; ++j)
947 // Stmt(i = s + 3 * m, j = t);
948 //
949 // {s,t,i,j,n,m} is the set of clast variables in this clast.
950 CharMapT *clastVars;
951
952 // Codegenerator for clast expressions.
953 ClastExpCodeGen ExpGen;
954
955 // Do we currently generate parallel code?
956 bool parallelCodeGeneration;
957
958 std::vector<std::string> parallelLoops;
959
960public:
961
Tobias Grosser9bc5eb082012-01-24 16:42:32 +0000962 const std::vector<std::string> &getParallelLoops();
Tobias Grosser75805372011-04-29 06:27:02 +0000963
964 protected:
Tobias Grosser9bc5eb082012-01-24 16:42:32 +0000965 void codegen(const clast_assignment *a);
Tobias Grosser75805372011-04-29 06:27:02 +0000966
967 void codegen(const clast_assignment *a, ScopStmt *Statement,
968 unsigned Dimension, int vectorDim,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +0000969 std::vector<ValueMapT> *VectorVMap = 0);
Tobias Grosser75805372011-04-29 06:27:02 +0000970
971 void codegenSubstitutions(const clast_stmt *Assignment,
972 ScopStmt *Statement, int vectorDim = 0,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +0000973 std::vector<ValueMapT> *VectorVMap = 0);
Tobias Grosser75805372011-04-29 06:27:02 +0000974
975 void codegen(const clast_user_stmt *u, std::vector<Value*> *IVS = NULL,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +0000976 const char *iterator = NULL, isl_set *scatteringDomain = 0);
Tobias Grosser75805372011-04-29 06:27:02 +0000977
Tobias Grosser9bc5eb082012-01-24 16:42:32 +0000978 void codegen(const clast_block *b);
Tobias Grosser75805372011-04-29 06:27:02 +0000979
980 /// @brief Create a classical sequential loop.
Tobias Grosser545bc312011-12-06 10:48:27 +0000981 void codegenForSequential(const clast_for *f, Value *LowerBound = 0,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +0000982 Value *UpperBound = 0);
Tobias Grosser75805372011-04-29 06:27:02 +0000983
Tobias Grosser75805372011-04-29 06:27:02 +0000984 /// @brief Add a new definition of an openmp subfunction.
Tobias Grosser9bc5eb082012-01-24 16:42:32 +0000985 Function *addOpenMPSubfunction(Module *M);
Tobias Grosser75805372011-04-29 06:27:02 +0000986
987 /// @brief Add values to the OpenMP structure.
988 ///
989 /// Create the subfunction structure and add the values from the list.
990 Value *addValuesToOpenMPStruct(SetVector<Value*> OMPDataVals,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +0000991 Function *SubFunction);
Tobias Grosser75805372011-04-29 06:27:02 +0000992
993 /// @brief Create OpenMP structure values.
994 ///
995 /// Create a list of values that has to be stored into the subfuncition
996 /// structure.
Tobias Grosser9bc5eb082012-01-24 16:42:32 +0000997 SetVector<Value*> createOpenMPStructValues();
Tobias Grosser75805372011-04-29 06:27:02 +0000998
999 /// @brief Extract the values from the subfunction parameter.
1000 ///
1001 /// Extract the values from the subfunction parameter and update the clast
1002 /// variables to point to the new values.
1003 void extractValuesFromOpenMPStruct(CharMapT *clastVarsOMP,
1004 SetVector<Value*> OMPDataVals,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001005 Value *userContext);
Tobias Grosser75805372011-04-29 06:27:02 +00001006
1007 /// @brief Add body to the subfunction.
1008 void addOpenMPSubfunctionBody(Function *FN, const clast_for *f,
1009 Value *structData,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001010 SetVector<Value*> OMPDataVals);
Tobias Grosser75805372011-04-29 06:27:02 +00001011
1012 /// @brief Create an OpenMP parallel for loop.
1013 ///
1014 /// This loop reflects a loop as if it would have been created by an OpenMP
1015 /// statement.
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001016 void codegenForOpenMP(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +00001017
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001018 bool isInnermostLoop(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +00001019
1020 /// @brief Get the number of loop iterations for this loop.
1021 /// @param f The clast for loop to check.
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001022 int getNumberOfIterations(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +00001023
1024 /// @brief Create vector instructions for this loop.
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001025 void codegenForVector(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +00001026
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001027 void codegen(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +00001028
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001029 Value *codegen(const clast_equation *eq);
Tobias Grosser75805372011-04-29 06:27:02 +00001030
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001031 void codegen(const clast_guard *g);
Tobias Grosser75805372011-04-29 06:27:02 +00001032
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001033 void codegen(const clast_stmt *stmt);
Tobias Grosser75805372011-04-29 06:27:02 +00001034
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001035 void addParameters(const CloogNames *names);
Tobias Grosser75805372011-04-29 06:27:02 +00001036
1037 public:
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001038 void codegen(const clast_root *r);
Tobias Grosser75805372011-04-29 06:27:02 +00001039
1040 ClastStmtCodeGen(Scop *scop, ScalarEvolution &se, DominatorTree *dt,
Hongbin Zheng94c5df12011-05-06 02:38:20 +00001041 ScopDetection *sd, Dependences *dp, TargetData *td,
Tobias Grosser0ac92142012-02-14 14:02:27 +00001042 IRBuilder<> &B, Pass *P);
Tobias Grosser75805372011-04-29 06:27:02 +00001043};
1044}
1045
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001046const std::vector<std::string> &ClastStmtCodeGen::getParallelLoops() {
1047 return parallelLoops;
1048}
1049
1050void ClastStmtCodeGen::codegen(const clast_assignment *a) {
1051 Value *V= ExpGen.codegen(a->RHS, TD->getIntPtrType(Builder.getContext()));
1052 (*clastVars)[a->LHS] = V;
1053}
1054
1055void ClastStmtCodeGen::codegen(const clast_assignment *a, ScopStmt *Statement,
1056 unsigned Dimension, int vectorDim,
1057 std::vector<ValueMapT> *VectorVMap) {
1058 Value *RHS = ExpGen.codegen(a->RHS,
1059 TD->getIntPtrType(Builder.getContext()));
1060
1061 assert(!a->LHS && "Statement assignments do not have left hand side");
1062 const PHINode *PN;
1063 PN = Statement->getInductionVariableForDimension(Dimension);
1064 const Value *V = PN;
1065
1066 if (VectorVMap)
1067 (*VectorVMap)[vectorDim][V] = RHS;
1068
1069 ValueMap[V] = RHS;
1070}
1071
1072void ClastStmtCodeGen::codegenSubstitutions(const clast_stmt *Assignment,
1073 ScopStmt *Statement, int vectorDim,
1074 std::vector<ValueMapT> *VectorVMap) {
1075 int Dimension = 0;
1076
1077 while (Assignment) {
1078 assert(CLAST_STMT_IS_A(Assignment, stmt_ass)
1079 && "Substitions are expected to be assignments");
1080 codegen((const clast_assignment *)Assignment, Statement, Dimension,
1081 vectorDim, VectorVMap);
1082 Assignment = Assignment->next;
1083 Dimension++;
1084 }
1085}
1086
1087void ClastStmtCodeGen::codegen(const clast_user_stmt *u,
1088 std::vector<Value*> *IVS , const char *iterator,
Tobias Grosser14bcbd52012-03-02 11:26:52 +00001089 isl_set *Domain) {
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001090 ScopStmt *Statement = (ScopStmt *)u->statement->usr;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001091
1092 if (u->substitutions)
1093 codegenSubstitutions(u->substitutions, Statement);
1094
Tobias Grosser80998e72012-03-02 11:27:28 +00001095 int VectorDimensions = IVS ? IVS->size() : 1;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001096
Tobias Grosser80998e72012-03-02 11:27:28 +00001097 if (VectorDimensions == 1) {
Tobias Grosser08a82382012-03-02 15:20:24 +00001098 BlockGenerator::generate(Builder, ValueMap, *Statement, P);
Tobias Grosser80998e72012-03-02 11:27:28 +00001099 return;
1100 }
1101
1102 VectorValueMapT VectorMap(VectorDimensions);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001103
1104 if (IVS) {
1105 assert (u->substitutions && "Substitutions expected!");
1106 int i = 0;
1107 for (std::vector<Value*>::iterator II = IVS->begin(), IE = IVS->end();
1108 II != IE; ++II) {
1109 (*clastVars)[iterator] = *II;
Tobias Grosser14bcbd52012-03-02 11:26:52 +00001110 codegenSubstitutions(u->substitutions, Statement, i, &VectorMap);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001111 i++;
1112 }
1113 }
1114
Tobias Grosser80998e72012-03-02 11:27:28 +00001115 VectorBlockGenerator::generate(Builder, ValueMap, VectorMap, *Statement,
1116 Domain, P);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001117}
1118
1119void ClastStmtCodeGen::codegen(const clast_block *b) {
1120 if (b->body)
1121 codegen(b->body);
1122}
1123
1124void ClastStmtCodeGen::codegenForSequential(const clast_for *f,
1125 Value *LowerBound,
1126 Value *UpperBound) {
1127 APInt Stride;
Tobias Grosser0ac92142012-02-14 14:02:27 +00001128 BasicBlock *AfterBB;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001129 Type *IntPtrTy;
1130
1131 Stride = APInt_from_MPZ(f->stride);
1132 IntPtrTy = TD->getIntPtrType(Builder.getContext());
1133
1134 // The value of lowerbound and upperbound will be supplied, if this
1135 // function is called while generating OpenMP code. Otherwise get
1136 // the values.
1137 assert(!!LowerBound == !!UpperBound && "Either give both bounds or none");
1138
1139 if (LowerBound == 0) {
1140 LowerBound = ExpGen.codegen(f->LB, IntPtrTy);
1141 UpperBound = ExpGen.codegen(f->UB, IntPtrTy);
1142 }
1143
Tobias Grosser0ac92142012-02-14 14:02:27 +00001144 Value *IV = createLoop(&Builder, LowerBound, UpperBound, Stride, DT, P,
1145 &AfterBB);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001146
1147 // Add loop iv to symbols.
1148 (*clastVars)[f->iterator] = IV;
1149
1150 if (f->body)
1151 codegen(f->body);
1152
1153 // Loop is finished, so remove its iv from the live symbols.
1154 clastVars->erase(f->iterator);
Tobias Grosser0ac92142012-02-14 14:02:27 +00001155 Builder.SetInsertPoint(AfterBB->begin());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001156}
1157
1158Function *ClastStmtCodeGen::addOpenMPSubfunction(Module *M) {
1159 Function *F = Builder.GetInsertBlock()->getParent();
1160 std::vector<Type*> Arguments(1, Builder.getInt8PtrTy());
1161 FunctionType *FT = FunctionType::get(Builder.getVoidTy(), Arguments, false);
1162 Function *FN = Function::Create(FT, Function::InternalLinkage,
1163 F->getName() + ".omp_subfn", M);
1164 // Do not run any polly pass on the new function.
1165 SD->markFunctionAsInvalid(FN);
1166
1167 Function::arg_iterator AI = FN->arg_begin();
1168 AI->setName("omp.userContext");
1169
1170 return FN;
1171}
1172
1173Value *ClastStmtCodeGen::addValuesToOpenMPStruct(SetVector<Value*> OMPDataVals,
1174 Function *SubFunction) {
1175 std::vector<Type*> structMembers;
1176
1177 // Create the structure.
1178 for (unsigned i = 0; i < OMPDataVals.size(); i++)
1179 structMembers.push_back(OMPDataVals[i]->getType());
1180
1181 StructType *structTy = StructType::get(Builder.getContext(),
1182 structMembers);
1183 // Store the values into the structure.
1184 Value *structData = Builder.CreateAlloca(structTy, 0, "omp.userContext");
1185 for (unsigned i = 0; i < OMPDataVals.size(); i++) {
1186 Value *storeAddr = Builder.CreateStructGEP(structData, i);
1187 Builder.CreateStore(OMPDataVals[i], storeAddr);
1188 }
1189
1190 return structData;
1191}
1192
1193SetVector<Value*> ClastStmtCodeGen::createOpenMPStructValues() {
1194 SetVector<Value*> OMPDataVals;
1195
1196 // Push the clast variables available in the clastVars.
1197 for (CharMapT::iterator I = clastVars->begin(), E = clastVars->end();
1198 I != E; I++)
1199 OMPDataVals.insert(I->second);
1200
1201 // Push the base addresses of memory references.
1202 for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI) {
1203 ScopStmt *Stmt = *SI;
1204 for (SmallVector<MemoryAccess*, 8>::iterator I = Stmt->memacc_begin(),
1205 E = Stmt->memacc_end(); I != E; ++I) {
1206 Value *BaseAddr = const_cast<Value*>((*I)->getBaseAddr());
1207 OMPDataVals.insert((BaseAddr));
1208 }
1209 }
1210
1211 return OMPDataVals;
1212}
1213
1214void ClastStmtCodeGen::extractValuesFromOpenMPStruct(CharMapT *clastVarsOMP,
1215 SetVector<Value*> OMPDataVals, Value *userContext) {
1216 // Extract the clast variables.
1217 unsigned i = 0;
1218 for (CharMapT::iterator I = clastVars->begin(), E = clastVars->end();
1219 I != E; I++) {
1220 Value *loadAddr = Builder.CreateStructGEP(userContext, i);
1221 (*clastVarsOMP)[I->first] = Builder.CreateLoad(loadAddr);
1222 i++;
1223 }
1224
1225 // Extract the base addresses of memory references.
1226 for (unsigned j = i; j < OMPDataVals.size(); j++) {
1227 Value *loadAddr = Builder.CreateStructGEP(userContext, j);
1228 Value *baseAddr = OMPDataVals[j];
1229 ValueMap[baseAddr] = Builder.CreateLoad(loadAddr);
1230 }
1231}
1232
1233void ClastStmtCodeGen::addOpenMPSubfunctionBody(Function *FN,
1234 const clast_for *f,
1235 Value *structData,
1236 SetVector<Value*> OMPDataVals) {
1237 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
1238 LLVMContext &Context = FN->getContext();
1239 IntegerType *intPtrTy = TD->getIntPtrType(Context);
1240
1241 // Store the previous basic block.
Tobias Grosser0ac92142012-02-14 14:02:27 +00001242 BasicBlock::iterator PrevInsertPoint = Builder.GetInsertPoint();
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001243 BasicBlock *PrevBB = Builder.GetInsertBlock();
1244
1245 // Create basic blocks.
1246 BasicBlock *HeaderBB = BasicBlock::Create(Context, "omp.setup", FN);
1247 BasicBlock *ExitBB = BasicBlock::Create(Context, "omp.exit", FN);
1248 BasicBlock *checkNextBB = BasicBlock::Create(Context, "omp.checkNext", FN);
1249 BasicBlock *loadIVBoundsBB = BasicBlock::Create(Context, "omp.loadIVBounds",
1250 FN);
1251
1252 DT->addNewBlock(HeaderBB, PrevBB);
1253 DT->addNewBlock(ExitBB, HeaderBB);
1254 DT->addNewBlock(checkNextBB, HeaderBB);
1255 DT->addNewBlock(loadIVBoundsBB, HeaderBB);
1256
1257 // Fill up basic block HeaderBB.
1258 Builder.SetInsertPoint(HeaderBB);
1259 Value *lowerBoundPtr = Builder.CreateAlloca(intPtrTy, 0,
1260 "omp.lowerBoundPtr");
1261 Value *upperBoundPtr = Builder.CreateAlloca(intPtrTy, 0,
1262 "omp.upperBoundPtr");
1263 Value *userContext = Builder.CreateBitCast(FN->arg_begin(),
1264 structData->getType(),
1265 "omp.userContext");
1266
1267 CharMapT clastVarsOMP;
1268 extractValuesFromOpenMPStruct(&clastVarsOMP, OMPDataVals, userContext);
1269
1270 Builder.CreateBr(checkNextBB);
1271
1272 // Add code to check if another set of iterations will be executed.
1273 Builder.SetInsertPoint(checkNextBB);
1274 Function *runtimeNextFunction = M->getFunction("GOMP_loop_runtime_next");
1275 Value *ret1 = Builder.CreateCall2(runtimeNextFunction,
1276 lowerBoundPtr, upperBoundPtr);
1277 Value *hasNextSchedule = Builder.CreateTrunc(ret1, Builder.getInt1Ty(),
1278 "omp.hasNextScheduleBlock");
1279 Builder.CreateCondBr(hasNextSchedule, loadIVBoundsBB, ExitBB);
1280
1281 // Add code to to load the iv bounds for this set of iterations.
1282 Builder.SetInsertPoint(loadIVBoundsBB);
1283 Value *lowerBound = Builder.CreateLoad(lowerBoundPtr, "omp.lowerBound");
1284 Value *upperBound = Builder.CreateLoad(upperBoundPtr, "omp.upperBound");
1285
1286 // Subtract one as the upper bound provided by openmp is a < comparison
1287 // whereas the codegenForSequential function creates a <= comparison.
1288 upperBound = Builder.CreateSub(upperBound, ConstantInt::get(intPtrTy, 1),
1289 "omp.upperBoundAdjusted");
1290
1291 // Use clastVarsOMP during code generation of the OpenMP subfunction.
1292 CharMapT *oldClastVars = clastVars;
1293 clastVars = &clastVarsOMP;
1294 ExpGen.setIVS(&clastVarsOMP);
1295
Tobias Grosser0ac92142012-02-14 14:02:27 +00001296 Builder.CreateBr(checkNextBB);
1297 Builder.SetInsertPoint(--Builder.GetInsertPoint());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001298 codegenForSequential(f, lowerBound, upperBound);
1299
1300 // Restore the old clastVars.
1301 clastVars = oldClastVars;
1302 ExpGen.setIVS(oldClastVars);
1303
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001304 // Add code to terminate this openmp subfunction.
1305 Builder.SetInsertPoint(ExitBB);
1306 Function *endnowaitFunction = M->getFunction("GOMP_loop_end_nowait");
1307 Builder.CreateCall(endnowaitFunction);
1308 Builder.CreateRetVoid();
1309
Tobias Grosser0ac92142012-02-14 14:02:27 +00001310 // Restore the previous insert point.
1311 Builder.SetInsertPoint(PrevInsertPoint);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001312}
1313
Tobias Grosser415245d2012-03-02 15:20:17 +00001314void ClastStmtCodeGen::codegenForOpenMP(const clast_for *For) {
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001315 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
Tobias Grosser415245d2012-03-02 15:20:17 +00001316 IntegerType *IntPtrTy = TD->getIntPtrType(Builder.getContext());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001317
1318 Function *SubFunction = addOpenMPSubfunction(M);
1319 SetVector<Value*> OMPDataVals = createOpenMPStructValues();
Tobias Grosser415245d2012-03-02 15:20:17 +00001320 Value *StructData = addValuesToOpenMPStruct(OMPDataVals, SubFunction);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001321
Tobias Grosser415245d2012-03-02 15:20:17 +00001322 addOpenMPSubfunctionBody(SubFunction, For, StructData, OMPDataVals);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001323
1324 // Create call for GOMP_parallel_loop_runtime_start.
Tobias Grosser415245d2012-03-02 15:20:17 +00001325 Value *SubfunctionParam = Builder.CreateBitCast(StructData,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001326 Builder.getInt8PtrTy(),
1327 "omp_data");
1328
Tobias Grosser415245d2012-03-02 15:20:17 +00001329 Value *NumberOfThreads = Builder.getInt32(0);
1330 Value *LowerBound = ExpGen.codegen(For->LB, IntPtrTy);
1331 Value *UpperBound = ExpGen.codegen(For->UB, IntPtrTy);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001332
1333 // Add one as the upper bound provided by openmp is a < comparison
1334 // whereas the codegenForSequential function creates a <= comparison.
Tobias Grosser415245d2012-03-02 15:20:17 +00001335 UpperBound = Builder.CreateAdd(UpperBound, ConstantInt::get(IntPtrTy, 1));
1336 APInt APStride = APInt_from_MPZ(For->stride);
1337 Value *Stride = ConstantInt::get(IntPtrTy,
1338 APStride.zext(IntPtrTy->getBitWidth()));
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001339
Tobias Grosser415245d2012-03-02 15:20:17 +00001340 Value *Arguments[] = { SubFunction, SubfunctionParam, NumberOfThreads,
1341 LowerBound, UpperBound, Stride};
1342 Builder.CreateCall(M->getFunction("GOMP_parallel_loop_runtime_start"),
1343 Arguments);
1344 Builder.CreateCall(SubFunction, SubfunctionParam);
1345 Builder.CreateCall(M->getFunction("GOMP_parallel_end"));
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001346}
1347
1348bool ClastStmtCodeGen::isInnermostLoop(const clast_for *f) {
1349 const clast_stmt *stmt = f->body;
1350
1351 while (stmt) {
1352 if (!CLAST_STMT_IS_A(stmt, stmt_user))
1353 return false;
1354
1355 stmt = stmt->next;
1356 }
1357
1358 return true;
1359}
1360
1361int ClastStmtCodeGen::getNumberOfIterations(const clast_for *f) {
1362 isl_set *loopDomain = isl_set_copy(isl_set_from_cloog_domain(f->domain));
1363 isl_set *tmp = isl_set_copy(loopDomain);
1364
1365 // Calculate a map similar to the identity map, but with the last input
1366 // and output dimension not related.
1367 // [i0, i1, i2, i3] -> [i0, i1, i2, o0]
1368 isl_space *Space = isl_set_get_space(loopDomain);
1369 Space = isl_space_drop_outputs(Space,
1370 isl_set_dim(loopDomain, isl_dim_set) - 2, 1);
1371 Space = isl_space_map_from_set(Space);
1372 isl_map *identity = isl_map_identity(Space);
1373 identity = isl_map_add_dims(identity, isl_dim_in, 1);
1374 identity = isl_map_add_dims(identity, isl_dim_out, 1);
1375
1376 isl_map *map = isl_map_from_domain_and_range(tmp, loopDomain);
1377 map = isl_map_intersect(map, identity);
1378
1379 isl_map *lexmax = isl_map_lexmax(isl_map_copy(map));
1380 isl_map *lexmin = isl_map_lexmin(map);
1381 isl_map *sub = isl_map_sum(lexmax, isl_map_neg(lexmin));
1382
1383 isl_set *elements = isl_map_range(sub);
1384
1385 if (!isl_set_is_singleton(elements)) {
1386 isl_set_free(elements);
1387 return -1;
1388 }
1389
1390 isl_point *p = isl_set_sample_point(elements);
1391
1392 isl_int v;
1393 isl_int_init(v);
1394 isl_point_get_coordinate(p, isl_dim_set, isl_set_n_dim(loopDomain) - 1, &v);
1395 int numberIterations = isl_int_get_si(v);
1396 isl_int_clear(v);
1397 isl_point_free(p);
1398
1399 return (numberIterations) / isl_int_get_si(f->stride) + 1;
1400}
1401
1402void ClastStmtCodeGen::codegenForVector(const clast_for *f) {
1403 DEBUG(dbgs() << "Vectorizing loop '" << f->iterator << "'\n";);
1404 int vectorWidth = getNumberOfIterations(f);
1405
1406 Value *LB = ExpGen.codegen(f->LB,
1407 TD->getIntPtrType(Builder.getContext()));
1408
1409 APInt Stride = APInt_from_MPZ(f->stride);
1410 IntegerType *LoopIVType = dyn_cast<IntegerType>(LB->getType());
1411 Stride = Stride.zext(LoopIVType->getBitWidth());
1412 Value *StrideValue = ConstantInt::get(LoopIVType, Stride);
1413
1414 std::vector<Value*> IVS(vectorWidth);
1415 IVS[0] = LB;
1416
1417 for (int i = 1; i < vectorWidth; i++)
1418 IVS[i] = Builder.CreateAdd(IVS[i-1], StrideValue, "p_vector_iv");
1419
1420 isl_set *scatteringDomain =
1421 isl_set_copy(isl_set_from_cloog_domain(f->domain));
1422
1423 // Add loop iv to symbols.
1424 (*clastVars)[f->iterator] = LB;
1425
1426 const clast_stmt *stmt = f->body;
1427
1428 while (stmt) {
1429 codegen((const clast_user_stmt *)stmt, &IVS, f->iterator,
1430 scatteringDomain);
1431 stmt = stmt->next;
1432 }
1433
1434 // Loop is finished, so remove its iv from the live symbols.
1435 isl_set_free(scatteringDomain);
1436 clastVars->erase(f->iterator);
1437}
1438
1439void ClastStmtCodeGen::codegen(const clast_for *f) {
Tobias Grosserce3f5372012-03-02 11:26:42 +00001440 if ((Vector || OpenMP) && DP->isParallelFor(f)) {
1441 if (Vector && isInnermostLoop(f) && (-1 != getNumberOfIterations(f))
1442 && (getNumberOfIterations(f) <= 16)) {
1443 codegenForVector(f);
1444 return;
1445 }
1446
1447 if (OpenMP && !parallelCodeGeneration) {
1448 parallelCodeGeneration = true;
1449 parallelLoops.push_back(f->iterator);
1450 codegenForOpenMP(f);
1451 parallelCodeGeneration = false;
1452 return;
1453 }
1454 }
1455
1456 codegenForSequential(f);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001457}
1458
1459Value *ClastStmtCodeGen::codegen(const clast_equation *eq) {
1460 Value *LHS = ExpGen.codegen(eq->LHS,
1461 TD->getIntPtrType(Builder.getContext()));
1462 Value *RHS = ExpGen.codegen(eq->RHS,
1463 TD->getIntPtrType(Builder.getContext()));
1464 CmpInst::Predicate P;
1465
1466 if (eq->sign == 0)
1467 P = ICmpInst::ICMP_EQ;
1468 else if (eq->sign > 0)
1469 P = ICmpInst::ICMP_SGE;
1470 else
1471 P = ICmpInst::ICMP_SLE;
1472
1473 return Builder.CreateICmp(P, LHS, RHS);
1474}
1475
1476void ClastStmtCodeGen::codegen(const clast_guard *g) {
1477 Function *F = Builder.GetInsertBlock()->getParent();
1478 LLVMContext &Context = F->getContext();
Tobias Grosser0ac92142012-02-14 14:02:27 +00001479
1480 BasicBlock *CondBB = SplitBlock(Builder.GetInsertBlock(),
1481 Builder.GetInsertPoint(), P);
1482 CondBB->setName("polly.cond");
1483 BasicBlock *MergeBB = SplitBlock(CondBB, CondBB->begin(), P);
1484 MergeBB->setName("polly.merge");
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001485 BasicBlock *ThenBB = BasicBlock::Create(Context, "polly.then", F);
Tobias Grosser0ac92142012-02-14 14:02:27 +00001486
1487 DT->addNewBlock(ThenBB, CondBB);
1488 DT->changeImmediateDominator(MergeBB, CondBB);
1489
1490 CondBB->getTerminator()->eraseFromParent();
1491
1492 Builder.SetInsertPoint(CondBB);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001493
1494 Value *Predicate = codegen(&(g->eq[0]));
1495
1496 for (int i = 1; i < g->n; ++i) {
1497 Value *TmpPredicate = codegen(&(g->eq[i]));
1498 Predicate = Builder.CreateAnd(Predicate, TmpPredicate);
1499 }
1500
1501 Builder.CreateCondBr(Predicate, ThenBB, MergeBB);
1502 Builder.SetInsertPoint(ThenBB);
Tobias Grosser0ac92142012-02-14 14:02:27 +00001503 Builder.CreateBr(MergeBB);
1504 Builder.SetInsertPoint(ThenBB->begin());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001505
1506 codegen(g->then);
Tobias Grosser62a3c962012-02-16 09:56:21 +00001507
1508 Builder.SetInsertPoint(MergeBB->begin());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001509}
1510
1511void ClastStmtCodeGen::codegen(const clast_stmt *stmt) {
1512 if (CLAST_STMT_IS_A(stmt, stmt_root))
1513 assert(false && "No second root statement expected");
1514 else if (CLAST_STMT_IS_A(stmt, stmt_ass))
1515 codegen((const clast_assignment *)stmt);
1516 else if (CLAST_STMT_IS_A(stmt, stmt_user))
1517 codegen((const clast_user_stmt *)stmt);
1518 else if (CLAST_STMT_IS_A(stmt, stmt_block))
1519 codegen((const clast_block *)stmt);
1520 else if (CLAST_STMT_IS_A(stmt, stmt_for))
1521 codegen((const clast_for *)stmt);
1522 else if (CLAST_STMT_IS_A(stmt, stmt_guard))
1523 codegen((const clast_guard *)stmt);
1524
1525 if (stmt->next)
1526 codegen(stmt->next);
1527}
1528
1529void ClastStmtCodeGen::addParameters(const CloogNames *names) {
1530 SCEVExpander Rewriter(SE, "polly");
1531
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001532 int i = 0;
1533 for (Scop::param_iterator PI = S->param_begin(), PE = S->param_end();
1534 PI != PE; ++PI) {
1535 assert(i < names->nb_parameters && "Not enough parameter names");
1536
1537 const SCEV *Param = *PI;
1538 Type *Ty = Param->getType();
1539
1540 Instruction *insertLocation = --(Builder.GetInsertBlock()->end());
1541 Value *V = Rewriter.expandCodeFor(Param, Ty, insertLocation);
1542 (*clastVars)[names->parameters[i]] = V;
1543
1544 ++i;
1545 }
1546}
1547
1548void ClastStmtCodeGen::codegen(const clast_root *r) {
1549 clastVars = new CharMapT();
1550 addParameters(r->names);
1551 ExpGen.setIVS(clastVars);
1552
1553 parallelCodeGeneration = false;
1554
1555 const clast_stmt *stmt = (const clast_stmt*) r;
1556 if (stmt->next)
1557 codegen(stmt->next);
1558
1559 delete clastVars;
1560}
1561
1562ClastStmtCodeGen::ClastStmtCodeGen(Scop *scop, ScalarEvolution &se,
1563 DominatorTree *dt, ScopDetection *sd,
1564 Dependences *dp, TargetData *td,
Tobias Grosser0ac92142012-02-14 14:02:27 +00001565 IRBuilder<> &B, Pass *P) :
1566 S(scop), SE(se), DT(dt), SD(sd), DP(dp), TD(td), P(P), Builder(B),
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001567 ExpGen(Builder, NULL) {}
1568
Tobias Grosser75805372011-04-29 06:27:02 +00001569namespace {
1570class CodeGeneration : public ScopPass {
1571 Region *region;
1572 Scop *S;
1573 DominatorTree *DT;
1574 ScalarEvolution *SE;
1575 ScopDetection *SD;
Tobias Grosser75805372011-04-29 06:27:02 +00001576 TargetData *TD;
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001577 RegionInfo *RI;
Tobias Grosser75805372011-04-29 06:27:02 +00001578
1579 std::vector<std::string> parallelLoops;
1580
1581 public:
1582 static char ID;
1583
1584 CodeGeneration() : ScopPass(ID) {}
1585
Tobias Grosserb1c95992012-02-12 12:09:27 +00001586 // Add the declarations needed by the OpenMP function calls that we insert in
1587 // OpenMP mode.
1588 void addOpenMPDeclarations(Module *M)
Tobias Grosser75805372011-04-29 06:27:02 +00001589 {
Tobias Grosserd855cc52012-02-12 12:09:32 +00001590 IRBuilder<> Builder(M->getContext());
1591 IntegerType *LongTy = TD->getIntPtrType(M->getContext());
1592
1593 llvm::GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
Tobias Grosser75805372011-04-29 06:27:02 +00001594
1595 if (!M->getFunction("GOMP_parallel_end")) {
Tobias Grosserd855cc52012-02-12 12:09:32 +00001596 FunctionType *Ty = FunctionType::get(Builder.getVoidTy(), false);
1597 Function::Create(Ty, Linkage, "GOMP_parallel_end", M);
Tobias Grosser75805372011-04-29 06:27:02 +00001598 }
1599
1600 if (!M->getFunction("GOMP_parallel_loop_runtime_start")) {
Tobias Grosserd855cc52012-02-12 12:09:32 +00001601 Type *Params[] = {
1602 PointerType::getUnqual(FunctionType::get(Builder.getVoidTy(),
1603 Builder.getInt8PtrTy(),
1604 false)),
1605 Builder.getInt8PtrTy(),
1606 Builder.getInt32Ty(),
1607 LongTy,
1608 LongTy,
1609 LongTy,
1610 };
Tobias Grosser75805372011-04-29 06:27:02 +00001611
Tobias Grosserd855cc52012-02-12 12:09:32 +00001612 FunctionType *Ty = FunctionType::get(Builder.getVoidTy(), Params, false);
1613 Function::Create(Ty, Linkage, "GOMP_parallel_loop_runtime_start", M);
Tobias Grosser75805372011-04-29 06:27:02 +00001614 }
1615
1616 if (!M->getFunction("GOMP_loop_runtime_next")) {
Tobias Grosserd855cc52012-02-12 12:09:32 +00001617 PointerType *LongPtrTy = PointerType::getUnqual(LongTy);
1618 Type *Params[] = {
1619 LongPtrTy,
1620 LongPtrTy,
1621 };
Tobias Grosser75805372011-04-29 06:27:02 +00001622
Tobias Grosserd855cc52012-02-12 12:09:32 +00001623 FunctionType *Ty = FunctionType::get(Builder.getInt8Ty(), Params, false);
1624 Function::Create(Ty, Linkage, "GOMP_loop_runtime_next", M);
Tobias Grosser75805372011-04-29 06:27:02 +00001625 }
1626
1627 if (!M->getFunction("GOMP_loop_end_nowait")) {
Tobias Grosserd855cc52012-02-12 12:09:32 +00001628 FunctionType *Ty = FunctionType::get(Builder.getVoidTy(), false);
1629 Function::Create(Ty, Linkage, "GOMP_loop_end_nowait", M);
Tobias Grosser75805372011-04-29 06:27:02 +00001630 }
1631 }
1632
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001633 // Split the entry edge of the region and generate a new basic block on this
1634 // edge. This function also updates ScopInfo and RegionInfo.
1635 //
1636 // @param region The region where the entry edge will be splitted.
1637 BasicBlock *splitEdgeAdvanced(Region *region) {
1638 BasicBlock *newBlock;
1639 BasicBlock *splitBlock;
1640
1641 newBlock = SplitEdge(region->getEnteringBlock(), region->getEntry(), this);
1642
1643 if (DT->dominates(region->getEntry(), newBlock)) {
Tobias Grossercb47dfe2012-02-15 09:58:50 +00001644 BasicBlock *OldBlock = region->getEntry();
1645 std::string OldName = OldBlock->getName();
1646
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001647 // Update ScopInfo.
1648 for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI)
Tobias Grosserf12cea42012-02-15 09:58:53 +00001649 if ((*SI)->getBasicBlock() == OldBlock) {
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001650 (*SI)->setBasicBlock(newBlock);
1651 break;
1652 }
1653
1654 // Update RegionInfo.
Tobias Grossercb47dfe2012-02-15 09:58:50 +00001655 splitBlock = OldBlock;
1656 OldBlock->setName("polly.split");
1657 newBlock->setName(OldName);
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001658 region->replaceEntry(newBlock);
Tobias Grosser7a16c892011-05-14 19:01:55 +00001659 RI->setRegionFor(newBlock, region);
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001660 } else {
1661 RI->setRegionFor(newBlock, region->getParent());
1662 splitBlock = newBlock;
1663 }
1664
1665 return splitBlock;
1666 }
1667
1668 // Create a split block that branches either to the old code or to a new basic
1669 // block where the new code can be inserted.
1670 //
Tobias Grosserbd608a82012-02-12 12:09:41 +00001671 // @param Builder A builder that will be set to point to a basic block, where
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001672 // the new code can be generated.
1673 // @return The split basic block.
Tobias Grosserbd608a82012-02-12 12:09:41 +00001674 BasicBlock *addSplitAndStartBlock(IRBuilder<> *Builder) {
1675 BasicBlock *StartBlock, *SplitBlock;
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001676
Tobias Grosserbd608a82012-02-12 12:09:41 +00001677 SplitBlock = splitEdgeAdvanced(region);
1678 SplitBlock->setName("polly.split_new_and_old");
1679 Function *F = SplitBlock->getParent();
1680 StartBlock = BasicBlock::Create(F->getContext(), "polly.start", F);
1681 SplitBlock->getTerminator()->eraseFromParent();
1682 Builder->SetInsertPoint(SplitBlock);
1683 Builder->CreateCondBr(Builder->getTrue(), StartBlock, region->getEntry());
1684 DT->addNewBlock(StartBlock, SplitBlock);
1685 Builder->SetInsertPoint(StartBlock);
1686 return SplitBlock;
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001687 }
1688
1689 // Merge the control flow of the newly generated code with the existing code.
1690 //
Tobias Grosserbd608a82012-02-12 12:09:41 +00001691 // @param SplitBlock The basic block where the control flow was split between
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001692 // old and new version of the Scop.
Tobias Grosserbd608a82012-02-12 12:09:41 +00001693 // @param Builder An IRBuilder that points to the last instruction of the
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001694 // newly generated code.
Tobias Grosserbd608a82012-02-12 12:09:41 +00001695 void mergeControlFlow(BasicBlock *SplitBlock, IRBuilder<> *Builder) {
1696 BasicBlock *MergeBlock;
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001697 Region *R = region;
1698
1699 if (R->getExit()->getSinglePredecessor())
1700 // No splitEdge required. A block with a single predecessor cannot have
1701 // PHI nodes that would complicate life.
Tobias Grosserbd608a82012-02-12 12:09:41 +00001702 MergeBlock = R->getExit();
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001703 else {
Tobias Grosserbd608a82012-02-12 12:09:41 +00001704 MergeBlock = SplitEdge(R->getExitingBlock(), R->getExit(), this);
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001705 // SplitEdge will never split R->getExit(), as R->getExit() has more than
1706 // one predecessor. Hence, mergeBlock is always a newly generated block.
Tobias Grosserbd608a82012-02-12 12:09:41 +00001707 R->replaceExit(MergeBlock);
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001708 }
1709
Tobias Grosserbd608a82012-02-12 12:09:41 +00001710 Builder->CreateBr(MergeBlock);
Tobias Grosser8518bbe2012-02-12 12:09:46 +00001711 MergeBlock->setName("polly.merge_new_and_old");
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001712
Tobias Grosserbd608a82012-02-12 12:09:41 +00001713 if (DT->dominates(SplitBlock, MergeBlock))
1714 DT->changeImmediateDominator(MergeBlock, SplitBlock);
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001715 }
1716
Tobias Grosser75805372011-04-29 06:27:02 +00001717 bool runOnScop(Scop &scop) {
1718 S = &scop;
1719 region = &S->getRegion();
Tobias Grosser75805372011-04-29 06:27:02 +00001720 DT = &getAnalysis<DominatorTree>();
1721 Dependences *DP = &getAnalysis<Dependences>();
1722 SE = &getAnalysis<ScalarEvolution>();
Tobias Grosser75805372011-04-29 06:27:02 +00001723 SD = &getAnalysis<ScopDetection>();
1724 TD = &getAnalysis<TargetData>();
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001725 RI = &getAnalysis<RegionInfo>();
Tobias Grosser75805372011-04-29 06:27:02 +00001726
1727 parallelLoops.clear();
1728
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001729 assert(region->isSimple() && "Only simple regions are supported");
Tobias Grosser76d7c522011-05-14 19:01:37 +00001730
Tobias Grosserb1c95992012-02-12 12:09:27 +00001731 Module *M = region->getEntry()->getParent()->getParent();
1732
Tobias Grosserd855cc52012-02-12 12:09:32 +00001733 if (OpenMP) addOpenMPDeclarations(M);
Tobias Grosserb1c95992012-02-12 12:09:27 +00001734
Tobias Grosser5772e652012-02-01 14:23:33 +00001735 // In the CFG the optimized code of the SCoP is generated next to the
1736 // original code. Both the new and the original version of the code remain
1737 // in the CFG. A branch statement decides which version is executed.
1738 // For now, we always execute the new version (the old one is dead code
1739 // eliminated by the cleanup passes). In the future we may decide to execute
1740 // the new version only if certain run time checks succeed. This will be
1741 // useful to support constructs for which we cannot prove all assumptions at
1742 // compile time.
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001743 //
1744 // Before transformation:
1745 //
1746 // bb0
1747 // |
1748 // orig_scop
1749 // |
1750 // bb1
1751 //
1752 // After transformation:
1753 // bb0
1754 // |
1755 // polly.splitBlock
Tobias Grosser2bd3af12011-08-01 22:39:00 +00001756 // / \.
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001757 // | startBlock
1758 // | |
1759 // orig_scop new_scop
1760 // \ /
1761 // \ /
1762 // bb1 (joinBlock)
1763 IRBuilder<> builder(region->getEntry());
Tobias Grosser75805372011-04-29 06:27:02 +00001764
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001765 // The builder will be set to startBlock.
1766 BasicBlock *splitBlock = addSplitAndStartBlock(&builder);
Tobias Grosser0ac92142012-02-14 14:02:27 +00001767 BasicBlock *StartBlock = builder.GetInsertBlock();
Tobias Grosser75805372011-04-29 06:27:02 +00001768
Tobias Grosser0ac92142012-02-14 14:02:27 +00001769 mergeControlFlow(splitBlock, &builder);
1770 builder.SetInsertPoint(StartBlock->begin());
1771
1772 ClastStmtCodeGen CodeGen(S, *SE, DT, SD, DP, TD, builder, this);
Tobias Grosser3fdecae2011-05-14 19:02:39 +00001773 CloogInfo &C = getAnalysis<CloogInfo>();
1774 CodeGen.codegen(C.getClast());
Tobias Grosser75805372011-04-29 06:27:02 +00001775
Tobias Grosser75805372011-04-29 06:27:02 +00001776 parallelLoops.insert(parallelLoops.begin(),
1777 CodeGen.getParallelLoops().begin(),
1778 CodeGen.getParallelLoops().end());
1779
Tobias Grosserabb6dcd2011-05-14 19:02:34 +00001780 return true;
Tobias Grosser75805372011-04-29 06:27:02 +00001781 }
1782
1783 virtual void printScop(raw_ostream &OS) const {
1784 for (std::vector<std::string>::const_iterator PI = parallelLoops.begin(),
1785 PE = parallelLoops.end(); PI != PE; ++PI)
1786 OS << "Parallel loop with iterator '" << *PI << "' generated\n";
1787 }
1788
1789 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
1790 AU.addRequired<CloogInfo>();
1791 AU.addRequired<Dependences>();
1792 AU.addRequired<DominatorTree>();
Tobias Grosser75805372011-04-29 06:27:02 +00001793 AU.addRequired<RegionInfo>();
Tobias Grosser73600b82011-10-08 00:30:40 +00001794 AU.addRequired<ScalarEvolution>();
Tobias Grosser75805372011-04-29 06:27:02 +00001795 AU.addRequired<ScopDetection>();
1796 AU.addRequired<ScopInfo>();
1797 AU.addRequired<TargetData>();
1798
1799 AU.addPreserved<CloogInfo>();
1800 AU.addPreserved<Dependences>();
Tobias Grosser5d6eb862011-05-14 19:02:45 +00001801
Tobias Grosser4e3f9a42011-05-23 15:23:36 +00001802 // FIXME: We do not create LoopInfo for the newly generated loops.
Tobias Grosser75805372011-04-29 06:27:02 +00001803 AU.addPreserved<LoopInfo>();
1804 AU.addPreserved<DominatorTree>();
Tobias Grosser75805372011-04-29 06:27:02 +00001805 AU.addPreserved<ScopDetection>();
1806 AU.addPreserved<ScalarEvolution>();
Tobias Grosser5d6eb862011-05-14 19:02:45 +00001807
Tobias Grosser4e3f9a42011-05-23 15:23:36 +00001808 // FIXME: We do not yet add regions for the newly generated code to the
1809 // region tree.
Tobias Grosser75805372011-04-29 06:27:02 +00001810 AU.addPreserved<RegionInfo>();
1811 AU.addPreserved<TempScopInfo>();
1812 AU.addPreserved<ScopInfo>();
1813 AU.addPreservedID(IndependentBlocksID);
1814 }
1815};
1816}
1817
1818char CodeGeneration::ID = 1;
1819
Tobias Grosser73600b82011-10-08 00:30:40 +00001820INITIALIZE_PASS_BEGIN(CodeGeneration, "polly-codegen",
1821 "Polly - Create LLVM-IR form SCoPs", false, false)
1822INITIALIZE_PASS_DEPENDENCY(CloogInfo)
1823INITIALIZE_PASS_DEPENDENCY(Dependences)
1824INITIALIZE_PASS_DEPENDENCY(DominatorTree)
1825INITIALIZE_PASS_DEPENDENCY(RegionInfo)
1826INITIALIZE_PASS_DEPENDENCY(ScalarEvolution)
1827INITIALIZE_PASS_DEPENDENCY(ScopDetection)
1828INITIALIZE_PASS_DEPENDENCY(TargetData)
1829INITIALIZE_PASS_END(CodeGeneration, "polly-codegen",
1830 "Polly - Create LLVM-IR form SCoPs", false, false)
Tobias Grosser75805372011-04-29 06:27:02 +00001831
Tobias Grosser7ffe4e82011-11-17 12:56:10 +00001832Pass *polly::createCodeGenerationPass() {
Tobias Grosser75805372011-04-29 06:27:02 +00001833 return new CodeGeneration();
1834}