blob: 758b05f6ea137686dce797b23c33fd4b7ebfff86 [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
Tobias Grosser80998e72012-03-02 11:27:28 +0000492 void generateLoad(const LoadInst *Load, ValueMapT &VectorMap,
493 VectorValueMapT &ScalarMaps);
494
495 void copyUnaryInst(const UnaryInstruction *Inst, ValueMapT &BBMap,
Tobias Grosser260e86d2012-03-02 15:20:28 +0000496 ValueMapT &VectorMap);
Tobias Grosser80998e72012-03-02 11:27:28 +0000497
498 void copyBinaryInst(const BinaryOperator *Inst, ValueMapT &BBMap,
Tobias Grosser260e86d2012-03-02 15:20:28 +0000499 ValueMapT &VectorMap);
Tobias Grosser80998e72012-03-02 11:27:28 +0000500
Tobias Grosser260e86d2012-03-02 15:20:28 +0000501 void copyStore(const StoreInst *Store, ValueMapT &BBMap, ValueMapT &VectorMap,
502 VectorValueMapT &ScalarMaps);
Tobias Grosser80998e72012-03-02 11:27:28 +0000503
504 bool hasVectorOperands(const Instruction *Inst, ValueMapT &VectorMap);
505
506 void copyInstruction(const Instruction *Inst, ValueMapT &VectorMap,
507 VectorValueMapT &ScalarMaps);
508
509 // Insert a copy of a basic block in the newly generated code.
510 void copyBB();
511};
512
513VectorBlockGenerator::VectorBlockGenerator(IRBuilder<> &B, ValueMapT &vmap,
514 VectorValueMapT &vmaps, ScopStmt &Stmt,
Tobias Grosser08a82382012-03-02 15:20:24 +0000515 __isl_keep isl_set *Domain, Pass *P)
516 : BlockGenerator(B, vmap, Stmt, P), ValueMaps(vmaps), Domain(Domain) {
Tobias Grosser80998e72012-03-02 11:27:28 +0000517 assert(ValueMaps.size() > 1 && "Only one vector lane found");
Tobias Grosser08a82382012-03-02 15:20:24 +0000518 assert(Domain && "No statement domain provided");
Tobias Grosser80998e72012-03-02 11:27:28 +0000519 }
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
Tobias Grosser08a82382012-03-02 15:20:24 +0000624 if (Access.isStrideZero(isl_set_copy(Domain)))
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000625 NewLoad = generateStrideZeroLoad(Load, ScalarMaps[0]);
Tobias Grosser08a82382012-03-02 15:20:24 +0000626 else if (Access.isStrideOne(isl_set_copy(Domain)))
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000627 NewLoad = generateStrideOneLoad(Load, ScalarMaps[0]);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000628 else
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000629 NewLoad = generateUnknownStrideLoad(Load, ScalarMaps);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000630
631 VectorMap[Load] = NewLoad;
632}
633
Tobias Grosser80998e72012-03-02 11:27:28 +0000634void VectorBlockGenerator::copyUnaryInst(const UnaryInstruction *Inst,
Tobias Grosser8b4bf8b2012-03-02 11:27:11 +0000635 ValueMapT &BBMap,
636 ValueMapT &VectorMap) {
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000637 int VectorWidth = getVectorWidth();
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000638 Value *NewOperand = getOperand(Inst->getOperand(0), BBMap, &VectorMap);
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000639 NewOperand = makeVectorOperand(NewOperand);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000640
641 assert(isa<CastInst>(Inst) && "Can not generate vector code for instruction");
642
643 const CastInst *Cast = dyn_cast<CastInst>(Inst);
644 VectorType *DestType = VectorType::get(Inst->getType(), VectorWidth);
645 VectorMap[Inst] = Builder.CreateCast(Cast->getOpcode(), NewOperand, DestType);
646}
647
Tobias Grosser80998e72012-03-02 11:27:28 +0000648void VectorBlockGenerator::copyBinaryInst(const BinaryOperator *Inst,
649 ValueMapT &BBMap,
650 ValueMapT &VectorMap) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000651 Value *OpZero = Inst->getOperand(0);
652 Value *OpOne = Inst->getOperand(1);
653
654 Value *NewOpZero, *NewOpOne;
655 NewOpZero = getOperand(OpZero, BBMap, &VectorMap);
656 NewOpOne = getOperand(OpOne, BBMap, &VectorMap);
657
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000658 NewOpZero = makeVectorOperand(NewOpZero);
659 NewOpOne = makeVectorOperand(NewOpOne);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000660
661 Value *NewInst = Builder.CreateBinOp(Inst->getOpcode(), NewOpZero,
662 NewOpOne,
663 Inst->getName() + "p_vec");
664 VectorMap[Inst] = NewInst;
665}
666
Tobias Grosser80998e72012-03-02 11:27:28 +0000667void VectorBlockGenerator::copyStore(const StoreInst *Store, ValueMapT &BBMap,
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000668 ValueMapT &VectorMap,
Tobias Grosser8927a442012-03-02 11:27:05 +0000669 VectorValueMapT &ScalarMaps) {
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000670 int VectorWidth = getVectorWidth();
671
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000672 MemoryAccess &Access = Statement.getAccessFor(Store);
673
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000674 const Value *Pointer = Store->getPointerOperand();
675 Value *Vector = getOperand(Store->getValueOperand(), BBMap, &VectorMap);
676
Tobias Grosser08a82382012-03-02 15:20:24 +0000677 if (Access.isStrideOne(isl_set_copy(Domain))) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000678 Type *VectorPtrType = getVectorPtrTy(Pointer, VectorWidth);
679 Value *NewPointer = getOperand(Pointer, BBMap, &VectorMap);
680
681 Value *VectorPtr = Builder.CreateBitCast(NewPointer, VectorPtrType,
682 "vector_ptr");
683 StoreInst *Store = Builder.CreateStore(Vector, VectorPtr);
684
685 if (!Aligned)
686 Store->setAlignment(8);
687 } else {
688 for (unsigned i = 0; i < ScalarMaps.size(); i++) {
689 Value *Scalar = Builder.CreateExtractElement(Vector,
690 Builder.getInt32(i));
691 Value *NewPointer = getOperand(Pointer, ScalarMaps[i]);
692 Builder.CreateStore(Scalar, NewPointer);
693 }
694 }
695}
696
Tobias Grosser80998e72012-03-02 11:27:28 +0000697bool VectorBlockGenerator::hasVectorOperands(const Instruction *Inst,
698 ValueMapT &VectorMap) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000699 for (Instruction::const_op_iterator OI = Inst->op_begin(),
700 OE = Inst->op_end(); OI != OE; ++OI)
701 if (VectorMap.count(*OI))
702 return true;
703 return false;
704}
705
Tobias Grosser80998e72012-03-02 11:27:28 +0000706int VectorBlockGenerator::getVectorWidth() {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000707 return ValueMaps.size();
708}
709
Tobias Grosser80998e72012-03-02 11:27:28 +0000710void VectorBlockGenerator::copyInstruction(const Instruction *Inst,
Tobias Grosser32152cb2012-03-02 11:27:18 +0000711 ValueMapT &VectorMap,
712 VectorValueMapT &ScalarMaps) {
Tobias Grosser80998e72012-03-02 11:27:28 +0000713 // Terminator instructions control the control flow. They are explicitly
714 // expressed in the clast and do not need to be copied.
715 if (Inst->isTerminator())
716 return;
717
Tobias Grosser32152cb2012-03-02 11:27:18 +0000718 if (const LoadInst *Load = dyn_cast<LoadInst>(Inst)) {
Tobias Grosser80998e72012-03-02 11:27:28 +0000719 generateLoad(Load, VectorMap, ScalarMaps);
Tobias Grosser32152cb2012-03-02 11:27:18 +0000720 return;
721 }
722
723 if (hasVectorOperands(Inst, VectorMap)) {
724 if (const StoreInst *Store = dyn_cast<StoreInst>(Inst)) {
Tobias Grosser80998e72012-03-02 11:27:28 +0000725 copyStore(Store, ScalarMaps[0], VectorMap, ScalarMaps);
Tobias Grosser32152cb2012-03-02 11:27:18 +0000726 return;
727 }
728
729 if (const UnaryInstruction *Unary = dyn_cast<UnaryInstruction>(Inst)) {
Tobias Grosser80998e72012-03-02 11:27:28 +0000730 copyUnaryInst(Unary, ScalarMaps[0], VectorMap);
Tobias Grosser32152cb2012-03-02 11:27:18 +0000731 return;
732 }
733
734 if (const BinaryOperator *Binary = dyn_cast<BinaryOperator>(Inst)) {
Tobias Grosser80998e72012-03-02 11:27:28 +0000735 copyBinaryInst(Binary, ScalarMaps[0], VectorMap);
Tobias Grosser32152cb2012-03-02 11:27:18 +0000736 return;
737 }
738
739 llvm_unreachable("Cannot issue vector code for this instruction");
740 }
741
742 for (int VectorLane = 0; VectorLane < getVectorWidth(); VectorLane++)
743 copyInstScalar(Inst, ScalarMaps[VectorLane]);
744}
745
Tobias Grosser80998e72012-03-02 11:27:28 +0000746void VectorBlockGenerator::copyBB() {
Tobias Grosser14bcbd52012-03-02 11:26:52 +0000747 BasicBlock *BB = Statement.getBasicBlock();
Tobias Grosser0ac92142012-02-14 14:02:27 +0000748 BasicBlock *CopyBB = SplitBlock(Builder.GetInsertBlock(),
749 Builder.GetInsertPoint(), P);
Tobias Grosserb61e6312012-02-15 09:58:46 +0000750 CopyBB->setName("polly.stmt." + BB->getName());
Tobias Grosser0ac92142012-02-14 14:02:27 +0000751 Builder.SetInsertPoint(CopyBB->begin());
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000752
753 // Create two maps that store the mapping from the original instructions of
754 // the old basic block to their copies in the new basic block. Those maps
755 // are basic block local.
756 //
757 // As vector code generation is supported there is one map for scalar values
758 // and one for vector values.
759 //
760 // In case we just do scalar code generation, the vectorMap is not used and
761 // the scalarMap has just one dimension, which contains the mapping.
762 //
763 // In case vector code generation is done, an instruction may either appear
764 // in the vector map once (as it is calculating >vectorwidth< values at a
765 // time. Or (if the values are calculated using scalar operations), it
766 // appears once in every dimension of the scalarMap.
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000767 VectorValueMapT ScalarBlockMap(getVectorWidth());
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000768 ValueMapT VectorBlockMap;
769
770 for (BasicBlock::const_iterator II = BB->begin(), IE = BB->end();
771 II != IE; ++II)
Tobias Grosserfc1153f2012-03-02 11:27:15 +0000772 copyInstruction(II, VectorBlockMap, ScalarBlockMap);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000773}
774
Tobias Grosser75805372011-04-29 06:27:02 +0000775/// Class to generate LLVM-IR that calculates the value of a clast_expr.
776class ClastExpCodeGen {
777 IRBuilder<> &Builder;
778 const CharMapT *IVS;
779
Tobias Grosserbb137e32012-01-24 16:42:28 +0000780 Value *codegen(const clast_name *e, Type *Ty);
781 Value *codegen(const clast_term *e, Type *Ty);
782 Value *codegen(const clast_binary *e, Type *Ty);
783 Value *codegen(const clast_reduction *r, Type *Ty);
Tobias Grosser75805372011-04-29 06:27:02 +0000784public:
785
786 // A generator for clast expressions.
787 //
788 // @param B The IRBuilder that defines where the code to calculate the
789 // clast expressions should be inserted.
790 // @param IVMAP A Map that translates strings describing the induction
791 // variables to the Values* that represent these variables
792 // on the LLVM side.
Tobias Grosserbb137e32012-01-24 16:42:28 +0000793 ClastExpCodeGen(IRBuilder<> &B, CharMapT *IVMap);
Tobias Grosser75805372011-04-29 06:27:02 +0000794
795 // Generates code to calculate a given clast expression.
796 //
797 // @param e The expression to calculate.
798 // @return The Value that holds the result.
Tobias Grosserbb137e32012-01-24 16:42:28 +0000799 Value *codegen(const clast_expr *e, Type *Ty);
Tobias Grosser75805372011-04-29 06:27:02 +0000800
801 // @brief Reset the CharMap.
802 //
803 // This function is called to reset the CharMap to new one, while generating
804 // OpenMP code.
Tobias Grosserbb137e32012-01-24 16:42:28 +0000805 void setIVS(CharMapT *IVSNew);
806};
807
808Value *ClastExpCodeGen::codegen(const clast_name *e, Type *Ty) {
809 CharMapT::const_iterator I = IVS->find(e->name);
810
811 assert(I != IVS->end() && "Clast name not found");
812
813 return Builder.CreateSExtOrBitCast(I->second, Ty);
814}
815
816Value *ClastExpCodeGen::codegen(const clast_term *e, Type *Ty) {
817 APInt a = APInt_from_MPZ(e->val);
818
819 Value *ConstOne = ConstantInt::get(Builder.getContext(), a);
820 ConstOne = Builder.CreateSExtOrBitCast(ConstOne, Ty);
821
822 if (!e->var)
823 return ConstOne;
824
825 Value *var = codegen(e->var, Ty);
826 return Builder.CreateMul(ConstOne, var);
827}
828
829Value *ClastExpCodeGen::codegen(const clast_binary *e, Type *Ty) {
830 Value *LHS = codegen(e->LHS, Ty);
831
832 APInt RHS_AP = APInt_from_MPZ(e->RHS);
833
834 Value *RHS = ConstantInt::get(Builder.getContext(), RHS_AP);
835 RHS = Builder.CreateSExtOrBitCast(RHS, Ty);
836
837 switch (e->type) {
838 case clast_bin_mod:
839 return Builder.CreateSRem(LHS, RHS);
840 case clast_bin_fdiv:
841 {
Tobias Grosser9a44b972012-02-16 14:13:19 +0000842 // floord(n,d) ((n < 0) ? (n - d + 1) : n) / d
Tobias Grosser906eafe2012-02-16 09:56:10 +0000843 Value *One = ConstantInt::get(Ty, 1);
844 Value *Zero = ConstantInt::get(Ty, 0);
Tobias Grosser9a44b972012-02-16 14:13:19 +0000845 Value *Sum1 = Builder.CreateSub(LHS, RHS);
846 Value *Sum2 = Builder.CreateAdd(Sum1, One);
847 Value *isNegative = Builder.CreateICmpSLT(LHS, Zero);
848 Value *Dividend = Builder.CreateSelect(isNegative, Sum2, LHS);
849 return Builder.CreateSDiv(Dividend, RHS);
Tobias Grosserbb137e32012-01-24 16:42:28 +0000850 }
851 case clast_bin_cdiv:
852 {
Tobias Grosser9a44b972012-02-16 14:13:19 +0000853 // ceild(n,d) ((n < 0) ? n : (n + d - 1)) / d
854 Value *One = ConstantInt::get(Ty, 1);
Tobias Grosser906eafe2012-02-16 09:56:10 +0000855 Value *Zero = ConstantInt::get(Ty, 0);
Tobias Grosser9a44b972012-02-16 14:13:19 +0000856 Value *Sum1 = Builder.CreateAdd(LHS, RHS);
857 Value *Sum2 = Builder.CreateSub(Sum1, One);
858 Value *isNegative = Builder.CreateICmpSLT(LHS, Zero);
859 Value *Dividend = Builder.CreateSelect(isNegative, LHS, Sum2);
860 return Builder.CreateSDiv(Dividend, RHS);
Tobias Grosserbb137e32012-01-24 16:42:28 +0000861 }
862 case clast_bin_div:
863 return Builder.CreateSDiv(LHS, RHS);
864 };
865
866 llvm_unreachable("Unknown clast binary expression type");
867}
868
869Value *ClastExpCodeGen::codegen(const clast_reduction *r, Type *Ty) {
870 assert(( r->type == clast_red_min
871 || r->type == clast_red_max
872 || r->type == clast_red_sum)
873 && "Clast reduction type not supported");
874 Value *old = codegen(r->elts[0], Ty);
875
876 for (int i=1; i < r->n; ++i) {
877 Value *exprValue = codegen(r->elts[i], Ty);
878
879 switch (r->type) {
880 case clast_red_min:
881 {
882 Value *cmp = Builder.CreateICmpSLT(old, exprValue);
883 old = Builder.CreateSelect(cmp, old, exprValue);
884 break;
885 }
886 case clast_red_max:
887 {
888 Value *cmp = Builder.CreateICmpSGT(old, exprValue);
889 old = Builder.CreateSelect(cmp, old, exprValue);
890 break;
891 }
892 case clast_red_sum:
893 old = Builder.CreateAdd(old, exprValue);
894 break;
Tobias Grosserbb137e32012-01-24 16:42:28 +0000895 }
Tobias Grosser75805372011-04-29 06:27:02 +0000896 }
897
Tobias Grosserbb137e32012-01-24 16:42:28 +0000898 return old;
899}
900
901ClastExpCodeGen::ClastExpCodeGen(IRBuilder<> &B, CharMapT *IVMap)
902 : Builder(B), IVS(IVMap) {}
903
904Value *ClastExpCodeGen::codegen(const clast_expr *e, Type *Ty) {
905 switch(e->type) {
906 case clast_expr_name:
907 return codegen((const clast_name *)e, Ty);
908 case clast_expr_term:
909 return codegen((const clast_term *)e, Ty);
910 case clast_expr_bin:
911 return codegen((const clast_binary *)e, Ty);
912 case clast_expr_red:
913 return codegen((const clast_reduction *)e, Ty);
914 }
915
916 llvm_unreachable("Unknown clast expression!");
917}
918
919void ClastExpCodeGen::setIVS(CharMapT *IVSNew) {
920 IVS = IVSNew;
921}
Tobias Grosser75805372011-04-29 06:27:02 +0000922
923class ClastStmtCodeGen {
924 // The Scop we code generate.
925 Scop *S;
926 ScalarEvolution &SE;
Tobias Grosser75805372011-04-29 06:27:02 +0000927 DominatorTree *DT;
Hongbin Zheng94c5df12011-05-06 02:38:20 +0000928 ScopDetection *SD;
Tobias Grosser75805372011-04-29 06:27:02 +0000929 Dependences *DP;
930 TargetData *TD;
Tobias Grosser0ac92142012-02-14 14:02:27 +0000931 Pass *P;
Tobias Grosser75805372011-04-29 06:27:02 +0000932
933 // The Builder specifies the current location to code generate at.
934 IRBuilder<> &Builder;
935
936 // Map the Values from the old code to their counterparts in the new code.
937 ValueMapT ValueMap;
938
939 // clastVars maps from the textual representation of a clast variable to its
940 // current *Value. clast variables are scheduling variables, original
941 // induction variables or parameters. They are used either in loop bounds or
942 // to define the statement instance that is executed.
943 //
944 // for (s = 0; s < n + 3; ++i)
945 // for (t = s; t < m; ++j)
946 // Stmt(i = s + 3 * m, j = t);
947 //
948 // {s,t,i,j,n,m} is the set of clast variables in this clast.
949 CharMapT *clastVars;
950
951 // Codegenerator for clast expressions.
952 ClastExpCodeGen ExpGen;
953
954 // Do we currently generate parallel code?
955 bool parallelCodeGeneration;
956
957 std::vector<std::string> parallelLoops;
958
959public:
960
Tobias Grosser9bc5eb082012-01-24 16:42:32 +0000961 const std::vector<std::string> &getParallelLoops();
Tobias Grosser75805372011-04-29 06:27:02 +0000962
963 protected:
Tobias Grosser9bc5eb082012-01-24 16:42:32 +0000964 void codegen(const clast_assignment *a);
Tobias Grosser75805372011-04-29 06:27:02 +0000965
966 void codegen(const clast_assignment *a, ScopStmt *Statement,
967 unsigned Dimension, int vectorDim,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +0000968 std::vector<ValueMapT> *VectorVMap = 0);
Tobias Grosser75805372011-04-29 06:27:02 +0000969
970 void codegenSubstitutions(const clast_stmt *Assignment,
971 ScopStmt *Statement, int vectorDim = 0,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +0000972 std::vector<ValueMapT> *VectorVMap = 0);
Tobias Grosser75805372011-04-29 06:27:02 +0000973
974 void codegen(const clast_user_stmt *u, std::vector<Value*> *IVS = NULL,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +0000975 const char *iterator = NULL, isl_set *scatteringDomain = 0);
Tobias Grosser75805372011-04-29 06:27:02 +0000976
Tobias Grosser9bc5eb082012-01-24 16:42:32 +0000977 void codegen(const clast_block *b);
Tobias Grosser75805372011-04-29 06:27:02 +0000978
979 /// @brief Create a classical sequential loop.
Tobias Grosser545bc312011-12-06 10:48:27 +0000980 void codegenForSequential(const clast_for *f, Value *LowerBound = 0,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +0000981 Value *UpperBound = 0);
Tobias Grosser75805372011-04-29 06:27:02 +0000982
Tobias Grosser75805372011-04-29 06:27:02 +0000983 /// @brief Add a new definition of an openmp subfunction.
Tobias Grosser9bc5eb082012-01-24 16:42:32 +0000984 Function *addOpenMPSubfunction(Module *M);
Tobias Grosser75805372011-04-29 06:27:02 +0000985
986 /// @brief Add values to the OpenMP structure.
987 ///
988 /// Create the subfunction structure and add the values from the list.
989 Value *addValuesToOpenMPStruct(SetVector<Value*> OMPDataVals,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +0000990 Function *SubFunction);
Tobias Grosser75805372011-04-29 06:27:02 +0000991
992 /// @brief Create OpenMP structure values.
993 ///
994 /// Create a list of values that has to be stored into the subfuncition
995 /// structure.
Tobias Grosser9bc5eb082012-01-24 16:42:32 +0000996 SetVector<Value*> createOpenMPStructValues();
Tobias Grosser75805372011-04-29 06:27:02 +0000997
998 /// @brief Extract the values from the subfunction parameter.
999 ///
1000 /// Extract the values from the subfunction parameter and update the clast
1001 /// variables to point to the new values.
1002 void extractValuesFromOpenMPStruct(CharMapT *clastVarsOMP,
1003 SetVector<Value*> OMPDataVals,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001004 Value *userContext);
Tobias Grosser75805372011-04-29 06:27:02 +00001005
1006 /// @brief Add body to the subfunction.
1007 void addOpenMPSubfunctionBody(Function *FN, const clast_for *f,
1008 Value *structData,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001009 SetVector<Value*> OMPDataVals);
Tobias Grosser75805372011-04-29 06:27:02 +00001010
1011 /// @brief Create an OpenMP parallel for loop.
1012 ///
1013 /// This loop reflects a loop as if it would have been created by an OpenMP
1014 /// statement.
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001015 void codegenForOpenMP(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +00001016
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001017 bool isInnermostLoop(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +00001018
1019 /// @brief Get the number of loop iterations for this loop.
1020 /// @param f The clast for loop to check.
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001021 int getNumberOfIterations(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +00001022
1023 /// @brief Create vector instructions for this loop.
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001024 void codegenForVector(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +00001025
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001026 void codegen(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +00001027
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001028 Value *codegen(const clast_equation *eq);
Tobias Grosser75805372011-04-29 06:27:02 +00001029
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001030 void codegen(const clast_guard *g);
Tobias Grosser75805372011-04-29 06:27:02 +00001031
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001032 void codegen(const clast_stmt *stmt);
Tobias Grosser75805372011-04-29 06:27:02 +00001033
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001034 void addParameters(const CloogNames *names);
Tobias Grosser75805372011-04-29 06:27:02 +00001035
1036 public:
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001037 void codegen(const clast_root *r);
Tobias Grosser75805372011-04-29 06:27:02 +00001038
1039 ClastStmtCodeGen(Scop *scop, ScalarEvolution &se, DominatorTree *dt,
Hongbin Zheng94c5df12011-05-06 02:38:20 +00001040 ScopDetection *sd, Dependences *dp, TargetData *td,
Tobias Grosser0ac92142012-02-14 14:02:27 +00001041 IRBuilder<> &B, Pass *P);
Tobias Grosser75805372011-04-29 06:27:02 +00001042};
1043}
1044
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001045const std::vector<std::string> &ClastStmtCodeGen::getParallelLoops() {
1046 return parallelLoops;
1047}
1048
1049void ClastStmtCodeGen::codegen(const clast_assignment *a) {
1050 Value *V= ExpGen.codegen(a->RHS, TD->getIntPtrType(Builder.getContext()));
1051 (*clastVars)[a->LHS] = V;
1052}
1053
1054void ClastStmtCodeGen::codegen(const clast_assignment *a, ScopStmt *Statement,
1055 unsigned Dimension, int vectorDim,
1056 std::vector<ValueMapT> *VectorVMap) {
1057 Value *RHS = ExpGen.codegen(a->RHS,
1058 TD->getIntPtrType(Builder.getContext()));
1059
1060 assert(!a->LHS && "Statement assignments do not have left hand side");
1061 const PHINode *PN;
1062 PN = Statement->getInductionVariableForDimension(Dimension);
1063 const Value *V = PN;
1064
1065 if (VectorVMap)
1066 (*VectorVMap)[vectorDim][V] = RHS;
1067
1068 ValueMap[V] = RHS;
1069}
1070
1071void ClastStmtCodeGen::codegenSubstitutions(const clast_stmt *Assignment,
1072 ScopStmt *Statement, int vectorDim,
1073 std::vector<ValueMapT> *VectorVMap) {
1074 int Dimension = 0;
1075
1076 while (Assignment) {
1077 assert(CLAST_STMT_IS_A(Assignment, stmt_ass)
1078 && "Substitions are expected to be assignments");
1079 codegen((const clast_assignment *)Assignment, Statement, Dimension,
1080 vectorDim, VectorVMap);
1081 Assignment = Assignment->next;
1082 Dimension++;
1083 }
1084}
1085
1086void ClastStmtCodeGen::codegen(const clast_user_stmt *u,
1087 std::vector<Value*> *IVS , const char *iterator,
Tobias Grosser14bcbd52012-03-02 11:26:52 +00001088 isl_set *Domain) {
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001089 ScopStmt *Statement = (ScopStmt *)u->statement->usr;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001090
1091 if (u->substitutions)
1092 codegenSubstitutions(u->substitutions, Statement);
1093
Tobias Grosser80998e72012-03-02 11:27:28 +00001094 int VectorDimensions = IVS ? IVS->size() : 1;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001095
Tobias Grosser80998e72012-03-02 11:27:28 +00001096 if (VectorDimensions == 1) {
Tobias Grosser08a82382012-03-02 15:20:24 +00001097 BlockGenerator::generate(Builder, ValueMap, *Statement, P);
Tobias Grosser80998e72012-03-02 11:27:28 +00001098 return;
1099 }
1100
1101 VectorValueMapT VectorMap(VectorDimensions);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001102
1103 if (IVS) {
1104 assert (u->substitutions && "Substitutions expected!");
1105 int i = 0;
1106 for (std::vector<Value*>::iterator II = IVS->begin(), IE = IVS->end();
1107 II != IE; ++II) {
1108 (*clastVars)[iterator] = *II;
Tobias Grosser14bcbd52012-03-02 11:26:52 +00001109 codegenSubstitutions(u->substitutions, Statement, i, &VectorMap);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001110 i++;
1111 }
1112 }
1113
Tobias Grosser80998e72012-03-02 11:27:28 +00001114 VectorBlockGenerator::generate(Builder, ValueMap, VectorMap, *Statement,
1115 Domain, P);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001116}
1117
1118void ClastStmtCodeGen::codegen(const clast_block *b) {
1119 if (b->body)
1120 codegen(b->body);
1121}
1122
1123void ClastStmtCodeGen::codegenForSequential(const clast_for *f,
1124 Value *LowerBound,
1125 Value *UpperBound) {
1126 APInt Stride;
Tobias Grosser0ac92142012-02-14 14:02:27 +00001127 BasicBlock *AfterBB;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001128 Type *IntPtrTy;
1129
1130 Stride = APInt_from_MPZ(f->stride);
1131 IntPtrTy = TD->getIntPtrType(Builder.getContext());
1132
1133 // The value of lowerbound and upperbound will be supplied, if this
1134 // function is called while generating OpenMP code. Otherwise get
1135 // the values.
1136 assert(!!LowerBound == !!UpperBound && "Either give both bounds or none");
1137
1138 if (LowerBound == 0) {
1139 LowerBound = ExpGen.codegen(f->LB, IntPtrTy);
1140 UpperBound = ExpGen.codegen(f->UB, IntPtrTy);
1141 }
1142
Tobias Grosser0ac92142012-02-14 14:02:27 +00001143 Value *IV = createLoop(&Builder, LowerBound, UpperBound, Stride, DT, P,
1144 &AfterBB);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001145
1146 // Add loop iv to symbols.
1147 (*clastVars)[f->iterator] = IV;
1148
1149 if (f->body)
1150 codegen(f->body);
1151
1152 // Loop is finished, so remove its iv from the live symbols.
1153 clastVars->erase(f->iterator);
Tobias Grosser0ac92142012-02-14 14:02:27 +00001154 Builder.SetInsertPoint(AfterBB->begin());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001155}
1156
1157Function *ClastStmtCodeGen::addOpenMPSubfunction(Module *M) {
1158 Function *F = Builder.GetInsertBlock()->getParent();
1159 std::vector<Type*> Arguments(1, Builder.getInt8PtrTy());
1160 FunctionType *FT = FunctionType::get(Builder.getVoidTy(), Arguments, false);
1161 Function *FN = Function::Create(FT, Function::InternalLinkage,
1162 F->getName() + ".omp_subfn", M);
1163 // Do not run any polly pass on the new function.
1164 SD->markFunctionAsInvalid(FN);
1165
1166 Function::arg_iterator AI = FN->arg_begin();
1167 AI->setName("omp.userContext");
1168
1169 return FN;
1170}
1171
1172Value *ClastStmtCodeGen::addValuesToOpenMPStruct(SetVector<Value*> OMPDataVals,
1173 Function *SubFunction) {
1174 std::vector<Type*> structMembers;
1175
1176 // Create the structure.
1177 for (unsigned i = 0; i < OMPDataVals.size(); i++)
1178 structMembers.push_back(OMPDataVals[i]->getType());
1179
1180 StructType *structTy = StructType::get(Builder.getContext(),
1181 structMembers);
1182 // Store the values into the structure.
1183 Value *structData = Builder.CreateAlloca(structTy, 0, "omp.userContext");
1184 for (unsigned i = 0; i < OMPDataVals.size(); i++) {
1185 Value *storeAddr = Builder.CreateStructGEP(structData, i);
1186 Builder.CreateStore(OMPDataVals[i], storeAddr);
1187 }
1188
1189 return structData;
1190}
1191
1192SetVector<Value*> ClastStmtCodeGen::createOpenMPStructValues() {
1193 SetVector<Value*> OMPDataVals;
1194
1195 // Push the clast variables available in the clastVars.
1196 for (CharMapT::iterator I = clastVars->begin(), E = clastVars->end();
1197 I != E; I++)
1198 OMPDataVals.insert(I->second);
1199
1200 // Push the base addresses of memory references.
1201 for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI) {
1202 ScopStmt *Stmt = *SI;
1203 for (SmallVector<MemoryAccess*, 8>::iterator I = Stmt->memacc_begin(),
1204 E = Stmt->memacc_end(); I != E; ++I) {
1205 Value *BaseAddr = const_cast<Value*>((*I)->getBaseAddr());
1206 OMPDataVals.insert((BaseAddr));
1207 }
1208 }
1209
1210 return OMPDataVals;
1211}
1212
1213void ClastStmtCodeGen::extractValuesFromOpenMPStruct(CharMapT *clastVarsOMP,
1214 SetVector<Value*> OMPDataVals, Value *userContext) {
1215 // Extract the clast variables.
1216 unsigned i = 0;
1217 for (CharMapT::iterator I = clastVars->begin(), E = clastVars->end();
1218 I != E; I++) {
1219 Value *loadAddr = Builder.CreateStructGEP(userContext, i);
1220 (*clastVarsOMP)[I->first] = Builder.CreateLoad(loadAddr);
1221 i++;
1222 }
1223
1224 // Extract the base addresses of memory references.
1225 for (unsigned j = i; j < OMPDataVals.size(); j++) {
1226 Value *loadAddr = Builder.CreateStructGEP(userContext, j);
1227 Value *baseAddr = OMPDataVals[j];
1228 ValueMap[baseAddr] = Builder.CreateLoad(loadAddr);
1229 }
1230}
1231
1232void ClastStmtCodeGen::addOpenMPSubfunctionBody(Function *FN,
1233 const clast_for *f,
1234 Value *structData,
1235 SetVector<Value*> OMPDataVals) {
1236 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
1237 LLVMContext &Context = FN->getContext();
1238 IntegerType *intPtrTy = TD->getIntPtrType(Context);
1239
1240 // Store the previous basic block.
Tobias Grosser0ac92142012-02-14 14:02:27 +00001241 BasicBlock::iterator PrevInsertPoint = Builder.GetInsertPoint();
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001242 BasicBlock *PrevBB = Builder.GetInsertBlock();
1243
1244 // Create basic blocks.
1245 BasicBlock *HeaderBB = BasicBlock::Create(Context, "omp.setup", FN);
1246 BasicBlock *ExitBB = BasicBlock::Create(Context, "omp.exit", FN);
1247 BasicBlock *checkNextBB = BasicBlock::Create(Context, "omp.checkNext", FN);
1248 BasicBlock *loadIVBoundsBB = BasicBlock::Create(Context, "omp.loadIVBounds",
1249 FN);
1250
1251 DT->addNewBlock(HeaderBB, PrevBB);
1252 DT->addNewBlock(ExitBB, HeaderBB);
1253 DT->addNewBlock(checkNextBB, HeaderBB);
1254 DT->addNewBlock(loadIVBoundsBB, HeaderBB);
1255
1256 // Fill up basic block HeaderBB.
1257 Builder.SetInsertPoint(HeaderBB);
1258 Value *lowerBoundPtr = Builder.CreateAlloca(intPtrTy, 0,
1259 "omp.lowerBoundPtr");
1260 Value *upperBoundPtr = Builder.CreateAlloca(intPtrTy, 0,
1261 "omp.upperBoundPtr");
1262 Value *userContext = Builder.CreateBitCast(FN->arg_begin(),
1263 structData->getType(),
1264 "omp.userContext");
1265
1266 CharMapT clastVarsOMP;
1267 extractValuesFromOpenMPStruct(&clastVarsOMP, OMPDataVals, userContext);
1268
1269 Builder.CreateBr(checkNextBB);
1270
1271 // Add code to check if another set of iterations will be executed.
1272 Builder.SetInsertPoint(checkNextBB);
1273 Function *runtimeNextFunction = M->getFunction("GOMP_loop_runtime_next");
1274 Value *ret1 = Builder.CreateCall2(runtimeNextFunction,
1275 lowerBoundPtr, upperBoundPtr);
1276 Value *hasNextSchedule = Builder.CreateTrunc(ret1, Builder.getInt1Ty(),
1277 "omp.hasNextScheduleBlock");
1278 Builder.CreateCondBr(hasNextSchedule, loadIVBoundsBB, ExitBB);
1279
1280 // Add code to to load the iv bounds for this set of iterations.
1281 Builder.SetInsertPoint(loadIVBoundsBB);
1282 Value *lowerBound = Builder.CreateLoad(lowerBoundPtr, "omp.lowerBound");
1283 Value *upperBound = Builder.CreateLoad(upperBoundPtr, "omp.upperBound");
1284
1285 // Subtract one as the upper bound provided by openmp is a < comparison
1286 // whereas the codegenForSequential function creates a <= comparison.
1287 upperBound = Builder.CreateSub(upperBound, ConstantInt::get(intPtrTy, 1),
1288 "omp.upperBoundAdjusted");
1289
1290 // Use clastVarsOMP during code generation of the OpenMP subfunction.
1291 CharMapT *oldClastVars = clastVars;
1292 clastVars = &clastVarsOMP;
1293 ExpGen.setIVS(&clastVarsOMP);
1294
Tobias Grosser0ac92142012-02-14 14:02:27 +00001295 Builder.CreateBr(checkNextBB);
1296 Builder.SetInsertPoint(--Builder.GetInsertPoint());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001297 codegenForSequential(f, lowerBound, upperBound);
1298
1299 // Restore the old clastVars.
1300 clastVars = oldClastVars;
1301 ExpGen.setIVS(oldClastVars);
1302
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001303 // Add code to terminate this openmp subfunction.
1304 Builder.SetInsertPoint(ExitBB);
1305 Function *endnowaitFunction = M->getFunction("GOMP_loop_end_nowait");
1306 Builder.CreateCall(endnowaitFunction);
1307 Builder.CreateRetVoid();
1308
Tobias Grosser0ac92142012-02-14 14:02:27 +00001309 // Restore the previous insert point.
1310 Builder.SetInsertPoint(PrevInsertPoint);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001311}
1312
Tobias Grosser415245d2012-03-02 15:20:17 +00001313void ClastStmtCodeGen::codegenForOpenMP(const clast_for *For) {
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001314 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
Tobias Grosser415245d2012-03-02 15:20:17 +00001315 IntegerType *IntPtrTy = TD->getIntPtrType(Builder.getContext());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001316
1317 Function *SubFunction = addOpenMPSubfunction(M);
1318 SetVector<Value*> OMPDataVals = createOpenMPStructValues();
Tobias Grosser415245d2012-03-02 15:20:17 +00001319 Value *StructData = addValuesToOpenMPStruct(OMPDataVals, SubFunction);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001320
Tobias Grosser415245d2012-03-02 15:20:17 +00001321 addOpenMPSubfunctionBody(SubFunction, For, StructData, OMPDataVals);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001322
1323 // Create call for GOMP_parallel_loop_runtime_start.
Tobias Grosser415245d2012-03-02 15:20:17 +00001324 Value *SubfunctionParam = Builder.CreateBitCast(StructData,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001325 Builder.getInt8PtrTy(),
1326 "omp_data");
1327
Tobias Grosser415245d2012-03-02 15:20:17 +00001328 Value *NumberOfThreads = Builder.getInt32(0);
1329 Value *LowerBound = ExpGen.codegen(For->LB, IntPtrTy);
1330 Value *UpperBound = ExpGen.codegen(For->UB, IntPtrTy);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001331
1332 // Add one as the upper bound provided by openmp is a < comparison
1333 // whereas the codegenForSequential function creates a <= comparison.
Tobias Grosser415245d2012-03-02 15:20:17 +00001334 UpperBound = Builder.CreateAdd(UpperBound, ConstantInt::get(IntPtrTy, 1));
1335 APInt APStride = APInt_from_MPZ(For->stride);
1336 Value *Stride = ConstantInt::get(IntPtrTy,
1337 APStride.zext(IntPtrTy->getBitWidth()));
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001338
Tobias Grosser415245d2012-03-02 15:20:17 +00001339 Value *Arguments[] = { SubFunction, SubfunctionParam, NumberOfThreads,
1340 LowerBound, UpperBound, Stride};
1341 Builder.CreateCall(M->getFunction("GOMP_parallel_loop_runtime_start"),
1342 Arguments);
1343 Builder.CreateCall(SubFunction, SubfunctionParam);
1344 Builder.CreateCall(M->getFunction("GOMP_parallel_end"));
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001345}
1346
1347bool ClastStmtCodeGen::isInnermostLoop(const clast_for *f) {
1348 const clast_stmt *stmt = f->body;
1349
1350 while (stmt) {
1351 if (!CLAST_STMT_IS_A(stmt, stmt_user))
1352 return false;
1353
1354 stmt = stmt->next;
1355 }
1356
1357 return true;
1358}
1359
1360int ClastStmtCodeGen::getNumberOfIterations(const clast_for *f) {
1361 isl_set *loopDomain = isl_set_copy(isl_set_from_cloog_domain(f->domain));
1362 isl_set *tmp = isl_set_copy(loopDomain);
1363
1364 // Calculate a map similar to the identity map, but with the last input
1365 // and output dimension not related.
1366 // [i0, i1, i2, i3] -> [i0, i1, i2, o0]
1367 isl_space *Space = isl_set_get_space(loopDomain);
1368 Space = isl_space_drop_outputs(Space,
1369 isl_set_dim(loopDomain, isl_dim_set) - 2, 1);
1370 Space = isl_space_map_from_set(Space);
1371 isl_map *identity = isl_map_identity(Space);
1372 identity = isl_map_add_dims(identity, isl_dim_in, 1);
1373 identity = isl_map_add_dims(identity, isl_dim_out, 1);
1374
1375 isl_map *map = isl_map_from_domain_and_range(tmp, loopDomain);
1376 map = isl_map_intersect(map, identity);
1377
1378 isl_map *lexmax = isl_map_lexmax(isl_map_copy(map));
1379 isl_map *lexmin = isl_map_lexmin(map);
1380 isl_map *sub = isl_map_sum(lexmax, isl_map_neg(lexmin));
1381
1382 isl_set *elements = isl_map_range(sub);
1383
1384 if (!isl_set_is_singleton(elements)) {
1385 isl_set_free(elements);
1386 return -1;
1387 }
1388
1389 isl_point *p = isl_set_sample_point(elements);
1390
1391 isl_int v;
1392 isl_int_init(v);
1393 isl_point_get_coordinate(p, isl_dim_set, isl_set_n_dim(loopDomain) - 1, &v);
1394 int numberIterations = isl_int_get_si(v);
1395 isl_int_clear(v);
1396 isl_point_free(p);
1397
1398 return (numberIterations) / isl_int_get_si(f->stride) + 1;
1399}
1400
1401void ClastStmtCodeGen::codegenForVector(const clast_for *f) {
1402 DEBUG(dbgs() << "Vectorizing loop '" << f->iterator << "'\n";);
1403 int vectorWidth = getNumberOfIterations(f);
1404
1405 Value *LB = ExpGen.codegen(f->LB,
1406 TD->getIntPtrType(Builder.getContext()));
1407
1408 APInt Stride = APInt_from_MPZ(f->stride);
1409 IntegerType *LoopIVType = dyn_cast<IntegerType>(LB->getType());
1410 Stride = Stride.zext(LoopIVType->getBitWidth());
1411 Value *StrideValue = ConstantInt::get(LoopIVType, Stride);
1412
1413 std::vector<Value*> IVS(vectorWidth);
1414 IVS[0] = LB;
1415
1416 for (int i = 1; i < vectorWidth; i++)
1417 IVS[i] = Builder.CreateAdd(IVS[i-1], StrideValue, "p_vector_iv");
1418
1419 isl_set *scatteringDomain =
1420 isl_set_copy(isl_set_from_cloog_domain(f->domain));
1421
1422 // Add loop iv to symbols.
1423 (*clastVars)[f->iterator] = LB;
1424
1425 const clast_stmt *stmt = f->body;
1426
1427 while (stmt) {
1428 codegen((const clast_user_stmt *)stmt, &IVS, f->iterator,
1429 scatteringDomain);
1430 stmt = stmt->next;
1431 }
1432
1433 // Loop is finished, so remove its iv from the live symbols.
1434 isl_set_free(scatteringDomain);
1435 clastVars->erase(f->iterator);
1436}
1437
1438void ClastStmtCodeGen::codegen(const clast_for *f) {
Tobias Grosserce3f5372012-03-02 11:26:42 +00001439 if ((Vector || OpenMP) && DP->isParallelFor(f)) {
1440 if (Vector && isInnermostLoop(f) && (-1 != getNumberOfIterations(f))
1441 && (getNumberOfIterations(f) <= 16)) {
1442 codegenForVector(f);
1443 return;
1444 }
1445
1446 if (OpenMP && !parallelCodeGeneration) {
1447 parallelCodeGeneration = true;
1448 parallelLoops.push_back(f->iterator);
1449 codegenForOpenMP(f);
1450 parallelCodeGeneration = false;
1451 return;
1452 }
1453 }
1454
1455 codegenForSequential(f);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001456}
1457
1458Value *ClastStmtCodeGen::codegen(const clast_equation *eq) {
1459 Value *LHS = ExpGen.codegen(eq->LHS,
1460 TD->getIntPtrType(Builder.getContext()));
1461 Value *RHS = ExpGen.codegen(eq->RHS,
1462 TD->getIntPtrType(Builder.getContext()));
1463 CmpInst::Predicate P;
1464
1465 if (eq->sign == 0)
1466 P = ICmpInst::ICMP_EQ;
1467 else if (eq->sign > 0)
1468 P = ICmpInst::ICMP_SGE;
1469 else
1470 P = ICmpInst::ICMP_SLE;
1471
1472 return Builder.CreateICmp(P, LHS, RHS);
1473}
1474
1475void ClastStmtCodeGen::codegen(const clast_guard *g) {
1476 Function *F = Builder.GetInsertBlock()->getParent();
1477 LLVMContext &Context = F->getContext();
Tobias Grosser0ac92142012-02-14 14:02:27 +00001478
1479 BasicBlock *CondBB = SplitBlock(Builder.GetInsertBlock(),
1480 Builder.GetInsertPoint(), P);
1481 CondBB->setName("polly.cond");
1482 BasicBlock *MergeBB = SplitBlock(CondBB, CondBB->begin(), P);
1483 MergeBB->setName("polly.merge");
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001484 BasicBlock *ThenBB = BasicBlock::Create(Context, "polly.then", F);
Tobias Grosser0ac92142012-02-14 14:02:27 +00001485
1486 DT->addNewBlock(ThenBB, CondBB);
1487 DT->changeImmediateDominator(MergeBB, CondBB);
1488
1489 CondBB->getTerminator()->eraseFromParent();
1490
1491 Builder.SetInsertPoint(CondBB);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001492
1493 Value *Predicate = codegen(&(g->eq[0]));
1494
1495 for (int i = 1; i < g->n; ++i) {
1496 Value *TmpPredicate = codegen(&(g->eq[i]));
1497 Predicate = Builder.CreateAnd(Predicate, TmpPredicate);
1498 }
1499
1500 Builder.CreateCondBr(Predicate, ThenBB, MergeBB);
1501 Builder.SetInsertPoint(ThenBB);
Tobias Grosser0ac92142012-02-14 14:02:27 +00001502 Builder.CreateBr(MergeBB);
1503 Builder.SetInsertPoint(ThenBB->begin());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001504
1505 codegen(g->then);
Tobias Grosser62a3c962012-02-16 09:56:21 +00001506
1507 Builder.SetInsertPoint(MergeBB->begin());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001508}
1509
1510void ClastStmtCodeGen::codegen(const clast_stmt *stmt) {
1511 if (CLAST_STMT_IS_A(stmt, stmt_root))
1512 assert(false && "No second root statement expected");
1513 else if (CLAST_STMT_IS_A(stmt, stmt_ass))
1514 codegen((const clast_assignment *)stmt);
1515 else if (CLAST_STMT_IS_A(stmt, stmt_user))
1516 codegen((const clast_user_stmt *)stmt);
1517 else if (CLAST_STMT_IS_A(stmt, stmt_block))
1518 codegen((const clast_block *)stmt);
1519 else if (CLAST_STMT_IS_A(stmt, stmt_for))
1520 codegen((const clast_for *)stmt);
1521 else if (CLAST_STMT_IS_A(stmt, stmt_guard))
1522 codegen((const clast_guard *)stmt);
1523
1524 if (stmt->next)
1525 codegen(stmt->next);
1526}
1527
1528void ClastStmtCodeGen::addParameters(const CloogNames *names) {
1529 SCEVExpander Rewriter(SE, "polly");
1530
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001531 int i = 0;
1532 for (Scop::param_iterator PI = S->param_begin(), PE = S->param_end();
1533 PI != PE; ++PI) {
1534 assert(i < names->nb_parameters && "Not enough parameter names");
1535
1536 const SCEV *Param = *PI;
1537 Type *Ty = Param->getType();
1538
1539 Instruction *insertLocation = --(Builder.GetInsertBlock()->end());
1540 Value *V = Rewriter.expandCodeFor(Param, Ty, insertLocation);
1541 (*clastVars)[names->parameters[i]] = V;
1542
1543 ++i;
1544 }
1545}
1546
1547void ClastStmtCodeGen::codegen(const clast_root *r) {
1548 clastVars = new CharMapT();
1549 addParameters(r->names);
1550 ExpGen.setIVS(clastVars);
1551
1552 parallelCodeGeneration = false;
1553
1554 const clast_stmt *stmt = (const clast_stmt*) r;
1555 if (stmt->next)
1556 codegen(stmt->next);
1557
1558 delete clastVars;
1559}
1560
1561ClastStmtCodeGen::ClastStmtCodeGen(Scop *scop, ScalarEvolution &se,
1562 DominatorTree *dt, ScopDetection *sd,
1563 Dependences *dp, TargetData *td,
Tobias Grosser0ac92142012-02-14 14:02:27 +00001564 IRBuilder<> &B, Pass *P) :
1565 S(scop), SE(se), DT(dt), SD(sd), DP(dp), TD(td), P(P), Builder(B),
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001566 ExpGen(Builder, NULL) {}
1567
Tobias Grosser75805372011-04-29 06:27:02 +00001568namespace {
1569class CodeGeneration : public ScopPass {
1570 Region *region;
1571 Scop *S;
1572 DominatorTree *DT;
1573 ScalarEvolution *SE;
1574 ScopDetection *SD;
Tobias Grosser75805372011-04-29 06:27:02 +00001575 TargetData *TD;
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001576 RegionInfo *RI;
Tobias Grosser75805372011-04-29 06:27:02 +00001577
1578 std::vector<std::string> parallelLoops;
1579
1580 public:
1581 static char ID;
1582
1583 CodeGeneration() : ScopPass(ID) {}
1584
Tobias Grosserb1c95992012-02-12 12:09:27 +00001585 // Add the declarations needed by the OpenMP function calls that we insert in
1586 // OpenMP mode.
1587 void addOpenMPDeclarations(Module *M)
Tobias Grosser75805372011-04-29 06:27:02 +00001588 {
Tobias Grosserd855cc52012-02-12 12:09:32 +00001589 IRBuilder<> Builder(M->getContext());
1590 IntegerType *LongTy = TD->getIntPtrType(M->getContext());
1591
1592 llvm::GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
Tobias Grosser75805372011-04-29 06:27:02 +00001593
1594 if (!M->getFunction("GOMP_parallel_end")) {
Tobias Grosserd855cc52012-02-12 12:09:32 +00001595 FunctionType *Ty = FunctionType::get(Builder.getVoidTy(), false);
1596 Function::Create(Ty, Linkage, "GOMP_parallel_end", M);
Tobias Grosser75805372011-04-29 06:27:02 +00001597 }
1598
1599 if (!M->getFunction("GOMP_parallel_loop_runtime_start")) {
Tobias Grosserd855cc52012-02-12 12:09:32 +00001600 Type *Params[] = {
1601 PointerType::getUnqual(FunctionType::get(Builder.getVoidTy(),
1602 Builder.getInt8PtrTy(),
1603 false)),
1604 Builder.getInt8PtrTy(),
1605 Builder.getInt32Ty(),
1606 LongTy,
1607 LongTy,
1608 LongTy,
1609 };
Tobias Grosser75805372011-04-29 06:27:02 +00001610
Tobias Grosserd855cc52012-02-12 12:09:32 +00001611 FunctionType *Ty = FunctionType::get(Builder.getVoidTy(), Params, false);
1612 Function::Create(Ty, Linkage, "GOMP_parallel_loop_runtime_start", M);
Tobias Grosser75805372011-04-29 06:27:02 +00001613 }
1614
1615 if (!M->getFunction("GOMP_loop_runtime_next")) {
Tobias Grosserd855cc52012-02-12 12:09:32 +00001616 PointerType *LongPtrTy = PointerType::getUnqual(LongTy);
1617 Type *Params[] = {
1618 LongPtrTy,
1619 LongPtrTy,
1620 };
Tobias Grosser75805372011-04-29 06:27:02 +00001621
Tobias Grosserd855cc52012-02-12 12:09:32 +00001622 FunctionType *Ty = FunctionType::get(Builder.getInt8Ty(), Params, false);
1623 Function::Create(Ty, Linkage, "GOMP_loop_runtime_next", M);
Tobias Grosser75805372011-04-29 06:27:02 +00001624 }
1625
1626 if (!M->getFunction("GOMP_loop_end_nowait")) {
Tobias Grosserd855cc52012-02-12 12:09:32 +00001627 FunctionType *Ty = FunctionType::get(Builder.getVoidTy(), false);
1628 Function::Create(Ty, Linkage, "GOMP_loop_end_nowait", M);
Tobias Grosser75805372011-04-29 06:27:02 +00001629 }
1630 }
1631
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001632 // Split the entry edge of the region and generate a new basic block on this
1633 // edge. This function also updates ScopInfo and RegionInfo.
1634 //
1635 // @param region The region where the entry edge will be splitted.
1636 BasicBlock *splitEdgeAdvanced(Region *region) {
1637 BasicBlock *newBlock;
1638 BasicBlock *splitBlock;
1639
1640 newBlock = SplitEdge(region->getEnteringBlock(), region->getEntry(), this);
1641
1642 if (DT->dominates(region->getEntry(), newBlock)) {
Tobias Grossercb47dfe2012-02-15 09:58:50 +00001643 BasicBlock *OldBlock = region->getEntry();
1644 std::string OldName = OldBlock->getName();
1645
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001646 // Update ScopInfo.
1647 for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI)
Tobias Grosserf12cea42012-02-15 09:58:53 +00001648 if ((*SI)->getBasicBlock() == OldBlock) {
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001649 (*SI)->setBasicBlock(newBlock);
1650 break;
1651 }
1652
1653 // Update RegionInfo.
Tobias Grossercb47dfe2012-02-15 09:58:50 +00001654 splitBlock = OldBlock;
1655 OldBlock->setName("polly.split");
1656 newBlock->setName(OldName);
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001657 region->replaceEntry(newBlock);
Tobias Grosser7a16c892011-05-14 19:01:55 +00001658 RI->setRegionFor(newBlock, region);
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001659 } else {
1660 RI->setRegionFor(newBlock, region->getParent());
1661 splitBlock = newBlock;
1662 }
1663
1664 return splitBlock;
1665 }
1666
1667 // Create a split block that branches either to the old code or to a new basic
1668 // block where the new code can be inserted.
1669 //
Tobias Grosserbd608a82012-02-12 12:09:41 +00001670 // @param Builder A builder that will be set to point to a basic block, where
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001671 // the new code can be generated.
1672 // @return The split basic block.
Tobias Grosserbd608a82012-02-12 12:09:41 +00001673 BasicBlock *addSplitAndStartBlock(IRBuilder<> *Builder) {
1674 BasicBlock *StartBlock, *SplitBlock;
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001675
Tobias Grosserbd608a82012-02-12 12:09:41 +00001676 SplitBlock = splitEdgeAdvanced(region);
1677 SplitBlock->setName("polly.split_new_and_old");
1678 Function *F = SplitBlock->getParent();
1679 StartBlock = BasicBlock::Create(F->getContext(), "polly.start", F);
1680 SplitBlock->getTerminator()->eraseFromParent();
1681 Builder->SetInsertPoint(SplitBlock);
1682 Builder->CreateCondBr(Builder->getTrue(), StartBlock, region->getEntry());
1683 DT->addNewBlock(StartBlock, SplitBlock);
1684 Builder->SetInsertPoint(StartBlock);
1685 return SplitBlock;
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001686 }
1687
1688 // Merge the control flow of the newly generated code with the existing code.
1689 //
Tobias Grosserbd608a82012-02-12 12:09:41 +00001690 // @param SplitBlock The basic block where the control flow was split between
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001691 // old and new version of the Scop.
Tobias Grosserbd608a82012-02-12 12:09:41 +00001692 // @param Builder An IRBuilder that points to the last instruction of the
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001693 // newly generated code.
Tobias Grosserbd608a82012-02-12 12:09:41 +00001694 void mergeControlFlow(BasicBlock *SplitBlock, IRBuilder<> *Builder) {
1695 BasicBlock *MergeBlock;
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001696 Region *R = region;
1697
1698 if (R->getExit()->getSinglePredecessor())
1699 // No splitEdge required. A block with a single predecessor cannot have
1700 // PHI nodes that would complicate life.
Tobias Grosserbd608a82012-02-12 12:09:41 +00001701 MergeBlock = R->getExit();
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001702 else {
Tobias Grosserbd608a82012-02-12 12:09:41 +00001703 MergeBlock = SplitEdge(R->getExitingBlock(), R->getExit(), this);
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001704 // SplitEdge will never split R->getExit(), as R->getExit() has more than
1705 // one predecessor. Hence, mergeBlock is always a newly generated block.
Tobias Grosserbd608a82012-02-12 12:09:41 +00001706 R->replaceExit(MergeBlock);
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001707 }
1708
Tobias Grosserbd608a82012-02-12 12:09:41 +00001709 Builder->CreateBr(MergeBlock);
Tobias Grosser8518bbe2012-02-12 12:09:46 +00001710 MergeBlock->setName("polly.merge_new_and_old");
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001711
Tobias Grosserbd608a82012-02-12 12:09:41 +00001712 if (DT->dominates(SplitBlock, MergeBlock))
1713 DT->changeImmediateDominator(MergeBlock, SplitBlock);
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001714 }
1715
Tobias Grosser75805372011-04-29 06:27:02 +00001716 bool runOnScop(Scop &scop) {
1717 S = &scop;
1718 region = &S->getRegion();
Tobias Grosser75805372011-04-29 06:27:02 +00001719 DT = &getAnalysis<DominatorTree>();
1720 Dependences *DP = &getAnalysis<Dependences>();
1721 SE = &getAnalysis<ScalarEvolution>();
Tobias Grosser75805372011-04-29 06:27:02 +00001722 SD = &getAnalysis<ScopDetection>();
1723 TD = &getAnalysis<TargetData>();
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001724 RI = &getAnalysis<RegionInfo>();
Tobias Grosser75805372011-04-29 06:27:02 +00001725
1726 parallelLoops.clear();
1727
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001728 assert(region->isSimple() && "Only simple regions are supported");
Tobias Grosser76d7c522011-05-14 19:01:37 +00001729
Tobias Grosserb1c95992012-02-12 12:09:27 +00001730 Module *M = region->getEntry()->getParent()->getParent();
1731
Tobias Grosserd855cc52012-02-12 12:09:32 +00001732 if (OpenMP) addOpenMPDeclarations(M);
Tobias Grosserb1c95992012-02-12 12:09:27 +00001733
Tobias Grosser5772e652012-02-01 14:23:33 +00001734 // In the CFG the optimized code of the SCoP is generated next to the
1735 // original code. Both the new and the original version of the code remain
1736 // in the CFG. A branch statement decides which version is executed.
1737 // For now, we always execute the new version (the old one is dead code
1738 // eliminated by the cleanup passes). In the future we may decide to execute
1739 // the new version only if certain run time checks succeed. This will be
1740 // useful to support constructs for which we cannot prove all assumptions at
1741 // compile time.
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001742 //
1743 // Before transformation:
1744 //
1745 // bb0
1746 // |
1747 // orig_scop
1748 // |
1749 // bb1
1750 //
1751 // After transformation:
1752 // bb0
1753 // |
1754 // polly.splitBlock
Tobias Grosser2bd3af12011-08-01 22:39:00 +00001755 // / \.
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001756 // | startBlock
1757 // | |
1758 // orig_scop new_scop
1759 // \ /
1760 // \ /
1761 // bb1 (joinBlock)
1762 IRBuilder<> builder(region->getEntry());
Tobias Grosser75805372011-04-29 06:27:02 +00001763
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001764 // The builder will be set to startBlock.
1765 BasicBlock *splitBlock = addSplitAndStartBlock(&builder);
Tobias Grosser0ac92142012-02-14 14:02:27 +00001766 BasicBlock *StartBlock = builder.GetInsertBlock();
Tobias Grosser75805372011-04-29 06:27:02 +00001767
Tobias Grosser0ac92142012-02-14 14:02:27 +00001768 mergeControlFlow(splitBlock, &builder);
1769 builder.SetInsertPoint(StartBlock->begin());
1770
1771 ClastStmtCodeGen CodeGen(S, *SE, DT, SD, DP, TD, builder, this);
Tobias Grosser3fdecae2011-05-14 19:02:39 +00001772 CloogInfo &C = getAnalysis<CloogInfo>();
1773 CodeGen.codegen(C.getClast());
Tobias Grosser75805372011-04-29 06:27:02 +00001774
Tobias Grosser75805372011-04-29 06:27:02 +00001775 parallelLoops.insert(parallelLoops.begin(),
1776 CodeGen.getParallelLoops().begin(),
1777 CodeGen.getParallelLoops().end());
1778
Tobias Grosserabb6dcd2011-05-14 19:02:34 +00001779 return true;
Tobias Grosser75805372011-04-29 06:27:02 +00001780 }
1781
1782 virtual void printScop(raw_ostream &OS) const {
1783 for (std::vector<std::string>::const_iterator PI = parallelLoops.begin(),
1784 PE = parallelLoops.end(); PI != PE; ++PI)
1785 OS << "Parallel loop with iterator '" << *PI << "' generated\n";
1786 }
1787
1788 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
1789 AU.addRequired<CloogInfo>();
1790 AU.addRequired<Dependences>();
1791 AU.addRequired<DominatorTree>();
Tobias Grosser75805372011-04-29 06:27:02 +00001792 AU.addRequired<RegionInfo>();
Tobias Grosser73600b82011-10-08 00:30:40 +00001793 AU.addRequired<ScalarEvolution>();
Tobias Grosser75805372011-04-29 06:27:02 +00001794 AU.addRequired<ScopDetection>();
1795 AU.addRequired<ScopInfo>();
1796 AU.addRequired<TargetData>();
1797
1798 AU.addPreserved<CloogInfo>();
1799 AU.addPreserved<Dependences>();
Tobias Grosser5d6eb862011-05-14 19:02:45 +00001800
Tobias Grosser4e3f9a42011-05-23 15:23:36 +00001801 // FIXME: We do not create LoopInfo for the newly generated loops.
Tobias Grosser75805372011-04-29 06:27:02 +00001802 AU.addPreserved<LoopInfo>();
1803 AU.addPreserved<DominatorTree>();
Tobias Grosser75805372011-04-29 06:27:02 +00001804 AU.addPreserved<ScopDetection>();
1805 AU.addPreserved<ScalarEvolution>();
Tobias Grosser5d6eb862011-05-14 19:02:45 +00001806
Tobias Grosser4e3f9a42011-05-23 15:23:36 +00001807 // FIXME: We do not yet add regions for the newly generated code to the
1808 // region tree.
Tobias Grosser75805372011-04-29 06:27:02 +00001809 AU.addPreserved<RegionInfo>();
1810 AU.addPreserved<TempScopInfo>();
1811 AU.addPreserved<ScopInfo>();
1812 AU.addPreservedID(IndependentBlocksID);
1813 }
1814};
1815}
1816
1817char CodeGeneration::ID = 1;
1818
Tobias Grosser73600b82011-10-08 00:30:40 +00001819INITIALIZE_PASS_BEGIN(CodeGeneration, "polly-codegen",
1820 "Polly - Create LLVM-IR form SCoPs", false, false)
1821INITIALIZE_PASS_DEPENDENCY(CloogInfo)
1822INITIALIZE_PASS_DEPENDENCY(Dependences)
1823INITIALIZE_PASS_DEPENDENCY(DominatorTree)
1824INITIALIZE_PASS_DEPENDENCY(RegionInfo)
1825INITIALIZE_PASS_DEPENDENCY(ScalarEvolution)
1826INITIALIZE_PASS_DEPENDENCY(ScopDetection)
1827INITIALIZE_PASS_DEPENDENCY(TargetData)
1828INITIALIZE_PASS_END(CodeGeneration, "polly-codegen",
1829 "Polly - Create LLVM-IR form SCoPs", false, false)
Tobias Grosser75805372011-04-29 06:27:02 +00001830
Tobias Grosser7ffe4e82011-11-17 12:56:10 +00001831Pass *polly::createCodeGenerationPass() {
Tobias Grosser75805372011-04-29 06:27:02 +00001832 return new CodeGeneration();
1833}