blob: 1d2b4d0c824c4fdb29148c0fc51136ebe4143658 [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
227
Tobias Grosser75805372011-04-29 06:27:02 +0000228class BlockGenerator {
Tobias Grosserc941ede2012-03-02 11:26:49 +0000229public:
230 /// @brief Generate code for single basic block.
231 static void generate(IRBuilder<> &B, ValueMapT &ValueMap,
232 VectorValueMapT &VectorMaps, ScopStmt &Stmt,
Tobias Grosser14bcbd52012-03-02 11:26:52 +0000233 __isl_keep isl_set *Domain, Pass *P) {
Tobias Grosser8412cda2012-03-02 11:26:55 +0000234 BlockGenerator Generator(B, ValueMap, VectorMaps, Stmt, Domain, P);
235 Generator.copyBB();
Tobias Grosserc941ede2012-03-02 11:26:49 +0000236 }
237
238private:
239 BlockGenerator(IRBuilder<> &B, ValueMapT &vmap, VectorValueMapT &vmaps,
Tobias Grosser8412cda2012-03-02 11:26:55 +0000240 ScopStmt &Stmt, __isl_keep isl_set *domain, Pass *p);
Tobias Grosserc941ede2012-03-02 11:26:49 +0000241
Tobias Grosser75805372011-04-29 06:27:02 +0000242 IRBuilder<> &Builder;
243 ValueMapT &VMap;
244 VectorValueMapT &ValueMaps;
245 Scop &S;
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000246 ScopStmt &Statement;
247 isl_set *ScatteringDomain;
Tobias Grosser8412cda2012-03-02 11:26:55 +0000248 Pass *P;
Tobias Grosser75805372011-04-29 06:27:02 +0000249
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000250 Value *makeVectorOperand(Value *Operand);
Tobias Grosser75805372011-04-29 06:27:02 +0000251
Tobias Grosser7ffe4e82011-11-17 12:56:10 +0000252 Value *getOperand(const Value *oldOperand, ValueMapT &BBMap,
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000253 ValueMapT *VectorMap = 0);
Tobias Grosser75805372011-04-29 06:27:02 +0000254
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000255 Type *getVectorPtrTy(const Value *V, int Width);
Tobias Grosser75805372011-04-29 06:27:02 +0000256
257 /// @brief Load a vector from a set of adjacent scalars
258 ///
259 /// In case a set of scalars is known to be next to each other in memory,
260 /// create a vector load that loads those scalars
261 ///
262 /// %vector_ptr= bitcast double* %p to <4 x double>*
263 /// %vec_full = load <4 x double>* %vector_ptr
264 ///
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000265 Value *generateStrideOneLoad(const LoadInst *Load, ValueMapT &BBMap);
Tobias Grosser75805372011-04-29 06:27:02 +0000266
267 /// @brief Load a vector initialized from a single scalar in memory
268 ///
269 /// In case all elements of a vector are initialized to the same
270 /// scalar value, this value is loaded and shuffeled into all elements
271 /// of the vector.
272 ///
273 /// %splat_one = load <1 x double>* %p
274 /// %splat = shufflevector <1 x double> %splat_one, <1 x
275 /// double> %splat_one, <4 x i32> zeroinitializer
276 ///
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000277 Value *generateStrideZeroLoad(const LoadInst *Load, ValueMapT &BBMap);
Tobias Grosser75805372011-04-29 06:27:02 +0000278
279 /// @Load a vector from scalars distributed in memory
280 ///
281 /// In case some scalars a distributed randomly in memory. Create a vector
282 /// by loading each scalar and by inserting one after the other into the
283 /// vector.
284 ///
285 /// %scalar_1= load double* %p_1
286 /// %vec_1 = insertelement <2 x double> undef, double %scalar_1, i32 0
287 /// %scalar 2 = load double* %p_2
288 /// %vec_2 = insertelement <2 x double> %vec_1, double %scalar_1, i32 1
289 ///
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000290 Value *generateUnknownStrideLoad(const LoadInst *Load,
291 VectorValueMapT &ScalarMaps);
Tobias Grosser75805372011-04-29 06:27:02 +0000292
Raghesh Aloor129e8672011-08-15 02:33:39 +0000293 /// @brief Get the memory access offset to be added to the base address
Raghesh Aloor46eceba2011-12-09 14:27:17 +0000294 std::vector <Value*> getMemoryAccessIndex(__isl_keep isl_map *AccessRelation,
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000295 Value *BaseAddress);
Raghesh Aloor129e8672011-08-15 02:33:39 +0000296
Raghesh Aloor62b13122011-08-03 17:02:50 +0000297 /// @brief Get the new operand address according to the changed access in
298 /// JSCOP file.
Raghesh Aloor46eceba2011-12-09 14:27:17 +0000299 Value *getNewAccessOperand(__isl_keep isl_map *NewAccessRelation,
300 Value *BaseAddress, const Value *OldOperand,
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000301 ValueMapT &BBMap);
Raghesh Aloor62b13122011-08-03 17:02:50 +0000302
303 /// @brief Generate the operand address
304 Value *generateLocationAccessed(const Instruction *Inst,
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000305 const Value *Pointer, ValueMapT &BBMap );
Raghesh Aloor129e8672011-08-15 02:33:39 +0000306
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000307 Value *generateScalarLoad(const LoadInst *load, ValueMapT &BBMap);
Tobias Grosser75805372011-04-29 06:27:02 +0000308
Tobias Grosserfc1153f2012-03-02 11:27:15 +0000309 void generateVectorLoad(const LoadInst *Load, ValueMapT &VectorMap,
310 VectorValueMapT &ScalarMaps);
Tobias Grosser75805372011-04-29 06:27:02 +0000311
Tobias Grosser8b4bf8b2012-03-02 11:27:11 +0000312 void copyVectorUnaryInst(const UnaryInstruction *Inst, ValueMapT &BBMap,
313 ValueMapT &VectorMap);
Tobias Grosserc9215152011-09-04 11:45:52 +0000314
Tobias Grosser8b4bf8b2012-03-02 11:27:11 +0000315 void copyVectorBinInst(const BinaryOperator *Inst, ValueMapT &BBMap,
316 ValueMapT &VectorMap);
Tobias Grosser09c57102011-09-04 11:45:29 +0000317
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000318 void copyVectorStore(const StoreInst *Store, ValueMapT &BBMap,
Tobias Grosser8927a442012-03-02 11:27:05 +0000319 ValueMapT &VectorMap, VectorValueMapT &ScalarMaps);
Tobias Grosser75805372011-04-29 06:27:02 +0000320
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000321 void copyInstScalar(const Instruction *Inst, ValueMapT &BBMap);
Tobias Grosser75805372011-04-29 06:27:02 +0000322
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000323 bool hasVectorOperands(const Instruction *Inst, ValueMapT &VectorMap);
Tobias Grosser75805372011-04-29 06:27:02 +0000324
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000325 int getVectorWidth();
Tobias Grosser75805372011-04-29 06:27:02 +0000326
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000327 bool isVectorBlock();
Tobias Grosser75805372011-04-29 06:27:02 +0000328
Tobias Grosser32152cb2012-03-02 11:27:18 +0000329 void copyVectorInstruction(const Instruction *Inst, ValueMapT &VectorMap,
330 VectorValueMapT &ScalarMaps);
Tobias Grosserfc1153f2012-03-02 11:27:15 +0000331 void copyInstruction(const Instruction *Inst, ValueMapT &VectorMap,
332 VectorValueMapT &ScalarMaps);
Tobias Grosser7551c302011-09-04 11:45:41 +0000333
Tobias Grosser75805372011-04-29 06:27:02 +0000334 // Insert a copy of a basic block in the newly generated code.
335 //
336 // @param Builder The builder used to insert the code. It also specifies
337 // where to insert the code.
Tobias Grosser75805372011-04-29 06:27:02 +0000338 // @param VMap A map returning for any old value its new equivalent. This
339 // is used to update the operands of the statements.
340 // For new statements a relation old->new is inserted in this
341 // map.
Tobias Grosser8412cda2012-03-02 11:26:55 +0000342 void copyBB();
Tobias Grosser75805372011-04-29 06:27:02 +0000343};
344
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000345BlockGenerator::BlockGenerator(IRBuilder<> &B, ValueMapT &vmap,
346 VectorValueMapT &vmaps, ScopStmt &Stmt,
Tobias Grosser8412cda2012-03-02 11:26:55 +0000347 __isl_keep isl_set *domain, Pass *P)
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000348 : Builder(B), VMap(vmap), ValueMaps(vmaps), S(*Stmt.getParent()),
Tobias Grosser8412cda2012-03-02 11:26:55 +0000349 Statement(Stmt), ScatteringDomain(domain), P(P) {}
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000350
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000351Value *BlockGenerator::makeVectorOperand(Value *Operand) {
352 int VectorWidth = getVectorWidth();
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000353 if (Operand->getType()->isVectorTy())
354 return Operand;
355
356 VectorType *VectorType = VectorType::get(Operand->getType(), VectorWidth);
357 Value *Vector = UndefValue::get(VectorType);
358 Vector = Builder.CreateInsertElement(Vector, Operand, Builder.getInt32(0));
359
360 std::vector<Constant*> Splat;
361
362 for (int i = 0; i < VectorWidth; i++)
363 Splat.push_back (Builder.getInt32(0));
364
365 Constant *SplatVector = ConstantVector::get(Splat);
366
367 return Builder.CreateShuffleVector(Vector, Vector, SplatVector);
368}
369
370Value *BlockGenerator::getOperand(const Value *OldOperand, ValueMapT &BBMap,
371 ValueMapT *VectorMap) {
372 const Instruction *OpInst = dyn_cast<Instruction>(OldOperand);
373
374 if (!OpInst)
375 return const_cast<Value*>(OldOperand);
376
377 if (VectorMap && VectorMap->count(OldOperand))
378 return (*VectorMap)[OldOperand];
379
380 // IVS and Parameters.
381 if (VMap.count(OldOperand)) {
382 Value *NewOperand = VMap[OldOperand];
383
384 // Insert a cast if types are different
385 if (OldOperand->getType()->getScalarSizeInBits()
386 < NewOperand->getType()->getScalarSizeInBits())
387 NewOperand = Builder.CreateTruncOrBitCast(NewOperand,
388 OldOperand->getType());
389
390 return NewOperand;
391 }
392
393 // Instructions calculated in the current BB.
394 if (BBMap.count(OldOperand)) {
395 return BBMap[OldOperand];
396 }
397
398 // Ignore instructions that are referencing ops in the old BB. These
399 // instructions are unused. They where replace by new ones during
400 // createIndependentBlocks().
Tobias Grosser44d16952012-03-02 11:27:21 +0000401 if (S.getRegion().contains(OpInst->getParent()))
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000402 return NULL;
403
404 return const_cast<Value*>(OldOperand);
405}
406
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000407Type *BlockGenerator::getVectorPtrTy(const Value *Val, int Width) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000408 PointerType *PointerTy = dyn_cast<PointerType>(Val->getType());
409 assert(PointerTy && "PointerType expected");
410
411 Type *ScalarType = PointerTy->getElementType();
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000412 VectorType *VectorType = VectorType::get(ScalarType, Width);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000413
414 return PointerType::getUnqual(VectorType);
415}
416
417Value *BlockGenerator::generateStrideOneLoad(const LoadInst *Load,
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000418 ValueMapT &BBMap) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000419 const Value *Pointer = Load->getPointerOperand();
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000420 Type *VectorPtrType = getVectorPtrTy(Pointer, getVectorWidth());
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000421 Value *NewPointer = getOperand(Pointer, BBMap);
422 Value *VectorPtr = Builder.CreateBitCast(NewPointer, VectorPtrType,
423 "vector_ptr");
424 LoadInst *VecLoad = Builder.CreateLoad(VectorPtr,
425 Load->getName() + "_p_vec_full");
426 if (!Aligned)
427 VecLoad->setAlignment(8);
428
429 return VecLoad;
430}
431
432Value *BlockGenerator::generateStrideZeroLoad(const LoadInst *Load,
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000433 ValueMapT &BBMap) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000434 const Value *Pointer = Load->getPointerOperand();
435 Type *VectorPtrType = getVectorPtrTy(Pointer, 1);
436 Value *NewPointer = getOperand(Pointer, BBMap);
437 Value *VectorPtr = Builder.CreateBitCast(NewPointer, VectorPtrType,
438 Load->getName() + "_p_vec_p");
439 LoadInst *ScalarLoad= Builder.CreateLoad(VectorPtr,
440 Load->getName() + "_p_splat_one");
441
442 if (!Aligned)
443 ScalarLoad->setAlignment(8);
444
Tobias Grossere5b423252012-01-24 16:42:25 +0000445 Constant *SplatVector =
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000446 Constant::getNullValue(VectorType::get(Builder.getInt32Ty(),
447 getVectorWidth()));
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000448
449 Value *VectorLoad = Builder.CreateShuffleVector(ScalarLoad, ScalarLoad,
450 SplatVector,
451 Load->getName()
452 + "_p_splat");
453 return VectorLoad;
454}
455
456Value *BlockGenerator::generateUnknownStrideLoad(const LoadInst *Load,
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000457 VectorValueMapT &ScalarMaps) {
458 int VectorWidth = getVectorWidth();
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000459 const Value *Pointer = Load->getPointerOperand();
460 VectorType *VectorType = VectorType::get(
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000461 dyn_cast<PointerType>(Pointer->getType())->getElementType(), VectorWidth);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000462
463 Value *Vector = UndefValue::get(VectorType);
464
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000465 for (int i = 0; i < VectorWidth; i++) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000466 Value *NewPointer = getOperand(Pointer, ScalarMaps[i]);
467 Value *ScalarLoad = Builder.CreateLoad(NewPointer,
468 Load->getName() + "_p_scalar_");
469 Vector = Builder.CreateInsertElement(Vector, ScalarLoad,
470 Builder.getInt32(i),
471 Load->getName() + "_p_vec_");
472 }
473
474 return Vector;
475}
476
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000477std::vector <Value*> BlockGenerator::getMemoryAccessIndex(
478 __isl_keep isl_map *AccessRelation, Value *BaseAddress) {
479 assert((isl_map_dim(AccessRelation, isl_dim_out) == 1)
480 && "Only single dimensional access functions supported");
481
482 isl_pw_aff *PwAff = isl_map_dim_max(isl_map_copy(AccessRelation), 0);
Tobias Grosser642c4112012-03-02 11:27:25 +0000483 IslGenerator IslGen(Builder);
484 Value *OffsetValue = IslGen.generateIslPwAff(PwAff);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000485
486 PointerType *BaseAddressType = dyn_cast<PointerType>(
487 BaseAddress->getType());
488 Type *ArrayTy = BaseAddressType->getElementType();
489 Type *ArrayElementType = dyn_cast<ArrayType>(ArrayTy)->getElementType();
490 OffsetValue = Builder.CreateSExtOrBitCast(OffsetValue, ArrayElementType);
491
492 std::vector<Value*> IndexArray;
493 Value *NullValue = Constant::getNullValue(ArrayElementType);
494 IndexArray.push_back(NullValue);
495 IndexArray.push_back(OffsetValue);
496 return IndexArray;
497}
498
499Value *BlockGenerator::getNewAccessOperand(
500 __isl_keep isl_map *NewAccessRelation, Value *BaseAddress, const Value
501 *OldOperand, ValueMapT &BBMap) {
502 std::vector<Value*> IndexArray = getMemoryAccessIndex(NewAccessRelation,
503 BaseAddress);
504 Value *NewOperand = Builder.CreateGEP(BaseAddress, IndexArray,
505 "p_newarrayidx_");
506 return NewOperand;
507}
508
509Value *BlockGenerator::generateLocationAccessed(const Instruction *Inst,
510 const Value *Pointer,
511 ValueMapT &BBMap ) {
512 MemoryAccess &Access = Statement.getAccessFor(Inst);
513 isl_map *CurrentAccessRelation = Access.getAccessRelation();
514 isl_map *NewAccessRelation = Access.getNewAccessRelation();
515
516 assert(isl_map_has_equal_space(CurrentAccessRelation, NewAccessRelation)
517 && "Current and new access function use different spaces");
518
519 Value *NewPointer;
520
521 if (!NewAccessRelation) {
522 NewPointer = getOperand(Pointer, BBMap);
523 } else {
524 Value *BaseAddress = const_cast<Value*>(Access.getBaseAddr());
525 NewPointer = getNewAccessOperand(NewAccessRelation, BaseAddress, Pointer,
526 BBMap);
527 }
528
529 isl_map_free(CurrentAccessRelation);
530 isl_map_free(NewAccessRelation);
531 return NewPointer;
532}
533
534Value *BlockGenerator::generateScalarLoad(const LoadInst *Load,
535 ValueMapT &BBMap) {
536 const Value *Pointer = Load->getPointerOperand();
537 const Instruction *Inst = dyn_cast<Instruction>(Load);
538 Value *NewPointer = generateLocationAccessed(Inst, Pointer, BBMap);
539 Value *ScalarLoad = Builder.CreateLoad(NewPointer,
540 Load->getName() + "_p_scalar_");
541 return ScalarLoad;
542}
543
Tobias Grosserfc1153f2012-03-02 11:27:15 +0000544void BlockGenerator::generateVectorLoad(const LoadInst *Load,
545 ValueMapT &VectorMap,
546 VectorValueMapT &ScalarMaps) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000547 Value *NewLoad;
548
549 MemoryAccess &Access = Statement.getAccessFor(Load);
550
551 assert(ScatteringDomain && "No scattering domain available");
552
553 if (Access.isStrideZero(isl_set_copy(ScatteringDomain)))
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000554 NewLoad = generateStrideZeroLoad(Load, ScalarMaps[0]);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000555 else if (Access.isStrideOne(isl_set_copy(ScatteringDomain)))
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000556 NewLoad = generateStrideOneLoad(Load, ScalarMaps[0]);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000557 else
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000558 NewLoad = generateUnknownStrideLoad(Load, ScalarMaps);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000559
560 VectorMap[Load] = NewLoad;
561}
562
Tobias Grosser8b4bf8b2012-03-02 11:27:11 +0000563void BlockGenerator::copyVectorUnaryInst(const UnaryInstruction *Inst,
564 ValueMapT &BBMap,
565 ValueMapT &VectorMap) {
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000566 int VectorWidth = getVectorWidth();
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000567 Value *NewOperand = getOperand(Inst->getOperand(0), BBMap, &VectorMap);
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000568 NewOperand = makeVectorOperand(NewOperand);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000569
570 assert(isa<CastInst>(Inst) && "Can not generate vector code for instruction");
571
572 const CastInst *Cast = dyn_cast<CastInst>(Inst);
573 VectorType *DestType = VectorType::get(Inst->getType(), VectorWidth);
574 VectorMap[Inst] = Builder.CreateCast(Cast->getOpcode(), NewOperand, DestType);
575}
576
Tobias Grosser8b4bf8b2012-03-02 11:27:11 +0000577void BlockGenerator::copyVectorBinInst(const BinaryOperator *Inst,
578 ValueMapT &BBMap, ValueMapT &VectorMap) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000579 Value *OpZero = Inst->getOperand(0);
580 Value *OpOne = Inst->getOperand(1);
581
582 Value *NewOpZero, *NewOpOne;
583 NewOpZero = getOperand(OpZero, BBMap, &VectorMap);
584 NewOpOne = getOperand(OpOne, BBMap, &VectorMap);
585
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000586 NewOpZero = makeVectorOperand(NewOpZero);
587 NewOpOne = makeVectorOperand(NewOpOne);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000588
589 Value *NewInst = Builder.CreateBinOp(Inst->getOpcode(), NewOpZero,
590 NewOpOne,
591 Inst->getName() + "p_vec");
592 VectorMap[Inst] = NewInst;
593}
594
595void BlockGenerator::copyVectorStore(const StoreInst *Store, ValueMapT &BBMap,
596 ValueMapT &VectorMap,
Tobias Grosser8927a442012-03-02 11:27:05 +0000597 VectorValueMapT &ScalarMaps) {
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000598 int VectorWidth = getVectorWidth();
599
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000600 MemoryAccess &Access = Statement.getAccessFor(Store);
601
602 assert(ScatteringDomain && "No scattering domain available");
603
604 const Value *Pointer = Store->getPointerOperand();
605 Value *Vector = getOperand(Store->getValueOperand(), BBMap, &VectorMap);
606
607 if (Access.isStrideOne(isl_set_copy(ScatteringDomain))) {
608 Type *VectorPtrType = getVectorPtrTy(Pointer, VectorWidth);
609 Value *NewPointer = getOperand(Pointer, BBMap, &VectorMap);
610
611 Value *VectorPtr = Builder.CreateBitCast(NewPointer, VectorPtrType,
612 "vector_ptr");
613 StoreInst *Store = Builder.CreateStore(Vector, VectorPtr);
614
615 if (!Aligned)
616 Store->setAlignment(8);
617 } else {
618 for (unsigned i = 0; i < ScalarMaps.size(); i++) {
619 Value *Scalar = Builder.CreateExtractElement(Vector,
620 Builder.getInt32(i));
621 Value *NewPointer = getOperand(Pointer, ScalarMaps[i]);
622 Builder.CreateStore(Scalar, NewPointer);
623 }
624 }
625}
626
627void BlockGenerator::copyInstScalar(const Instruction *Inst, ValueMapT &BBMap) {
628 Instruction *NewInst = Inst->clone();
629
630 // Replace old operands with the new ones.
631 for (Instruction::const_op_iterator OI = Inst->op_begin(),
632 OE = Inst->op_end(); OI != OE; ++OI) {
633 Value *OldOperand = *OI;
634 Value *NewOperand = getOperand(OldOperand, BBMap);
635
636 if (!NewOperand) {
637 assert(!isa<StoreInst>(NewInst)
638 && "Store instructions are always needed!");
639 delete NewInst;
640 return;
641 }
642
643 NewInst->replaceUsesOfWith(OldOperand, NewOperand);
644 }
645
646 Builder.Insert(NewInst);
647 BBMap[Inst] = NewInst;
648
649 if (!NewInst->getType()->isVoidTy())
650 NewInst->setName("p_" + Inst->getName());
651}
652
653bool BlockGenerator::hasVectorOperands(const Instruction *Inst,
654 ValueMapT &VectorMap) {
655 for (Instruction::const_op_iterator OI = Inst->op_begin(),
656 OE = Inst->op_end(); OI != OE; ++OI)
657 if (VectorMap.count(*OI))
658 return true;
659 return false;
660}
661
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000662int BlockGenerator::getVectorWidth() {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000663 return ValueMaps.size();
664}
665
666bool BlockGenerator::isVectorBlock() {
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000667 return getVectorWidth() > 1;
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000668}
669
Tobias Grosser32152cb2012-03-02 11:27:18 +0000670void BlockGenerator::copyVectorInstruction(const Instruction *Inst,
671 ValueMapT &VectorMap,
672 VectorValueMapT &ScalarMaps) {
673 if (const LoadInst *Load = dyn_cast<LoadInst>(Inst)) {
674 generateVectorLoad(Load, VectorMap, ScalarMaps);
675 return;
676 }
677
678 if (hasVectorOperands(Inst, VectorMap)) {
679 if (const StoreInst *Store = dyn_cast<StoreInst>(Inst)) {
680 copyVectorStore(Store, ScalarMaps[0], VectorMap, ScalarMaps);
681 return;
682 }
683
684 if (const UnaryInstruction *Unary = dyn_cast<UnaryInstruction>(Inst)) {
685 copyVectorUnaryInst(Unary, ScalarMaps[0], VectorMap);
686 return;
687 }
688
689 if (const BinaryOperator *Binary = dyn_cast<BinaryOperator>(Inst)) {
690 copyVectorBinInst(Binary, ScalarMaps[0], VectorMap);
691 return;
692 }
693
694 llvm_unreachable("Cannot issue vector code for this instruction");
695 }
696
697 for (int VectorLane = 0; VectorLane < getVectorWidth(); VectorLane++)
698 copyInstScalar(Inst, ScalarMaps[VectorLane]);
699}
700
Tobias Grosserfc1153f2012-03-02 11:27:15 +0000701void BlockGenerator::copyInstruction(const Instruction *Inst,
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000702 ValueMapT &VectorMap,
Tobias Grosserfc1153f2012-03-02 11:27:15 +0000703 VectorValueMapT &ScalarMaps) {
Tobias Grosserb35d9c12012-03-02 11:27:08 +0000704 // Terminator instructions control the control flow. They are explicitly
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000705 // expressed in the clast and do not need to be copied.
706 if (Inst->isTerminator())
707 return;
708
709 if (isVectorBlock()) {
Tobias Grosser32152cb2012-03-02 11:27:18 +0000710 copyVectorInstruction(Inst, VectorMap, ScalarMaps);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000711 return;
712 }
713
Tobias Grosserfc1153f2012-03-02 11:27:15 +0000714 if (const LoadInst *Load = dyn_cast<LoadInst>(Inst)) {
715 ScalarMaps[0][Load] = generateScalarLoad(Load, ScalarMaps[0]);
716 return;
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000717 }
718
Tobias Grosserfc1153f2012-03-02 11:27:15 +0000719 copyInstScalar(Inst, ScalarMaps[0]);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000720}
721
Tobias Grosser8412cda2012-03-02 11:26:55 +0000722void BlockGenerator::copyBB() {
Tobias Grosser14bcbd52012-03-02 11:26:52 +0000723 BasicBlock *BB = Statement.getBasicBlock();
Tobias Grosser0ac92142012-02-14 14:02:27 +0000724 BasicBlock *CopyBB = SplitBlock(Builder.GetInsertBlock(),
725 Builder.GetInsertPoint(), P);
Tobias Grosserb61e6312012-02-15 09:58:46 +0000726 CopyBB->setName("polly.stmt." + BB->getName());
Tobias Grosser0ac92142012-02-14 14:02:27 +0000727 Builder.SetInsertPoint(CopyBB->begin());
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000728
729 // Create two maps that store the mapping from the original instructions of
730 // the old basic block to their copies in the new basic block. Those maps
731 // are basic block local.
732 //
733 // As vector code generation is supported there is one map for scalar values
734 // and one for vector values.
735 //
736 // In case we just do scalar code generation, the vectorMap is not used and
737 // the scalarMap has just one dimension, which contains the mapping.
738 //
739 // In case vector code generation is done, an instruction may either appear
740 // in the vector map once (as it is calculating >vectorwidth< values at a
741 // time. Or (if the values are calculated using scalar operations), it
742 // appears once in every dimension of the scalarMap.
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000743 VectorValueMapT ScalarBlockMap(getVectorWidth());
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000744 ValueMapT VectorBlockMap;
745
746 for (BasicBlock::const_iterator II = BB->begin(), IE = BB->end();
747 II != IE; ++II)
Tobias Grosserfc1153f2012-03-02 11:27:15 +0000748 copyInstruction(II, VectorBlockMap, ScalarBlockMap);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000749}
750
Tobias Grosser75805372011-04-29 06:27:02 +0000751/// Class to generate LLVM-IR that calculates the value of a clast_expr.
752class ClastExpCodeGen {
753 IRBuilder<> &Builder;
754 const CharMapT *IVS;
755
Tobias Grosserbb137e32012-01-24 16:42:28 +0000756 Value *codegen(const clast_name *e, Type *Ty);
757 Value *codegen(const clast_term *e, Type *Ty);
758 Value *codegen(const clast_binary *e, Type *Ty);
759 Value *codegen(const clast_reduction *r, Type *Ty);
Tobias Grosser75805372011-04-29 06:27:02 +0000760public:
761
762 // A generator for clast expressions.
763 //
764 // @param B The IRBuilder that defines where the code to calculate the
765 // clast expressions should be inserted.
766 // @param IVMAP A Map that translates strings describing the induction
767 // variables to the Values* that represent these variables
768 // on the LLVM side.
Tobias Grosserbb137e32012-01-24 16:42:28 +0000769 ClastExpCodeGen(IRBuilder<> &B, CharMapT *IVMap);
Tobias Grosser75805372011-04-29 06:27:02 +0000770
771 // Generates code to calculate a given clast expression.
772 //
773 // @param e The expression to calculate.
774 // @return The Value that holds the result.
Tobias Grosserbb137e32012-01-24 16:42:28 +0000775 Value *codegen(const clast_expr *e, Type *Ty);
Tobias Grosser75805372011-04-29 06:27:02 +0000776
777 // @brief Reset the CharMap.
778 //
779 // This function is called to reset the CharMap to new one, while generating
780 // OpenMP code.
Tobias Grosserbb137e32012-01-24 16:42:28 +0000781 void setIVS(CharMapT *IVSNew);
782};
783
784Value *ClastExpCodeGen::codegen(const clast_name *e, Type *Ty) {
785 CharMapT::const_iterator I = IVS->find(e->name);
786
787 assert(I != IVS->end() && "Clast name not found");
788
789 return Builder.CreateSExtOrBitCast(I->second, Ty);
790}
791
792Value *ClastExpCodeGen::codegen(const clast_term *e, Type *Ty) {
793 APInt a = APInt_from_MPZ(e->val);
794
795 Value *ConstOne = ConstantInt::get(Builder.getContext(), a);
796 ConstOne = Builder.CreateSExtOrBitCast(ConstOne, Ty);
797
798 if (!e->var)
799 return ConstOne;
800
801 Value *var = codegen(e->var, Ty);
802 return Builder.CreateMul(ConstOne, var);
803}
804
805Value *ClastExpCodeGen::codegen(const clast_binary *e, Type *Ty) {
806 Value *LHS = codegen(e->LHS, Ty);
807
808 APInt RHS_AP = APInt_from_MPZ(e->RHS);
809
810 Value *RHS = ConstantInt::get(Builder.getContext(), RHS_AP);
811 RHS = Builder.CreateSExtOrBitCast(RHS, Ty);
812
813 switch (e->type) {
814 case clast_bin_mod:
815 return Builder.CreateSRem(LHS, RHS);
816 case clast_bin_fdiv:
817 {
Tobias Grosser9a44b972012-02-16 14:13:19 +0000818 // floord(n,d) ((n < 0) ? (n - d + 1) : n) / d
Tobias Grosser906eafe2012-02-16 09:56:10 +0000819 Value *One = ConstantInt::get(Ty, 1);
820 Value *Zero = ConstantInt::get(Ty, 0);
Tobias Grosser9a44b972012-02-16 14:13:19 +0000821 Value *Sum1 = Builder.CreateSub(LHS, RHS);
822 Value *Sum2 = Builder.CreateAdd(Sum1, One);
823 Value *isNegative = Builder.CreateICmpSLT(LHS, Zero);
824 Value *Dividend = Builder.CreateSelect(isNegative, Sum2, LHS);
825 return Builder.CreateSDiv(Dividend, RHS);
Tobias Grosserbb137e32012-01-24 16:42:28 +0000826 }
827 case clast_bin_cdiv:
828 {
Tobias Grosser9a44b972012-02-16 14:13:19 +0000829 // ceild(n,d) ((n < 0) ? n : (n + d - 1)) / d
830 Value *One = ConstantInt::get(Ty, 1);
Tobias Grosser906eafe2012-02-16 09:56:10 +0000831 Value *Zero = ConstantInt::get(Ty, 0);
Tobias Grosser9a44b972012-02-16 14:13:19 +0000832 Value *Sum1 = Builder.CreateAdd(LHS, RHS);
833 Value *Sum2 = Builder.CreateSub(Sum1, One);
834 Value *isNegative = Builder.CreateICmpSLT(LHS, Zero);
835 Value *Dividend = Builder.CreateSelect(isNegative, LHS, Sum2);
836 return Builder.CreateSDiv(Dividend, RHS);
Tobias Grosserbb137e32012-01-24 16:42:28 +0000837 }
838 case clast_bin_div:
839 return Builder.CreateSDiv(LHS, RHS);
840 };
841
842 llvm_unreachable("Unknown clast binary expression type");
843}
844
845Value *ClastExpCodeGen::codegen(const clast_reduction *r, Type *Ty) {
846 assert(( r->type == clast_red_min
847 || r->type == clast_red_max
848 || r->type == clast_red_sum)
849 && "Clast reduction type not supported");
850 Value *old = codegen(r->elts[0], Ty);
851
852 for (int i=1; i < r->n; ++i) {
853 Value *exprValue = codegen(r->elts[i], Ty);
854
855 switch (r->type) {
856 case clast_red_min:
857 {
858 Value *cmp = Builder.CreateICmpSLT(old, exprValue);
859 old = Builder.CreateSelect(cmp, old, exprValue);
860 break;
861 }
862 case clast_red_max:
863 {
864 Value *cmp = Builder.CreateICmpSGT(old, exprValue);
865 old = Builder.CreateSelect(cmp, old, exprValue);
866 break;
867 }
868 case clast_red_sum:
869 old = Builder.CreateAdd(old, exprValue);
870 break;
Tobias Grosserbb137e32012-01-24 16:42:28 +0000871 }
Tobias Grosser75805372011-04-29 06:27:02 +0000872 }
873
Tobias Grosserbb137e32012-01-24 16:42:28 +0000874 return old;
875}
876
877ClastExpCodeGen::ClastExpCodeGen(IRBuilder<> &B, CharMapT *IVMap)
878 : Builder(B), IVS(IVMap) {}
879
880Value *ClastExpCodeGen::codegen(const clast_expr *e, Type *Ty) {
881 switch(e->type) {
882 case clast_expr_name:
883 return codegen((const clast_name *)e, Ty);
884 case clast_expr_term:
885 return codegen((const clast_term *)e, Ty);
886 case clast_expr_bin:
887 return codegen((const clast_binary *)e, Ty);
888 case clast_expr_red:
889 return codegen((const clast_reduction *)e, Ty);
890 }
891
892 llvm_unreachable("Unknown clast expression!");
893}
894
895void ClastExpCodeGen::setIVS(CharMapT *IVSNew) {
896 IVS = IVSNew;
897}
Tobias Grosser75805372011-04-29 06:27:02 +0000898
899class ClastStmtCodeGen {
900 // The Scop we code generate.
901 Scop *S;
902 ScalarEvolution &SE;
Tobias Grosser75805372011-04-29 06:27:02 +0000903 DominatorTree *DT;
Hongbin Zheng94c5df12011-05-06 02:38:20 +0000904 ScopDetection *SD;
Tobias Grosser75805372011-04-29 06:27:02 +0000905 Dependences *DP;
906 TargetData *TD;
Tobias Grosser0ac92142012-02-14 14:02:27 +0000907 Pass *P;
Tobias Grosser75805372011-04-29 06:27:02 +0000908
909 // The Builder specifies the current location to code generate at.
910 IRBuilder<> &Builder;
911
912 // Map the Values from the old code to their counterparts in the new code.
913 ValueMapT ValueMap;
914
915 // clastVars maps from the textual representation of a clast variable to its
916 // current *Value. clast variables are scheduling variables, original
917 // induction variables or parameters. They are used either in loop bounds or
918 // to define the statement instance that is executed.
919 //
920 // for (s = 0; s < n + 3; ++i)
921 // for (t = s; t < m; ++j)
922 // Stmt(i = s + 3 * m, j = t);
923 //
924 // {s,t,i,j,n,m} is the set of clast variables in this clast.
925 CharMapT *clastVars;
926
927 // Codegenerator for clast expressions.
928 ClastExpCodeGen ExpGen;
929
930 // Do we currently generate parallel code?
931 bool parallelCodeGeneration;
932
933 std::vector<std::string> parallelLoops;
934
935public:
936
Tobias Grosser9bc5eb082012-01-24 16:42:32 +0000937 const std::vector<std::string> &getParallelLoops();
Tobias Grosser75805372011-04-29 06:27:02 +0000938
939 protected:
Tobias Grosser9bc5eb082012-01-24 16:42:32 +0000940 void codegen(const clast_assignment *a);
Tobias Grosser75805372011-04-29 06:27:02 +0000941
942 void codegen(const clast_assignment *a, ScopStmt *Statement,
943 unsigned Dimension, int vectorDim,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +0000944 std::vector<ValueMapT> *VectorVMap = 0);
Tobias Grosser75805372011-04-29 06:27:02 +0000945
946 void codegenSubstitutions(const clast_stmt *Assignment,
947 ScopStmt *Statement, int vectorDim = 0,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +0000948 std::vector<ValueMapT> *VectorVMap = 0);
Tobias Grosser75805372011-04-29 06:27:02 +0000949
950 void codegen(const clast_user_stmt *u, std::vector<Value*> *IVS = NULL,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +0000951 const char *iterator = NULL, isl_set *scatteringDomain = 0);
Tobias Grosser75805372011-04-29 06:27:02 +0000952
Tobias Grosser9bc5eb082012-01-24 16:42:32 +0000953 void codegen(const clast_block *b);
Tobias Grosser75805372011-04-29 06:27:02 +0000954
955 /// @brief Create a classical sequential loop.
Tobias Grosser545bc312011-12-06 10:48:27 +0000956 void codegenForSequential(const clast_for *f, Value *LowerBound = 0,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +0000957 Value *UpperBound = 0);
Tobias Grosser75805372011-04-29 06:27:02 +0000958
Tobias Grosser75805372011-04-29 06:27:02 +0000959 /// @brief Add a new definition of an openmp subfunction.
Tobias Grosser9bc5eb082012-01-24 16:42:32 +0000960 Function *addOpenMPSubfunction(Module *M);
Tobias Grosser75805372011-04-29 06:27:02 +0000961
962 /// @brief Add values to the OpenMP structure.
963 ///
964 /// Create the subfunction structure and add the values from the list.
965 Value *addValuesToOpenMPStruct(SetVector<Value*> OMPDataVals,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +0000966 Function *SubFunction);
Tobias Grosser75805372011-04-29 06:27:02 +0000967
968 /// @brief Create OpenMP structure values.
969 ///
970 /// Create a list of values that has to be stored into the subfuncition
971 /// structure.
Tobias Grosser9bc5eb082012-01-24 16:42:32 +0000972 SetVector<Value*> createOpenMPStructValues();
Tobias Grosser75805372011-04-29 06:27:02 +0000973
974 /// @brief Extract the values from the subfunction parameter.
975 ///
976 /// Extract the values from the subfunction parameter and update the clast
977 /// variables to point to the new values.
978 void extractValuesFromOpenMPStruct(CharMapT *clastVarsOMP,
979 SetVector<Value*> OMPDataVals,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +0000980 Value *userContext);
Tobias Grosser75805372011-04-29 06:27:02 +0000981
982 /// @brief Add body to the subfunction.
983 void addOpenMPSubfunctionBody(Function *FN, const clast_for *f,
984 Value *structData,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +0000985 SetVector<Value*> OMPDataVals);
Tobias Grosser75805372011-04-29 06:27:02 +0000986
987 /// @brief Create an OpenMP parallel for loop.
988 ///
989 /// This loop reflects a loop as if it would have been created by an OpenMP
990 /// statement.
Tobias Grosser9bc5eb082012-01-24 16:42:32 +0000991 void codegenForOpenMP(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +0000992
Tobias Grosser9bc5eb082012-01-24 16:42:32 +0000993 bool isInnermostLoop(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +0000994
995 /// @brief Get the number of loop iterations for this loop.
996 /// @param f The clast for loop to check.
Tobias Grosser9bc5eb082012-01-24 16:42:32 +0000997 int getNumberOfIterations(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +0000998
999 /// @brief Create vector instructions for this loop.
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001000 void codegenForVector(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +00001001
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001002 void codegen(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +00001003
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001004 Value *codegen(const clast_equation *eq);
Tobias Grosser75805372011-04-29 06:27:02 +00001005
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001006 void codegen(const clast_guard *g);
Tobias Grosser75805372011-04-29 06:27:02 +00001007
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001008 void codegen(const clast_stmt *stmt);
Tobias Grosser75805372011-04-29 06:27:02 +00001009
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001010 void addParameters(const CloogNames *names);
Tobias Grosser75805372011-04-29 06:27:02 +00001011
1012 public:
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001013 void codegen(const clast_root *r);
Tobias Grosser75805372011-04-29 06:27:02 +00001014
1015 ClastStmtCodeGen(Scop *scop, ScalarEvolution &se, DominatorTree *dt,
Hongbin Zheng94c5df12011-05-06 02:38:20 +00001016 ScopDetection *sd, Dependences *dp, TargetData *td,
Tobias Grosser0ac92142012-02-14 14:02:27 +00001017 IRBuilder<> &B, Pass *P);
Tobias Grosser75805372011-04-29 06:27:02 +00001018};
1019}
1020
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001021const std::vector<std::string> &ClastStmtCodeGen::getParallelLoops() {
1022 return parallelLoops;
1023}
1024
1025void ClastStmtCodeGen::codegen(const clast_assignment *a) {
1026 Value *V= ExpGen.codegen(a->RHS, TD->getIntPtrType(Builder.getContext()));
1027 (*clastVars)[a->LHS] = V;
1028}
1029
1030void ClastStmtCodeGen::codegen(const clast_assignment *a, ScopStmt *Statement,
1031 unsigned Dimension, int vectorDim,
1032 std::vector<ValueMapT> *VectorVMap) {
1033 Value *RHS = ExpGen.codegen(a->RHS,
1034 TD->getIntPtrType(Builder.getContext()));
1035
1036 assert(!a->LHS && "Statement assignments do not have left hand side");
1037 const PHINode *PN;
1038 PN = Statement->getInductionVariableForDimension(Dimension);
1039 const Value *V = PN;
1040
1041 if (VectorVMap)
1042 (*VectorVMap)[vectorDim][V] = RHS;
1043
1044 ValueMap[V] = RHS;
1045}
1046
1047void ClastStmtCodeGen::codegenSubstitutions(const clast_stmt *Assignment,
1048 ScopStmt *Statement, int vectorDim,
1049 std::vector<ValueMapT> *VectorVMap) {
1050 int Dimension = 0;
1051
1052 while (Assignment) {
1053 assert(CLAST_STMT_IS_A(Assignment, stmt_ass)
1054 && "Substitions are expected to be assignments");
1055 codegen((const clast_assignment *)Assignment, Statement, Dimension,
1056 vectorDim, VectorVMap);
1057 Assignment = Assignment->next;
1058 Dimension++;
1059 }
1060}
1061
1062void ClastStmtCodeGen::codegen(const clast_user_stmt *u,
1063 std::vector<Value*> *IVS , const char *iterator,
Tobias Grosser14bcbd52012-03-02 11:26:52 +00001064 isl_set *Domain) {
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001065 ScopStmt *Statement = (ScopStmt *)u->statement->usr;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001066
1067 if (u->substitutions)
1068 codegenSubstitutions(u->substitutions, Statement);
1069
1070 int vectorDimensions = IVS ? IVS->size() : 1;
1071
Tobias Grosser14bcbd52012-03-02 11:26:52 +00001072 VectorValueMapT VectorMap(vectorDimensions);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001073
1074 if (IVS) {
1075 assert (u->substitutions && "Substitutions expected!");
1076 int i = 0;
1077 for (std::vector<Value*>::iterator II = IVS->begin(), IE = IVS->end();
1078 II != IE; ++II) {
1079 (*clastVars)[iterator] = *II;
Tobias Grosser14bcbd52012-03-02 11:26:52 +00001080 codegenSubstitutions(u->substitutions, Statement, i, &VectorMap);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001081 i++;
1082 }
1083 }
1084
Tobias Grosser14bcbd52012-03-02 11:26:52 +00001085 BlockGenerator::generate(Builder, ValueMap, VectorMap, *Statement, Domain, P);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001086}
1087
1088void ClastStmtCodeGen::codegen(const clast_block *b) {
1089 if (b->body)
1090 codegen(b->body);
1091}
1092
1093void ClastStmtCodeGen::codegenForSequential(const clast_for *f,
1094 Value *LowerBound,
1095 Value *UpperBound) {
1096 APInt Stride;
Tobias Grosser0ac92142012-02-14 14:02:27 +00001097 BasicBlock *AfterBB;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001098 Type *IntPtrTy;
1099
1100 Stride = APInt_from_MPZ(f->stride);
1101 IntPtrTy = TD->getIntPtrType(Builder.getContext());
1102
1103 // The value of lowerbound and upperbound will be supplied, if this
1104 // function is called while generating OpenMP code. Otherwise get
1105 // the values.
1106 assert(!!LowerBound == !!UpperBound && "Either give both bounds or none");
1107
1108 if (LowerBound == 0) {
1109 LowerBound = ExpGen.codegen(f->LB, IntPtrTy);
1110 UpperBound = ExpGen.codegen(f->UB, IntPtrTy);
1111 }
1112
Tobias Grosser0ac92142012-02-14 14:02:27 +00001113 Value *IV = createLoop(&Builder, LowerBound, UpperBound, Stride, DT, P,
1114 &AfterBB);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001115
1116 // Add loop iv to symbols.
1117 (*clastVars)[f->iterator] = IV;
1118
1119 if (f->body)
1120 codegen(f->body);
1121
1122 // Loop is finished, so remove its iv from the live symbols.
1123 clastVars->erase(f->iterator);
Tobias Grosser0ac92142012-02-14 14:02:27 +00001124 Builder.SetInsertPoint(AfterBB->begin());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001125}
1126
1127Function *ClastStmtCodeGen::addOpenMPSubfunction(Module *M) {
1128 Function *F = Builder.GetInsertBlock()->getParent();
1129 std::vector<Type*> Arguments(1, Builder.getInt8PtrTy());
1130 FunctionType *FT = FunctionType::get(Builder.getVoidTy(), Arguments, false);
1131 Function *FN = Function::Create(FT, Function::InternalLinkage,
1132 F->getName() + ".omp_subfn", M);
1133 // Do not run any polly pass on the new function.
1134 SD->markFunctionAsInvalid(FN);
1135
1136 Function::arg_iterator AI = FN->arg_begin();
1137 AI->setName("omp.userContext");
1138
1139 return FN;
1140}
1141
1142Value *ClastStmtCodeGen::addValuesToOpenMPStruct(SetVector<Value*> OMPDataVals,
1143 Function *SubFunction) {
1144 std::vector<Type*> structMembers;
1145
1146 // Create the structure.
1147 for (unsigned i = 0; i < OMPDataVals.size(); i++)
1148 structMembers.push_back(OMPDataVals[i]->getType());
1149
1150 StructType *structTy = StructType::get(Builder.getContext(),
1151 structMembers);
1152 // Store the values into the structure.
1153 Value *structData = Builder.CreateAlloca(structTy, 0, "omp.userContext");
1154 for (unsigned i = 0; i < OMPDataVals.size(); i++) {
1155 Value *storeAddr = Builder.CreateStructGEP(structData, i);
1156 Builder.CreateStore(OMPDataVals[i], storeAddr);
1157 }
1158
1159 return structData;
1160}
1161
1162SetVector<Value*> ClastStmtCodeGen::createOpenMPStructValues() {
1163 SetVector<Value*> OMPDataVals;
1164
1165 // Push the clast variables available in the clastVars.
1166 for (CharMapT::iterator I = clastVars->begin(), E = clastVars->end();
1167 I != E; I++)
1168 OMPDataVals.insert(I->second);
1169
1170 // Push the base addresses of memory references.
1171 for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI) {
1172 ScopStmt *Stmt = *SI;
1173 for (SmallVector<MemoryAccess*, 8>::iterator I = Stmt->memacc_begin(),
1174 E = Stmt->memacc_end(); I != E; ++I) {
1175 Value *BaseAddr = const_cast<Value*>((*I)->getBaseAddr());
1176 OMPDataVals.insert((BaseAddr));
1177 }
1178 }
1179
1180 return OMPDataVals;
1181}
1182
1183void ClastStmtCodeGen::extractValuesFromOpenMPStruct(CharMapT *clastVarsOMP,
1184 SetVector<Value*> OMPDataVals, Value *userContext) {
1185 // Extract the clast variables.
1186 unsigned i = 0;
1187 for (CharMapT::iterator I = clastVars->begin(), E = clastVars->end();
1188 I != E; I++) {
1189 Value *loadAddr = Builder.CreateStructGEP(userContext, i);
1190 (*clastVarsOMP)[I->first] = Builder.CreateLoad(loadAddr);
1191 i++;
1192 }
1193
1194 // Extract the base addresses of memory references.
1195 for (unsigned j = i; j < OMPDataVals.size(); j++) {
1196 Value *loadAddr = Builder.CreateStructGEP(userContext, j);
1197 Value *baseAddr = OMPDataVals[j];
1198 ValueMap[baseAddr] = Builder.CreateLoad(loadAddr);
1199 }
1200}
1201
1202void ClastStmtCodeGen::addOpenMPSubfunctionBody(Function *FN,
1203 const clast_for *f,
1204 Value *structData,
1205 SetVector<Value*> OMPDataVals) {
1206 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
1207 LLVMContext &Context = FN->getContext();
1208 IntegerType *intPtrTy = TD->getIntPtrType(Context);
1209
1210 // Store the previous basic block.
Tobias Grosser0ac92142012-02-14 14:02:27 +00001211 BasicBlock::iterator PrevInsertPoint = Builder.GetInsertPoint();
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001212 BasicBlock *PrevBB = Builder.GetInsertBlock();
1213
1214 // Create basic blocks.
1215 BasicBlock *HeaderBB = BasicBlock::Create(Context, "omp.setup", FN);
1216 BasicBlock *ExitBB = BasicBlock::Create(Context, "omp.exit", FN);
1217 BasicBlock *checkNextBB = BasicBlock::Create(Context, "omp.checkNext", FN);
1218 BasicBlock *loadIVBoundsBB = BasicBlock::Create(Context, "omp.loadIVBounds",
1219 FN);
1220
1221 DT->addNewBlock(HeaderBB, PrevBB);
1222 DT->addNewBlock(ExitBB, HeaderBB);
1223 DT->addNewBlock(checkNextBB, HeaderBB);
1224 DT->addNewBlock(loadIVBoundsBB, HeaderBB);
1225
1226 // Fill up basic block HeaderBB.
1227 Builder.SetInsertPoint(HeaderBB);
1228 Value *lowerBoundPtr = Builder.CreateAlloca(intPtrTy, 0,
1229 "omp.lowerBoundPtr");
1230 Value *upperBoundPtr = Builder.CreateAlloca(intPtrTy, 0,
1231 "omp.upperBoundPtr");
1232 Value *userContext = Builder.CreateBitCast(FN->arg_begin(),
1233 structData->getType(),
1234 "omp.userContext");
1235
1236 CharMapT clastVarsOMP;
1237 extractValuesFromOpenMPStruct(&clastVarsOMP, OMPDataVals, userContext);
1238
1239 Builder.CreateBr(checkNextBB);
1240
1241 // Add code to check if another set of iterations will be executed.
1242 Builder.SetInsertPoint(checkNextBB);
1243 Function *runtimeNextFunction = M->getFunction("GOMP_loop_runtime_next");
1244 Value *ret1 = Builder.CreateCall2(runtimeNextFunction,
1245 lowerBoundPtr, upperBoundPtr);
1246 Value *hasNextSchedule = Builder.CreateTrunc(ret1, Builder.getInt1Ty(),
1247 "omp.hasNextScheduleBlock");
1248 Builder.CreateCondBr(hasNextSchedule, loadIVBoundsBB, ExitBB);
1249
1250 // Add code to to load the iv bounds for this set of iterations.
1251 Builder.SetInsertPoint(loadIVBoundsBB);
1252 Value *lowerBound = Builder.CreateLoad(lowerBoundPtr, "omp.lowerBound");
1253 Value *upperBound = Builder.CreateLoad(upperBoundPtr, "omp.upperBound");
1254
1255 // Subtract one as the upper bound provided by openmp is a < comparison
1256 // whereas the codegenForSequential function creates a <= comparison.
1257 upperBound = Builder.CreateSub(upperBound, ConstantInt::get(intPtrTy, 1),
1258 "omp.upperBoundAdjusted");
1259
1260 // Use clastVarsOMP during code generation of the OpenMP subfunction.
1261 CharMapT *oldClastVars = clastVars;
1262 clastVars = &clastVarsOMP;
1263 ExpGen.setIVS(&clastVarsOMP);
1264
Tobias Grosser0ac92142012-02-14 14:02:27 +00001265 Builder.CreateBr(checkNextBB);
1266 Builder.SetInsertPoint(--Builder.GetInsertPoint());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001267 codegenForSequential(f, lowerBound, upperBound);
1268
1269 // Restore the old clastVars.
1270 clastVars = oldClastVars;
1271 ExpGen.setIVS(oldClastVars);
1272
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001273 // Add code to terminate this openmp subfunction.
1274 Builder.SetInsertPoint(ExitBB);
1275 Function *endnowaitFunction = M->getFunction("GOMP_loop_end_nowait");
1276 Builder.CreateCall(endnowaitFunction);
1277 Builder.CreateRetVoid();
1278
Tobias Grosser0ac92142012-02-14 14:02:27 +00001279 // Restore the previous insert point.
1280 Builder.SetInsertPoint(PrevInsertPoint);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001281}
1282
1283void ClastStmtCodeGen::codegenForOpenMP(const clast_for *f) {
1284 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
1285 IntegerType *intPtrTy = TD->getIntPtrType(Builder.getContext());
1286
1287 Function *SubFunction = addOpenMPSubfunction(M);
1288 SetVector<Value*> OMPDataVals = createOpenMPStructValues();
1289 Value *structData = addValuesToOpenMPStruct(OMPDataVals, SubFunction);
1290
1291 addOpenMPSubfunctionBody(SubFunction, f, structData, OMPDataVals);
1292
1293 // Create call for GOMP_parallel_loop_runtime_start.
1294 Value *subfunctionParam = Builder.CreateBitCast(structData,
1295 Builder.getInt8PtrTy(),
1296 "omp_data");
1297
1298 Value *numberOfThreads = Builder.getInt32(0);
1299 Value *lowerBound = ExpGen.codegen(f->LB, intPtrTy);
1300 Value *upperBound = ExpGen.codegen(f->UB, intPtrTy);
1301
1302 // Add one as the upper bound provided by openmp is a < comparison
1303 // whereas the codegenForSequential function creates a <= comparison.
1304 upperBound = Builder.CreateAdd(upperBound, ConstantInt::get(intPtrTy, 1));
1305 APInt APStride = APInt_from_MPZ(f->stride);
1306 Value *stride = ConstantInt::get(intPtrTy,
1307 APStride.zext(intPtrTy->getBitWidth()));
1308
1309 SmallVector<Value *, 6> Arguments;
1310 Arguments.push_back(SubFunction);
1311 Arguments.push_back(subfunctionParam);
1312 Arguments.push_back(numberOfThreads);
1313 Arguments.push_back(lowerBound);
1314 Arguments.push_back(upperBound);
1315 Arguments.push_back(stride);
1316
1317 Function *parallelStartFunction =
1318 M->getFunction("GOMP_parallel_loop_runtime_start");
1319 Builder.CreateCall(parallelStartFunction, Arguments);
1320
1321 // Create call to the subfunction.
1322 Builder.CreateCall(SubFunction, subfunctionParam);
1323
1324 // Create call for GOMP_parallel_end.
1325 Function *FN = M->getFunction("GOMP_parallel_end");
1326 Builder.CreateCall(FN);
1327}
1328
1329bool ClastStmtCodeGen::isInnermostLoop(const clast_for *f) {
1330 const clast_stmt *stmt = f->body;
1331
1332 while (stmt) {
1333 if (!CLAST_STMT_IS_A(stmt, stmt_user))
1334 return false;
1335
1336 stmt = stmt->next;
1337 }
1338
1339 return true;
1340}
1341
1342int ClastStmtCodeGen::getNumberOfIterations(const clast_for *f) {
1343 isl_set *loopDomain = isl_set_copy(isl_set_from_cloog_domain(f->domain));
1344 isl_set *tmp = isl_set_copy(loopDomain);
1345
1346 // Calculate a map similar to the identity map, but with the last input
1347 // and output dimension not related.
1348 // [i0, i1, i2, i3] -> [i0, i1, i2, o0]
1349 isl_space *Space = isl_set_get_space(loopDomain);
1350 Space = isl_space_drop_outputs(Space,
1351 isl_set_dim(loopDomain, isl_dim_set) - 2, 1);
1352 Space = isl_space_map_from_set(Space);
1353 isl_map *identity = isl_map_identity(Space);
1354 identity = isl_map_add_dims(identity, isl_dim_in, 1);
1355 identity = isl_map_add_dims(identity, isl_dim_out, 1);
1356
1357 isl_map *map = isl_map_from_domain_and_range(tmp, loopDomain);
1358 map = isl_map_intersect(map, identity);
1359
1360 isl_map *lexmax = isl_map_lexmax(isl_map_copy(map));
1361 isl_map *lexmin = isl_map_lexmin(map);
1362 isl_map *sub = isl_map_sum(lexmax, isl_map_neg(lexmin));
1363
1364 isl_set *elements = isl_map_range(sub);
1365
1366 if (!isl_set_is_singleton(elements)) {
1367 isl_set_free(elements);
1368 return -1;
1369 }
1370
1371 isl_point *p = isl_set_sample_point(elements);
1372
1373 isl_int v;
1374 isl_int_init(v);
1375 isl_point_get_coordinate(p, isl_dim_set, isl_set_n_dim(loopDomain) - 1, &v);
1376 int numberIterations = isl_int_get_si(v);
1377 isl_int_clear(v);
1378 isl_point_free(p);
1379
1380 return (numberIterations) / isl_int_get_si(f->stride) + 1;
1381}
1382
1383void ClastStmtCodeGen::codegenForVector(const clast_for *f) {
1384 DEBUG(dbgs() << "Vectorizing loop '" << f->iterator << "'\n";);
1385 int vectorWidth = getNumberOfIterations(f);
1386
1387 Value *LB = ExpGen.codegen(f->LB,
1388 TD->getIntPtrType(Builder.getContext()));
1389
1390 APInt Stride = APInt_from_MPZ(f->stride);
1391 IntegerType *LoopIVType = dyn_cast<IntegerType>(LB->getType());
1392 Stride = Stride.zext(LoopIVType->getBitWidth());
1393 Value *StrideValue = ConstantInt::get(LoopIVType, Stride);
1394
1395 std::vector<Value*> IVS(vectorWidth);
1396 IVS[0] = LB;
1397
1398 for (int i = 1; i < vectorWidth; i++)
1399 IVS[i] = Builder.CreateAdd(IVS[i-1], StrideValue, "p_vector_iv");
1400
1401 isl_set *scatteringDomain =
1402 isl_set_copy(isl_set_from_cloog_domain(f->domain));
1403
1404 // Add loop iv to symbols.
1405 (*clastVars)[f->iterator] = LB;
1406
1407 const clast_stmt *stmt = f->body;
1408
1409 while (stmt) {
1410 codegen((const clast_user_stmt *)stmt, &IVS, f->iterator,
1411 scatteringDomain);
1412 stmt = stmt->next;
1413 }
1414
1415 // Loop is finished, so remove its iv from the live symbols.
1416 isl_set_free(scatteringDomain);
1417 clastVars->erase(f->iterator);
1418}
1419
1420void ClastStmtCodeGen::codegen(const clast_for *f) {
Tobias Grosserce3f5372012-03-02 11:26:42 +00001421 if ((Vector || OpenMP) && DP->isParallelFor(f)) {
1422 if (Vector && isInnermostLoop(f) && (-1 != getNumberOfIterations(f))
1423 && (getNumberOfIterations(f) <= 16)) {
1424 codegenForVector(f);
1425 return;
1426 }
1427
1428 if (OpenMP && !parallelCodeGeneration) {
1429 parallelCodeGeneration = true;
1430 parallelLoops.push_back(f->iterator);
1431 codegenForOpenMP(f);
1432 parallelCodeGeneration = false;
1433 return;
1434 }
1435 }
1436
1437 codegenForSequential(f);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001438}
1439
1440Value *ClastStmtCodeGen::codegen(const clast_equation *eq) {
1441 Value *LHS = ExpGen.codegen(eq->LHS,
1442 TD->getIntPtrType(Builder.getContext()));
1443 Value *RHS = ExpGen.codegen(eq->RHS,
1444 TD->getIntPtrType(Builder.getContext()));
1445 CmpInst::Predicate P;
1446
1447 if (eq->sign == 0)
1448 P = ICmpInst::ICMP_EQ;
1449 else if (eq->sign > 0)
1450 P = ICmpInst::ICMP_SGE;
1451 else
1452 P = ICmpInst::ICMP_SLE;
1453
1454 return Builder.CreateICmp(P, LHS, RHS);
1455}
1456
1457void ClastStmtCodeGen::codegen(const clast_guard *g) {
1458 Function *F = Builder.GetInsertBlock()->getParent();
1459 LLVMContext &Context = F->getContext();
Tobias Grosser0ac92142012-02-14 14:02:27 +00001460
1461 BasicBlock *CondBB = SplitBlock(Builder.GetInsertBlock(),
1462 Builder.GetInsertPoint(), P);
1463 CondBB->setName("polly.cond");
1464 BasicBlock *MergeBB = SplitBlock(CondBB, CondBB->begin(), P);
1465 MergeBB->setName("polly.merge");
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001466 BasicBlock *ThenBB = BasicBlock::Create(Context, "polly.then", F);
Tobias Grosser0ac92142012-02-14 14:02:27 +00001467
1468 DT->addNewBlock(ThenBB, CondBB);
1469 DT->changeImmediateDominator(MergeBB, CondBB);
1470
1471 CondBB->getTerminator()->eraseFromParent();
1472
1473 Builder.SetInsertPoint(CondBB);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001474
1475 Value *Predicate = codegen(&(g->eq[0]));
1476
1477 for (int i = 1; i < g->n; ++i) {
1478 Value *TmpPredicate = codegen(&(g->eq[i]));
1479 Predicate = Builder.CreateAnd(Predicate, TmpPredicate);
1480 }
1481
1482 Builder.CreateCondBr(Predicate, ThenBB, MergeBB);
1483 Builder.SetInsertPoint(ThenBB);
Tobias Grosser0ac92142012-02-14 14:02:27 +00001484 Builder.CreateBr(MergeBB);
1485 Builder.SetInsertPoint(ThenBB->begin());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001486
1487 codegen(g->then);
Tobias Grosser62a3c962012-02-16 09:56:21 +00001488
1489 Builder.SetInsertPoint(MergeBB->begin());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001490}
1491
1492void ClastStmtCodeGen::codegen(const clast_stmt *stmt) {
1493 if (CLAST_STMT_IS_A(stmt, stmt_root))
1494 assert(false && "No second root statement expected");
1495 else if (CLAST_STMT_IS_A(stmt, stmt_ass))
1496 codegen((const clast_assignment *)stmt);
1497 else if (CLAST_STMT_IS_A(stmt, stmt_user))
1498 codegen((const clast_user_stmt *)stmt);
1499 else if (CLAST_STMT_IS_A(stmt, stmt_block))
1500 codegen((const clast_block *)stmt);
1501 else if (CLAST_STMT_IS_A(stmt, stmt_for))
1502 codegen((const clast_for *)stmt);
1503 else if (CLAST_STMT_IS_A(stmt, stmt_guard))
1504 codegen((const clast_guard *)stmt);
1505
1506 if (stmt->next)
1507 codegen(stmt->next);
1508}
1509
1510void ClastStmtCodeGen::addParameters(const CloogNames *names) {
1511 SCEVExpander Rewriter(SE, "polly");
1512
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001513 int i = 0;
1514 for (Scop::param_iterator PI = S->param_begin(), PE = S->param_end();
1515 PI != PE; ++PI) {
1516 assert(i < names->nb_parameters && "Not enough parameter names");
1517
1518 const SCEV *Param = *PI;
1519 Type *Ty = Param->getType();
1520
1521 Instruction *insertLocation = --(Builder.GetInsertBlock()->end());
1522 Value *V = Rewriter.expandCodeFor(Param, Ty, insertLocation);
1523 (*clastVars)[names->parameters[i]] = V;
1524
1525 ++i;
1526 }
1527}
1528
1529void ClastStmtCodeGen::codegen(const clast_root *r) {
1530 clastVars = new CharMapT();
1531 addParameters(r->names);
1532 ExpGen.setIVS(clastVars);
1533
1534 parallelCodeGeneration = false;
1535
1536 const clast_stmt *stmt = (const clast_stmt*) r;
1537 if (stmt->next)
1538 codegen(stmt->next);
1539
1540 delete clastVars;
1541}
1542
1543ClastStmtCodeGen::ClastStmtCodeGen(Scop *scop, ScalarEvolution &se,
1544 DominatorTree *dt, ScopDetection *sd,
1545 Dependences *dp, TargetData *td,
Tobias Grosser0ac92142012-02-14 14:02:27 +00001546 IRBuilder<> &B, Pass *P) :
1547 S(scop), SE(se), DT(dt), SD(sd), DP(dp), TD(td), P(P), Builder(B),
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001548 ExpGen(Builder, NULL) {}
1549
Tobias Grosser75805372011-04-29 06:27:02 +00001550namespace {
1551class CodeGeneration : public ScopPass {
1552 Region *region;
1553 Scop *S;
1554 DominatorTree *DT;
1555 ScalarEvolution *SE;
1556 ScopDetection *SD;
Tobias Grosser75805372011-04-29 06:27:02 +00001557 TargetData *TD;
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001558 RegionInfo *RI;
Tobias Grosser75805372011-04-29 06:27:02 +00001559
1560 std::vector<std::string> parallelLoops;
1561
1562 public:
1563 static char ID;
1564
1565 CodeGeneration() : ScopPass(ID) {}
1566
Tobias Grosserb1c95992012-02-12 12:09:27 +00001567 // Add the declarations needed by the OpenMP function calls that we insert in
1568 // OpenMP mode.
1569 void addOpenMPDeclarations(Module *M)
Tobias Grosser75805372011-04-29 06:27:02 +00001570 {
Tobias Grosserd855cc52012-02-12 12:09:32 +00001571 IRBuilder<> Builder(M->getContext());
1572 IntegerType *LongTy = TD->getIntPtrType(M->getContext());
1573
1574 llvm::GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
Tobias Grosser75805372011-04-29 06:27:02 +00001575
1576 if (!M->getFunction("GOMP_parallel_end")) {
Tobias Grosserd855cc52012-02-12 12:09:32 +00001577 FunctionType *Ty = FunctionType::get(Builder.getVoidTy(), false);
1578 Function::Create(Ty, Linkage, "GOMP_parallel_end", M);
Tobias Grosser75805372011-04-29 06:27:02 +00001579 }
1580
1581 if (!M->getFunction("GOMP_parallel_loop_runtime_start")) {
Tobias Grosserd855cc52012-02-12 12:09:32 +00001582 Type *Params[] = {
1583 PointerType::getUnqual(FunctionType::get(Builder.getVoidTy(),
1584 Builder.getInt8PtrTy(),
1585 false)),
1586 Builder.getInt8PtrTy(),
1587 Builder.getInt32Ty(),
1588 LongTy,
1589 LongTy,
1590 LongTy,
1591 };
Tobias Grosser75805372011-04-29 06:27:02 +00001592
Tobias Grosserd855cc52012-02-12 12:09:32 +00001593 FunctionType *Ty = FunctionType::get(Builder.getVoidTy(), Params, false);
1594 Function::Create(Ty, Linkage, "GOMP_parallel_loop_runtime_start", M);
Tobias Grosser75805372011-04-29 06:27:02 +00001595 }
1596
1597 if (!M->getFunction("GOMP_loop_runtime_next")) {
Tobias Grosserd855cc52012-02-12 12:09:32 +00001598 PointerType *LongPtrTy = PointerType::getUnqual(LongTy);
1599 Type *Params[] = {
1600 LongPtrTy,
1601 LongPtrTy,
1602 };
Tobias Grosser75805372011-04-29 06:27:02 +00001603
Tobias Grosserd855cc52012-02-12 12:09:32 +00001604 FunctionType *Ty = FunctionType::get(Builder.getInt8Ty(), Params, false);
1605 Function::Create(Ty, Linkage, "GOMP_loop_runtime_next", M);
Tobias Grosser75805372011-04-29 06:27:02 +00001606 }
1607
1608 if (!M->getFunction("GOMP_loop_end_nowait")) {
Tobias Grosserd855cc52012-02-12 12:09:32 +00001609 FunctionType *Ty = FunctionType::get(Builder.getVoidTy(), false);
1610 Function::Create(Ty, Linkage, "GOMP_loop_end_nowait", M);
Tobias Grosser75805372011-04-29 06:27:02 +00001611 }
1612 }
1613
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001614 // Split the entry edge of the region and generate a new basic block on this
1615 // edge. This function also updates ScopInfo and RegionInfo.
1616 //
1617 // @param region The region where the entry edge will be splitted.
1618 BasicBlock *splitEdgeAdvanced(Region *region) {
1619 BasicBlock *newBlock;
1620 BasicBlock *splitBlock;
1621
1622 newBlock = SplitEdge(region->getEnteringBlock(), region->getEntry(), this);
1623
1624 if (DT->dominates(region->getEntry(), newBlock)) {
Tobias Grossercb47dfe2012-02-15 09:58:50 +00001625 BasicBlock *OldBlock = region->getEntry();
1626 std::string OldName = OldBlock->getName();
1627
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001628 // Update ScopInfo.
1629 for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI)
Tobias Grosserf12cea42012-02-15 09:58:53 +00001630 if ((*SI)->getBasicBlock() == OldBlock) {
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001631 (*SI)->setBasicBlock(newBlock);
1632 break;
1633 }
1634
1635 // Update RegionInfo.
Tobias Grossercb47dfe2012-02-15 09:58:50 +00001636 splitBlock = OldBlock;
1637 OldBlock->setName("polly.split");
1638 newBlock->setName(OldName);
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001639 region->replaceEntry(newBlock);
Tobias Grosser7a16c892011-05-14 19:01:55 +00001640 RI->setRegionFor(newBlock, region);
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001641 } else {
1642 RI->setRegionFor(newBlock, region->getParent());
1643 splitBlock = newBlock;
1644 }
1645
1646 return splitBlock;
1647 }
1648
1649 // Create a split block that branches either to the old code or to a new basic
1650 // block where the new code can be inserted.
1651 //
Tobias Grosserbd608a82012-02-12 12:09:41 +00001652 // @param Builder A builder that will be set to point to a basic block, where
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001653 // the new code can be generated.
1654 // @return The split basic block.
Tobias Grosserbd608a82012-02-12 12:09:41 +00001655 BasicBlock *addSplitAndStartBlock(IRBuilder<> *Builder) {
1656 BasicBlock *StartBlock, *SplitBlock;
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001657
Tobias Grosserbd608a82012-02-12 12:09:41 +00001658 SplitBlock = splitEdgeAdvanced(region);
1659 SplitBlock->setName("polly.split_new_and_old");
1660 Function *F = SplitBlock->getParent();
1661 StartBlock = BasicBlock::Create(F->getContext(), "polly.start", F);
1662 SplitBlock->getTerminator()->eraseFromParent();
1663 Builder->SetInsertPoint(SplitBlock);
1664 Builder->CreateCondBr(Builder->getTrue(), StartBlock, region->getEntry());
1665 DT->addNewBlock(StartBlock, SplitBlock);
1666 Builder->SetInsertPoint(StartBlock);
1667 return SplitBlock;
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001668 }
1669
1670 // Merge the control flow of the newly generated code with the existing code.
1671 //
Tobias Grosserbd608a82012-02-12 12:09:41 +00001672 // @param SplitBlock The basic block where the control flow was split between
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001673 // old and new version of the Scop.
Tobias Grosserbd608a82012-02-12 12:09:41 +00001674 // @param Builder An IRBuilder that points to the last instruction of the
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001675 // newly generated code.
Tobias Grosserbd608a82012-02-12 12:09:41 +00001676 void mergeControlFlow(BasicBlock *SplitBlock, IRBuilder<> *Builder) {
1677 BasicBlock *MergeBlock;
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001678 Region *R = region;
1679
1680 if (R->getExit()->getSinglePredecessor())
1681 // No splitEdge required. A block with a single predecessor cannot have
1682 // PHI nodes that would complicate life.
Tobias Grosserbd608a82012-02-12 12:09:41 +00001683 MergeBlock = R->getExit();
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001684 else {
Tobias Grosserbd608a82012-02-12 12:09:41 +00001685 MergeBlock = SplitEdge(R->getExitingBlock(), R->getExit(), this);
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001686 // SplitEdge will never split R->getExit(), as R->getExit() has more than
1687 // one predecessor. Hence, mergeBlock is always a newly generated block.
Tobias Grosserbd608a82012-02-12 12:09:41 +00001688 R->replaceExit(MergeBlock);
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001689 }
1690
Tobias Grosserbd608a82012-02-12 12:09:41 +00001691 Builder->CreateBr(MergeBlock);
Tobias Grosser8518bbe2012-02-12 12:09:46 +00001692 MergeBlock->setName("polly.merge_new_and_old");
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001693
Tobias Grosserbd608a82012-02-12 12:09:41 +00001694 if (DT->dominates(SplitBlock, MergeBlock))
1695 DT->changeImmediateDominator(MergeBlock, SplitBlock);
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001696 }
1697
Tobias Grosser75805372011-04-29 06:27:02 +00001698 bool runOnScop(Scop &scop) {
1699 S = &scop;
1700 region = &S->getRegion();
Tobias Grosser75805372011-04-29 06:27:02 +00001701 DT = &getAnalysis<DominatorTree>();
1702 Dependences *DP = &getAnalysis<Dependences>();
1703 SE = &getAnalysis<ScalarEvolution>();
Tobias Grosser75805372011-04-29 06:27:02 +00001704 SD = &getAnalysis<ScopDetection>();
1705 TD = &getAnalysis<TargetData>();
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001706 RI = &getAnalysis<RegionInfo>();
Tobias Grosser75805372011-04-29 06:27:02 +00001707
1708 parallelLoops.clear();
1709
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001710 assert(region->isSimple() && "Only simple regions are supported");
Tobias Grosser76d7c522011-05-14 19:01:37 +00001711
Tobias Grosserb1c95992012-02-12 12:09:27 +00001712 Module *M = region->getEntry()->getParent()->getParent();
1713
Tobias Grosserd855cc52012-02-12 12:09:32 +00001714 if (OpenMP) addOpenMPDeclarations(M);
Tobias Grosserb1c95992012-02-12 12:09:27 +00001715
Tobias Grosser5772e652012-02-01 14:23:33 +00001716 // In the CFG the optimized code of the SCoP is generated next to the
1717 // original code. Both the new and the original version of the code remain
1718 // in the CFG. A branch statement decides which version is executed.
1719 // For now, we always execute the new version (the old one is dead code
1720 // eliminated by the cleanup passes). In the future we may decide to execute
1721 // the new version only if certain run time checks succeed. This will be
1722 // useful to support constructs for which we cannot prove all assumptions at
1723 // compile time.
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001724 //
1725 // Before transformation:
1726 //
1727 // bb0
1728 // |
1729 // orig_scop
1730 // |
1731 // bb1
1732 //
1733 // After transformation:
1734 // bb0
1735 // |
1736 // polly.splitBlock
Tobias Grosser2bd3af12011-08-01 22:39:00 +00001737 // / \.
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001738 // | startBlock
1739 // | |
1740 // orig_scop new_scop
1741 // \ /
1742 // \ /
1743 // bb1 (joinBlock)
1744 IRBuilder<> builder(region->getEntry());
Tobias Grosser75805372011-04-29 06:27:02 +00001745
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001746 // The builder will be set to startBlock.
1747 BasicBlock *splitBlock = addSplitAndStartBlock(&builder);
Tobias Grosser0ac92142012-02-14 14:02:27 +00001748 BasicBlock *StartBlock = builder.GetInsertBlock();
Tobias Grosser75805372011-04-29 06:27:02 +00001749
Tobias Grosser0ac92142012-02-14 14:02:27 +00001750 mergeControlFlow(splitBlock, &builder);
1751 builder.SetInsertPoint(StartBlock->begin());
1752
1753 ClastStmtCodeGen CodeGen(S, *SE, DT, SD, DP, TD, builder, this);
Tobias Grosser3fdecae2011-05-14 19:02:39 +00001754 CloogInfo &C = getAnalysis<CloogInfo>();
1755 CodeGen.codegen(C.getClast());
Tobias Grosser75805372011-04-29 06:27:02 +00001756
Tobias Grosser75805372011-04-29 06:27:02 +00001757 parallelLoops.insert(parallelLoops.begin(),
1758 CodeGen.getParallelLoops().begin(),
1759 CodeGen.getParallelLoops().end());
1760
Tobias Grosserabb6dcd2011-05-14 19:02:34 +00001761 return true;
Tobias Grosser75805372011-04-29 06:27:02 +00001762 }
1763
1764 virtual void printScop(raw_ostream &OS) const {
1765 for (std::vector<std::string>::const_iterator PI = parallelLoops.begin(),
1766 PE = parallelLoops.end(); PI != PE; ++PI)
1767 OS << "Parallel loop with iterator '" << *PI << "' generated\n";
1768 }
1769
1770 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
1771 AU.addRequired<CloogInfo>();
1772 AU.addRequired<Dependences>();
1773 AU.addRequired<DominatorTree>();
Tobias Grosser75805372011-04-29 06:27:02 +00001774 AU.addRequired<RegionInfo>();
Tobias Grosser73600b82011-10-08 00:30:40 +00001775 AU.addRequired<ScalarEvolution>();
Tobias Grosser75805372011-04-29 06:27:02 +00001776 AU.addRequired<ScopDetection>();
1777 AU.addRequired<ScopInfo>();
1778 AU.addRequired<TargetData>();
1779
1780 AU.addPreserved<CloogInfo>();
1781 AU.addPreserved<Dependences>();
Tobias Grosser5d6eb862011-05-14 19:02:45 +00001782
Tobias Grosser4e3f9a42011-05-23 15:23:36 +00001783 // FIXME: We do not create LoopInfo for the newly generated loops.
Tobias Grosser75805372011-04-29 06:27:02 +00001784 AU.addPreserved<LoopInfo>();
1785 AU.addPreserved<DominatorTree>();
Tobias Grosser75805372011-04-29 06:27:02 +00001786 AU.addPreserved<ScopDetection>();
1787 AU.addPreserved<ScalarEvolution>();
Tobias Grosser5d6eb862011-05-14 19:02:45 +00001788
Tobias Grosser4e3f9a42011-05-23 15:23:36 +00001789 // FIXME: We do not yet add regions for the newly generated code to the
1790 // region tree.
Tobias Grosser75805372011-04-29 06:27:02 +00001791 AU.addPreserved<RegionInfo>();
1792 AU.addPreserved<TempScopInfo>();
1793 AU.addPreserved<ScopInfo>();
1794 AU.addPreservedID(IndependentBlocksID);
1795 }
1796};
1797}
1798
1799char CodeGeneration::ID = 1;
1800
Tobias Grosser73600b82011-10-08 00:30:40 +00001801INITIALIZE_PASS_BEGIN(CodeGeneration, "polly-codegen",
1802 "Polly - Create LLVM-IR form SCoPs", false, false)
1803INITIALIZE_PASS_DEPENDENCY(CloogInfo)
1804INITIALIZE_PASS_DEPENDENCY(Dependences)
1805INITIALIZE_PASS_DEPENDENCY(DominatorTree)
1806INITIALIZE_PASS_DEPENDENCY(RegionInfo)
1807INITIALIZE_PASS_DEPENDENCY(ScalarEvolution)
1808INITIALIZE_PASS_DEPENDENCY(ScopDetection)
1809INITIALIZE_PASS_DEPENDENCY(TargetData)
1810INITIALIZE_PASS_END(CodeGeneration, "polly-codegen",
1811 "Polly - Create LLVM-IR form SCoPs", false, false)
Tobias Grosser75805372011-04-29 06:27:02 +00001812
Tobias Grosser7ffe4e82011-11-17 12:56:10 +00001813Pass *polly::createCodeGenerationPass() {
Tobias Grosser75805372011-04-29 06:27:02 +00001814 return new CodeGeneration();
1815}