blob: 30494dc67e6d64336cd98bf50370a8b1e8925392 [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"
Tobias Grosserf74a4cd2012-03-23 10:35:18 +000032#include "polly/LoopGenerators.h"
Tobias Grosserbda1f8f2012-02-01 14:23:29 +000033
34#include "llvm/Module.h"
35#include "llvm/ADT/SetVector.h"
36#include "llvm/Analysis/LoopInfo.h"
37#include "llvm/Analysis/ScalarEvolutionExpander.h"
Tobias Grosser75805372011-04-29 06:27:02 +000038#include "llvm/Support/CommandLine.h"
39#include "llvm/Support/Debug.h"
40#include "llvm/Support/IRBuilder.h"
Tobias Grosser75805372011-04-29 06:27:02 +000041#include "llvm/Target/TargetData.h"
Tobias Grosserbda1f8f2012-02-01 14:23:29 +000042#include "llvm/Transforms/Utils/BasicBlockUtils.h"
Tobias Grosser75805372011-04-29 06:27:02 +000043
44#define CLOOG_INT_GMP 1
45#include "cloog/cloog.h"
46#include "cloog/isl/cloog.h"
47
Raghesh Aloora71989c2011-12-28 02:48:26 +000048#include "isl/aff.h"
49
Tobias Grosser75805372011-04-29 06:27:02 +000050#include <vector>
51#include <utility>
52
53using namespace polly;
54using namespace llvm;
55
56struct isl_set;
57
58namespace polly {
59
Tobias Grosser67707b72011-10-23 20:59:40 +000060bool EnablePollyVector;
61
62static cl::opt<bool, true>
Tobias Grosser75805372011-04-29 06:27:02 +000063Vector("enable-polly-vector",
64 cl::desc("Enable polly vector code generation"), cl::Hidden,
Tobias Grosser0acfcdb2012-03-16 17:17:16 +000065 cl::location(EnablePollyVector), cl::init(false), cl::ZeroOrMore);
Tobias Grosser75805372011-04-29 06:27:02 +000066
67static cl::opt<bool>
68OpenMP("enable-polly-openmp",
69 cl::desc("Generate OpenMP parallel code"), cl::Hidden,
70 cl::value_desc("OpenMP code generation enabled if true"),
Tobias Grosser0acfcdb2012-03-16 17:17:16 +000071 cl::init(false), cl::ZeroOrMore);
Tobias Grosser75805372011-04-29 06:27:02 +000072
73static cl::opt<bool>
74AtLeastOnce("enable-polly-atLeastOnce",
75 cl::desc("Give polly the hint, that every loop is executed at least"
76 "once"), cl::Hidden,
77 cl::value_desc("OpenMP code generation enabled if true"),
Tobias Grosser0acfcdb2012-03-16 17:17:16 +000078 cl::init(false), cl::ZeroOrMore);
Tobias Grosser75805372011-04-29 06:27:02 +000079
80static cl::opt<bool>
81Aligned("enable-polly-aligned",
82 cl::desc("Assumed aligned memory accesses."), cl::Hidden,
83 cl::value_desc("OpenMP code generation enabled if true"),
Tobias Grosser0acfcdb2012-03-16 17:17:16 +000084 cl::init(false), cl::ZeroOrMore);
Tobias Grosser75805372011-04-29 06:27:02 +000085
Tobias Grosser75805372011-04-29 06:27:02 +000086typedef DenseMap<const Value*, Value*> ValueMapT;
87typedef DenseMap<const char*, Value*> CharMapT;
88typedef std::vector<ValueMapT> VectorValueMapT;
89
Tobias Grosser642c4112012-03-02 11:27:25 +000090class IslGenerator;
91
92class IslGenerator {
93public:
Tobias Grosserd6adda32012-03-23 08:21:22 +000094 IslGenerator(IRBuilder<> &Builder, std::vector<Value *> &IVS) :
95 Builder(Builder), IVS(IVS) {}
Tobias Grosser642c4112012-03-02 11:27:25 +000096 Value *generateIslInt(__isl_take isl_int Int);
97 Value *generateIslAff(__isl_take isl_aff *Aff);
98 Value *generateIslPwAff(__isl_take isl_pw_aff *PwAff);
99
100private:
101 typedef struct {
102 Value *Result;
103 class IslGenerator *Generator;
104 } IslGenInfo;
105
106 IRBuilder<> &Builder;
Tobias Grosserd6adda32012-03-23 08:21:22 +0000107 std::vector<Value *> &IVS;
Tobias Grosser642c4112012-03-02 11:27:25 +0000108 static int mergeIslAffValues(__isl_take isl_set *Set,
109 __isl_take isl_aff *Aff, void *User);
110};
111
112Value *IslGenerator::generateIslInt(isl_int Int) {
113 mpz_t IntMPZ;
114 mpz_init(IntMPZ);
115 isl_int_get_gmp(Int, IntMPZ);
116 Value *IntValue = Builder.getInt(APInt_from_MPZ(IntMPZ));
117 mpz_clear(IntMPZ);
118 return IntValue;
119}
120
121Value *IslGenerator::generateIslAff(__isl_take isl_aff *Aff) {
Tobias Grosserd6adda32012-03-23 08:21:22 +0000122 Value *Result;
Tobias Grosser642c4112012-03-02 11:27:25 +0000123 Value *ConstValue;
124 isl_int ConstIsl;
125
126 isl_int_init(ConstIsl);
127 isl_aff_get_constant(Aff, &ConstIsl);
128 ConstValue = generateIslInt(ConstIsl);
Tobias Grosserd6adda32012-03-23 08:21:22 +0000129 Type *Ty = Builder.getInt64Ty();
Tobias Grosser642c4112012-03-02 11:27:25 +0000130
Tobias Grosserd6adda32012-03-23 08:21:22 +0000131 // FIXME: We should give the constant and coefficients the right type. Here
132 // we force it into i64.
133 Result = Builder.CreateSExtOrBitCast(ConstValue, Ty);
134
135 unsigned int NbInputDims = isl_aff_dim(Aff, isl_dim_in);
136
137 assert((IVS.size() == NbInputDims) && "The Dimension of Induction Variables"
138 "must match the dimension of the affine space.");
139
140 isl_int CoefficientIsl;
141 isl_int_init(CoefficientIsl);
142
143 for (unsigned int i = 0; i < NbInputDims; ++i) {
144 Value *CoefficientValue;
145 isl_aff_get_coefficient(Aff, isl_dim_in, i, &CoefficientIsl);
146
147 if (isl_int_is_zero(CoefficientIsl))
148 continue;
149
150 CoefficientValue = generateIslInt(CoefficientIsl);
151 CoefficientValue = Builder.CreateIntCast(CoefficientValue, Ty, true);
152 Value *IV = Builder.CreateIntCast(IVS[i], Ty, true);
153 Value *PAdd = Builder.CreateMul(CoefficientValue, IV, "p_mul_coeff");
154 Result = Builder.CreateAdd(Result, PAdd, "p_sum_coeff");
155 }
156
157 isl_int_clear(CoefficientIsl);
Tobias Grosser642c4112012-03-02 11:27:25 +0000158 isl_int_clear(ConstIsl);
159 isl_aff_free(Aff);
160
Tobias Grosserd6adda32012-03-23 08:21:22 +0000161 return Result;
Tobias Grosser642c4112012-03-02 11:27:25 +0000162}
163
164int IslGenerator::mergeIslAffValues(__isl_take isl_set *Set,
165 __isl_take isl_aff *Aff, void *User) {
166 IslGenInfo *GenInfo = (IslGenInfo *)User;
167
168 assert((GenInfo->Result == NULL) && "Result is already set."
169 "Currently only single isl_aff is supported");
170 assert(isl_set_plain_is_universe(Set)
171 && "Code generation failed because the set is not universe");
172
173 GenInfo->Result = GenInfo->Generator->generateIslAff(Aff);
174
175 isl_set_free(Set);
176 return 0;
177}
178
179Value *IslGenerator::generateIslPwAff(__isl_take isl_pw_aff *PwAff) {
180 IslGenInfo User;
181 User.Result = NULL;
182 User.Generator = this;
183 isl_pw_aff_foreach_piece(PwAff, mergeIslAffValues, &User);
184 assert(User.Result && "Code generation for isl_pw_aff failed");
185
186 isl_pw_aff_free(PwAff);
187 return User.Result;
188}
189
Tobias Grosser55d52082012-03-02 15:20:39 +0000190/// @brief Generate a new basic block for a polyhedral statement.
191///
192/// The only public function exposed is generate().
Tobias Grosser75805372011-04-29 06:27:02 +0000193class BlockGenerator {
Tobias Grosserc941ede2012-03-02 11:26:49 +0000194public:
Tobias Grosser55d52082012-03-02 15:20:39 +0000195 /// @brief Generate a new BasicBlock for a ScopStmt.
196 ///
197 /// @param Builder The LLVM-IR Builder used to generate the statement. The
198 /// code is generated at the location, the Builder points to.
199 /// @param Stmt The statement to code generate.
200 /// @param GlobalMap A map that defines for certain Values referenced from the
201 /// original code new Values they should be replaced with.
202 /// @param P A reference to the pass this function is called from.
203 /// The pass is needed to update other analysis.
204 static void generate(IRBuilder<> &Builder, ScopStmt &Stmt,
205 ValueMapT &GlobalMap, Pass *P) {
206 BlockGenerator Generator(Builder, Stmt, P);
207 Generator.copyBB(GlobalMap);
Tobias Grosserc941ede2012-03-02 11:26:49 +0000208 }
209
Tobias Grosser80998e72012-03-02 11:27:28 +0000210protected:
Tobias Grosser75805372011-04-29 06:27:02 +0000211 IRBuilder<> &Builder;
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000212 ScopStmt &Statement;
Tobias Grosser8412cda2012-03-02 11:26:55 +0000213 Pass *P;
Tobias Grosser75805372011-04-29 06:27:02 +0000214
Tobias Grosser55d52082012-03-02 15:20:39 +0000215 BlockGenerator(IRBuilder<> &B, ScopStmt &Stmt, Pass *P);
Tobias Grosser75805372011-04-29 06:27:02 +0000216
Tobias Grosser55d52082012-03-02 15:20:39 +0000217 /// @brief Get the new version of a Value.
218 ///
219 /// @param Old The old Value.
Tobias Grosser3c2efba2012-03-06 07:38:57 +0000220 /// @param BBMap A mapping from old values to their new values
Tobias Grosser55d52082012-03-02 15:20:39 +0000221 /// (for values recalculated within this basic block).
222 /// @param GlobalMap A mapping from old values to their new values
223 /// (for values recalculated in the new ScoP, but not
224 /// within this basic block).
225 ///
226 /// @returns o The old value, if it is still valid.
227 /// o The new value, if available.
228 /// o NULL, if no value is found.
229 Value *getNewValue(const Value *Old, ValueMapT &BBMap, ValueMapT &GlobalMap);
Tobias Grosser75805372011-04-29 06:27:02 +0000230
Tobias Grosserdf382372012-03-02 15:20:35 +0000231 void copyInstScalar(const Instruction *Inst, ValueMapT &BBMap,
232 ValueMapT &GlobalMap);
Tobias Grosser75805372011-04-29 06:27:02 +0000233
Raghesh Aloor129e8672011-08-15 02:33:39 +0000234 /// @brief Get the memory access offset to be added to the base address
Tobias Grosser80998e72012-03-02 11:27:28 +0000235 std::vector<Value*> getMemoryAccessIndex(__isl_keep isl_map *AccessRelation,
Tobias Grosserd6adda32012-03-23 08:21:22 +0000236 Value *BaseAddress, ValueMapT &BBMap,
237 ValueMapT &GlobalMap);
Raghesh Aloor129e8672011-08-15 02:33:39 +0000238
Raghesh Aloor62b13122011-08-03 17:02:50 +0000239 /// @brief Get the new operand address according to the changed access in
240 /// JSCOP file.
Raghesh Aloor46eceba2011-12-09 14:27:17 +0000241 Value *getNewAccessOperand(__isl_keep isl_map *NewAccessRelation,
242 Value *BaseAddress, const Value *OldOperand,
Tobias Grosserd6adda32012-03-23 08:21:22 +0000243 ValueMapT &BBMap, ValueMapT &GlobalMap);
Raghesh Aloor62b13122011-08-03 17:02:50 +0000244
245 /// @brief Generate the operand address
246 Value *generateLocationAccessed(const Instruction *Inst,
Tobias Grosserdf382372012-03-02 15:20:35 +0000247 const Value *Pointer, ValueMapT &BBMap,
248 ValueMapT &GlobalMap);
Raghesh Aloor129e8672011-08-15 02:33:39 +0000249
Tobias Grosserdf382372012-03-02 15:20:35 +0000250 Value *generateScalarLoad(const LoadInst *load, ValueMapT &BBMap,
251 ValueMapT &GlobalMap);
Tobias Grosser75805372011-04-29 06:27:02 +0000252
Tobias Grosserd6adda32012-03-23 08:21:22 +0000253 Value *generateScalarStore(const StoreInst *store, ValueMapT &BBMap,
254 ValueMapT &GlobalMap);
255
Tobias Grosser55d52082012-03-02 15:20:39 +0000256 /// @brief Copy a single Instruction.
257 ///
258 /// This copies a single Instruction and updates references to old values
259 /// with references to new values, as defined by GlobalMap and BBMap.
260 ///
Tobias Grosser3c2efba2012-03-06 07:38:57 +0000261 /// @param BBMap A mapping from old values to their new values
Tobias Grosser55d52082012-03-02 15:20:39 +0000262 /// (for values recalculated within this basic block).
263 /// @param GlobalMap A mapping from old values to their new values
264 /// (for values recalculated in the new ScoP, but not
265 /// within this basic block).
266 void copyInstruction(const Instruction *Inst, ValueMapT &BBMap,
Tobias Grosserdf382372012-03-02 15:20:35 +0000267 ValueMapT &GlobalMap);
Tobias Grosser75805372011-04-29 06:27:02 +0000268
Tobias Grosser55d52082012-03-02 15:20:39 +0000269 /// @brief Copy the basic block.
270 ///
271 /// This copies the entire basic block and updates references to old values
272 /// with references to new values, as defined by GlobalMap.
273 ///
274 /// @param GlobalMap A mapping from old values to their new values
275 /// (for values recalculated in the new ScoP, but not
276 /// within this basic block).
277 void copyBB(ValueMapT &GlobalMap);
Tobias Grosser75805372011-04-29 06:27:02 +0000278};
279
Tobias Grosser55d52082012-03-02 15:20:39 +0000280BlockGenerator::BlockGenerator(IRBuilder<> &B, ScopStmt &Stmt, Pass *P):
281 Builder(B), Statement(Stmt), P(P) {}
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000282
Tobias Grosser55d52082012-03-02 15:20:39 +0000283Value *BlockGenerator::getNewValue(const Value *Old, ValueMapT &BBMap,
284 ValueMapT &GlobalMap) {
285 const Instruction *Inst = dyn_cast<Instruction>(Old);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000286
Tobias Grosser55d52082012-03-02 15:20:39 +0000287 if (!Inst)
288 return const_cast<Value*>(Old);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000289
Tobias Grosser8367e0c2012-03-02 15:20:31 +0000290 // OldOperand was redefined outside of this BasicBlock.
Tobias Grosser55d52082012-03-02 15:20:39 +0000291 if (GlobalMap.count(Old)) {
292 Value *New = GlobalMap[Old];
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000293
Tobias Grosser55d52082012-03-02 15:20:39 +0000294 if (Old->getType()->getScalarSizeInBits()
295 < New->getType()->getScalarSizeInBits())
296 New = Builder.CreateTruncOrBitCast(New, Old->getType());
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000297
Tobias Grosser55d52082012-03-02 15:20:39 +0000298 return New;
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000299 }
300
Tobias Grosser8367e0c2012-03-02 15:20:31 +0000301 // OldOperand was recalculated within this BasicBlock.
Tobias Grosser55d52082012-03-02 15:20:39 +0000302 if (BBMap.count(Old)) {
303 return BBMap[Old];
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000304 }
305
Tobias Grosser8367e0c2012-03-02 15:20:31 +0000306 // OldOperand is SCoP invariant.
Tobias Grosser55d52082012-03-02 15:20:39 +0000307 if (!Statement.getParent()->getRegion().contains(Inst->getParent()))
308 return const_cast<Value*>(Old);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000309
Tobias Grosser8367e0c2012-03-02 15:20:31 +0000310 // We could not find any valid new operand.
311 return NULL;
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000312}
313
Tobias Grosserdf382372012-03-02 15:20:35 +0000314void BlockGenerator::copyInstScalar(const Instruction *Inst, ValueMapT &BBMap,
315 ValueMapT &GlobalMap) {
Tobias Grosser80998e72012-03-02 11:27:28 +0000316 Instruction *NewInst = Inst->clone();
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000317
Tobias Grosser80998e72012-03-02 11:27:28 +0000318 // Replace old operands with the new ones.
319 for (Instruction::const_op_iterator OI = Inst->op_begin(),
320 OE = Inst->op_end(); OI != OE; ++OI) {
321 Value *OldOperand = *OI;
Tobias Grosser55d52082012-03-02 15:20:39 +0000322 Value *NewOperand = getNewValue(OldOperand, BBMap, GlobalMap);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000323
Tobias Grosser80998e72012-03-02 11:27:28 +0000324 if (!NewOperand) {
325 assert(!isa<StoreInst>(NewInst)
326 && "Store instructions are always needed!");
327 delete NewInst;
328 return;
329 }
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000330
Tobias Grosser80998e72012-03-02 11:27:28 +0000331 NewInst->replaceUsesOfWith(OldOperand, NewOperand);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000332 }
333
Tobias Grosser80998e72012-03-02 11:27:28 +0000334 Builder.Insert(NewInst);
335 BBMap[Inst] = NewInst;
336
337 if (!NewInst->getType()->isVoidTy())
338 NewInst->setName("p_" + Inst->getName());
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000339}
340
Tobias Grosserd6adda32012-03-23 08:21:22 +0000341std::vector<Value*> BlockGenerator::getMemoryAccessIndex(
342 __isl_keep isl_map *AccessRelation, Value *BaseAddress,
343 ValueMapT &BBMap, ValueMapT &GlobalMap) {
344
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000345 assert((isl_map_dim(AccessRelation, isl_dim_out) == 1)
346 && "Only single dimensional access functions supported");
347
Tobias Grosserd6adda32012-03-23 08:21:22 +0000348 std::vector<Value *> IVS;
349 for (unsigned i = 0; i < Statement.getNumIterators(); ++i) {
350 const Value *OriginalIV = Statement.getInductionVariableForDimension(i);
351 Value *NewIV = getNewValue(OriginalIV, BBMap, GlobalMap);
352 IVS.push_back(NewIV);
353 }
354
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000355 isl_pw_aff *PwAff = isl_map_dim_max(isl_map_copy(AccessRelation), 0);
Tobias Grosserd6adda32012-03-23 08:21:22 +0000356 IslGenerator IslGen(Builder, IVS);
Tobias Grosser642c4112012-03-02 11:27:25 +0000357 Value *OffsetValue = IslGen.generateIslPwAff(PwAff);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000358
Tobias Grosserd6adda32012-03-23 08:21:22 +0000359 Type *Ty = Builder.getInt64Ty();
360 OffsetValue = Builder.CreateIntCast(OffsetValue, Ty, true);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000361
362 std::vector<Value*> IndexArray;
Tobias Grosserd6adda32012-03-23 08:21:22 +0000363 Value *NullValue = Constant::getNullValue(Ty);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000364 IndexArray.push_back(NullValue);
365 IndexArray.push_back(OffsetValue);
366 return IndexArray;
367}
368
369Value *BlockGenerator::getNewAccessOperand(
370 __isl_keep isl_map *NewAccessRelation, Value *BaseAddress, const Value
Tobias Grosserd6adda32012-03-23 08:21:22 +0000371 *OldOperand, ValueMapT &BBMap, ValueMapT &GlobalMap) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000372 std::vector<Value*> IndexArray = getMemoryAccessIndex(NewAccessRelation,
Tobias Grosserd6adda32012-03-23 08:21:22 +0000373 BaseAddress,
374 BBMap, GlobalMap);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000375 Value *NewOperand = Builder.CreateGEP(BaseAddress, IndexArray,
376 "p_newarrayidx_");
377 return NewOperand;
378}
379
380Value *BlockGenerator::generateLocationAccessed(const Instruction *Inst,
381 const Value *Pointer,
Tobias Grosserdf382372012-03-02 15:20:35 +0000382 ValueMapT &BBMap,
383 ValueMapT &GlobalMap) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000384 MemoryAccess &Access = Statement.getAccessFor(Inst);
385 isl_map *CurrentAccessRelation = Access.getAccessRelation();
386 isl_map *NewAccessRelation = Access.getNewAccessRelation();
387
388 assert(isl_map_has_equal_space(CurrentAccessRelation, NewAccessRelation)
389 && "Current and new access function use different spaces");
390
391 Value *NewPointer;
392
393 if (!NewAccessRelation) {
Tobias Grosser55d52082012-03-02 15:20:39 +0000394 NewPointer = getNewValue(Pointer, BBMap, GlobalMap);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000395 } else {
396 Value *BaseAddress = const_cast<Value*>(Access.getBaseAddr());
397 NewPointer = getNewAccessOperand(NewAccessRelation, BaseAddress, Pointer,
Tobias Grosserd6adda32012-03-23 08:21:22 +0000398 BBMap, GlobalMap);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000399 }
400
401 isl_map_free(CurrentAccessRelation);
402 isl_map_free(NewAccessRelation);
403 return NewPointer;
404}
405
406Value *BlockGenerator::generateScalarLoad(const LoadInst *Load,
Tobias Grosserdf382372012-03-02 15:20:35 +0000407 ValueMapT &BBMap,
408 ValueMapT &GlobalMap) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000409 const Value *Pointer = Load->getPointerOperand();
410 const Instruction *Inst = dyn_cast<Instruction>(Load);
Tobias Grosserdf382372012-03-02 15:20:35 +0000411 Value *NewPointer = generateLocationAccessed(Inst, Pointer, BBMap, GlobalMap);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000412 Value *ScalarLoad = Builder.CreateLoad(NewPointer,
413 Load->getName() + "_p_scalar_");
414 return ScalarLoad;
415}
416
Tobias Grosserd6adda32012-03-23 08:21:22 +0000417Value *BlockGenerator::generateScalarStore(const StoreInst *Store,
418 ValueMapT &BBMap,
419 ValueMapT &GlobalMap) {
420 const Value *Pointer = Store->getPointerOperand();
421 Value *NewPointer = generateLocationAccessed(Store, Pointer, BBMap,
422 GlobalMap);
423 Value *ValueOperand = getNewValue(Store->getValueOperand(), BBMap, GlobalMap);
424
425 return Builder.CreateStore(ValueOperand, NewPointer);
426}
427
Tobias Grosser80998e72012-03-02 11:27:28 +0000428void BlockGenerator::copyInstruction(const Instruction *Inst,
Tobias Grosserdf382372012-03-02 15:20:35 +0000429 ValueMapT &BBMap, ValueMapT &GlobalMap) {
Tobias Grosser80998e72012-03-02 11:27:28 +0000430 // Terminator instructions control the control flow. They are explicitly
431 // expressed in the clast and do not need to be copied.
432 if (Inst->isTerminator())
433 return;
434
435 if (const LoadInst *Load = dyn_cast<LoadInst>(Inst)) {
Tobias Grosserdf382372012-03-02 15:20:35 +0000436 BBMap[Load] = generateScalarLoad(Load, BBMap, GlobalMap);
Tobias Grosser80998e72012-03-02 11:27:28 +0000437 return;
438 }
439
Tobias Grosserd6adda32012-03-23 08:21:22 +0000440 if (const StoreInst *Store = dyn_cast<StoreInst>(Inst)) {
441 BBMap[Store] = generateScalarStore(Store, BBMap, GlobalMap);
442 return;
443 }
444
Tobias Grosserdf382372012-03-02 15:20:35 +0000445 copyInstScalar(Inst, BBMap, GlobalMap);
Tobias Grosser80998e72012-03-02 11:27:28 +0000446}
447
448
Tobias Grosser55d52082012-03-02 15:20:39 +0000449void BlockGenerator::copyBB(ValueMapT &GlobalMap) {
Tobias Grosser80998e72012-03-02 11:27:28 +0000450 BasicBlock *BB = Statement.getBasicBlock();
451 BasicBlock *CopyBB = SplitBlock(Builder.GetInsertBlock(),
452 Builder.GetInsertPoint(), P);
453 CopyBB->setName("polly.stmt." + BB->getName());
454 Builder.SetInsertPoint(CopyBB->begin());
455
Tobias Grosserdf382372012-03-02 15:20:35 +0000456 ValueMapT BBMap;
Tobias Grosser80998e72012-03-02 11:27:28 +0000457
458 for (BasicBlock::const_iterator II = BB->begin(), IE = BB->end(); II != IE;
459 ++II)
Tobias Grosserdf382372012-03-02 15:20:35 +0000460 copyInstruction(II, BBMap, GlobalMap);
Tobias Grosser80998e72012-03-02 11:27:28 +0000461}
462
Tobias Grosser55d52082012-03-02 15:20:39 +0000463/// @brief Generate a new vector basic block for a polyhedral statement.
464///
465/// The only public function exposed is generate().
Tobias Grosser80998e72012-03-02 11:27:28 +0000466class VectorBlockGenerator : BlockGenerator {
467public:
Tobias Grosser55d52082012-03-02 15:20:39 +0000468 /// @brief Generate a new vector basic block for a ScoPStmt.
469 ///
470 /// This code generation is similar to the normal, scalar code generation,
471 /// except that each instruction is code generated for several vector lanes
472 /// at a time. If possible instructions are issued as actual vector
473 /// instructions, but e.g. for address calculation instructions we currently
474 /// generate scalar instructions for each vector lane.
475 ///
476 /// @param Builder The LLVM-IR Builder used to generate the statement. The
477 /// code is generated at the location, the builder points
478 /// to.
479 /// @param Stmt The statement to code generate.
480 /// @param GlobalMaps A vector of maps that define for certain Values
481 /// referenced from the original code new Values they should
482 /// be replaced with. Each map in the vector of maps is
483 /// used for one vector lane. The number of elements in the
484 /// vector defines the width of the generated vector
485 /// instructions.
486 /// @param P A reference to the pass this function is called from.
487 /// The pass is needed to update other analysis.
488 static void generate(IRBuilder<> &B, ScopStmt &Stmt,
489 VectorValueMapT &GlobalMaps, __isl_keep isl_set *Domain,
490 Pass *P) {
491 VectorBlockGenerator Generator(B, GlobalMaps, Stmt, Domain, P);
Tobias Grosser80998e72012-03-02 11:27:28 +0000492 Generator.copyBB();
493 }
494
495private:
Tobias Grosser55d52082012-03-02 15:20:39 +0000496 // This is a vector of global value maps. The first map is used for the first
497 // vector lane, ...
498 // Each map, contains information about Instructions in the old ScoP, which
499 // are recalculated in the new SCoP. When copying the basic block, we replace
500 // all referenes to the old instructions with their recalculated values.
Tobias Grosserdf382372012-03-02 15:20:35 +0000501 VectorValueMapT &GlobalMaps;
Tobias Grosser80998e72012-03-02 11:27:28 +0000502
Tobias Grosser08a82382012-03-02 15:20:24 +0000503 isl_set *Domain;
504
Tobias Grosser55d52082012-03-02 15:20:39 +0000505 VectorBlockGenerator(IRBuilder<> &B, VectorValueMapT &GlobalMaps,
506 ScopStmt &Stmt, __isl_keep isl_set *Domain, Pass *P);
Tobias Grosser80998e72012-03-02 11:27:28 +0000507
508 int getVectorWidth();
509
Tobias Grosser55d52082012-03-02 15:20:39 +0000510 Value *getVectorValue(const Value *Old, ValueMapT &VectorMap,
511 VectorValueMapT &ScalarMaps);
Tobias Grosser80998e72012-03-02 11:27:28 +0000512
513 Type *getVectorPtrTy(const Value *V, int Width);
514
515 /// @brief Load a vector from a set of adjacent scalars
516 ///
517 /// In case a set of scalars is known to be next to each other in memory,
518 /// create a vector load that loads those scalars
519 ///
520 /// %vector_ptr= bitcast double* %p to <4 x double>*
521 /// %vec_full = load <4 x double>* %vector_ptr
522 ///
523 Value *generateStrideOneLoad(const LoadInst *Load, ValueMapT &BBMap);
524
525 /// @brief Load a vector initialized from a single scalar in memory
526 ///
527 /// In case all elements of a vector are initialized to the same
528 /// scalar value, this value is loaded and shuffeled into all elements
529 /// of the vector.
530 ///
531 /// %splat_one = load <1 x double>* %p
532 /// %splat = shufflevector <1 x double> %splat_one, <1 x
533 /// double> %splat_one, <4 x i32> zeroinitializer
534 ///
535 Value *generateStrideZeroLoad(const LoadInst *Load, ValueMapT &BBMap);
536
537 /// @Load a vector from scalars distributed in memory
538 ///
539 /// In case some scalars a distributed randomly in memory. Create a vector
540 /// by loading each scalar and by inserting one after the other into the
541 /// vector.
542 ///
543 /// %scalar_1= load double* %p_1
544 /// %vec_1 = insertelement <2 x double> undef, double %scalar_1, i32 0
545 /// %scalar 2 = load double* %p_2
546 /// %vec_2 = insertelement <2 x double> %vec_1, double %scalar_1, i32 1
547 ///
548 Value *generateUnknownStrideLoad(const LoadInst *Load,
549 VectorValueMapT &ScalarMaps);
550
Tobias Grosser80998e72012-03-02 11:27:28 +0000551 void generateLoad(const LoadInst *Load, ValueMapT &VectorMap,
552 VectorValueMapT &ScalarMaps);
553
Tobias Grosserdf382372012-03-02 15:20:35 +0000554 void copyUnaryInst(const UnaryInstruction *Inst, ValueMapT &VectorMap,
555 VectorValueMapT &ScalarMaps);
Tobias Grosser80998e72012-03-02 11:27:28 +0000556
Tobias Grosserdf382372012-03-02 15:20:35 +0000557 void copyBinaryInst(const BinaryOperator *Inst, ValueMapT &VectorMap,
558 VectorValueMapT &ScalarMaps);
Tobias Grosser80998e72012-03-02 11:27:28 +0000559
Tobias Grosserdf382372012-03-02 15:20:35 +0000560 void copyStore(const StoreInst *Store, ValueMapT &VectorMap,
Tobias Grosser260e86d2012-03-02 15:20:28 +0000561 VectorValueMapT &ScalarMaps);
Tobias Grosser80998e72012-03-02 11:27:28 +0000562
563 bool hasVectorOperands(const Instruction *Inst, ValueMapT &VectorMap);
564
565 void copyInstruction(const Instruction *Inst, ValueMapT &VectorMap,
566 VectorValueMapT &ScalarMaps);
567
Tobias Grosser80998e72012-03-02 11:27:28 +0000568 void copyBB();
569};
570
Tobias Grosser55d52082012-03-02 15:20:39 +0000571VectorBlockGenerator::VectorBlockGenerator(IRBuilder<> &B,
572 VectorValueMapT &GlobalMaps, ScopStmt &Stmt, __isl_keep isl_set *Domain,
573 Pass *P) : BlockGenerator(B, Stmt, P), GlobalMaps(GlobalMaps),
574 Domain(Domain) {
Tobias Grosserdf382372012-03-02 15:20:35 +0000575 assert(GlobalMaps.size() > 1 && "Only one vector lane found");
Tobias Grosser08a82382012-03-02 15:20:24 +0000576 assert(Domain && "No statement domain provided");
Tobias Grosser80998e72012-03-02 11:27:28 +0000577 }
578
Tobias Grosser55d52082012-03-02 15:20:39 +0000579Value *VectorBlockGenerator::getVectorValue(const Value *Old,
580 ValueMapT &VectorMap,
581 VectorValueMapT &ScalarMaps) {
582 if (VectorMap.count(Old))
583 return VectorMap[Old];
Tobias Grosser80998e72012-03-02 11:27:28 +0000584
Tobias Grosserdf382372012-03-02 15:20:35 +0000585 int Width = getVectorWidth();
Tobias Grosser80998e72012-03-02 11:27:28 +0000586
Tobias Grosser55d52082012-03-02 15:20:39 +0000587 Value *Vector = UndefValue::get(VectorType::get(Old->getType(), Width));
Tobias Grosser80998e72012-03-02 11:27:28 +0000588
Tobias Grosserdf382372012-03-02 15:20:35 +0000589 for (int Lane = 0; Lane < Width; Lane++)
590 Vector = Builder.CreateInsertElement(Vector,
Tobias Grosser55d52082012-03-02 15:20:39 +0000591 getNewValue(Old,
592 ScalarMaps[Lane],
593 GlobalMaps[Lane]),
Tobias Grosserdf382372012-03-02 15:20:35 +0000594 Builder.getInt32(Lane));
Tobias Grosser80998e72012-03-02 11:27:28 +0000595
Tobias Grosser55d52082012-03-02 15:20:39 +0000596 VectorMap[Old] = Vector;
Tobias Grosserdf382372012-03-02 15:20:35 +0000597
598 return Vector;
Tobias Grosser80998e72012-03-02 11:27:28 +0000599}
600
601Type *VectorBlockGenerator::getVectorPtrTy(const Value *Val, int Width) {
602 PointerType *PointerTy = dyn_cast<PointerType>(Val->getType());
603 assert(PointerTy && "PointerType expected");
604
605 Type *ScalarType = PointerTy->getElementType();
606 VectorType *VectorType = VectorType::get(ScalarType, Width);
607
608 return PointerType::getUnqual(VectorType);
609}
610
611Value *VectorBlockGenerator::generateStrideOneLoad(const LoadInst *Load,
612 ValueMapT &BBMap) {
613 const Value *Pointer = Load->getPointerOperand();
614 Type *VectorPtrType = getVectorPtrTy(Pointer, getVectorWidth());
Tobias Grosser55d52082012-03-02 15:20:39 +0000615 Value *NewPointer = getNewValue(Pointer, BBMap, GlobalMaps[0]);
Tobias Grosser80998e72012-03-02 11:27:28 +0000616 Value *VectorPtr = Builder.CreateBitCast(NewPointer, VectorPtrType,
617 "vector_ptr");
618 LoadInst *VecLoad = Builder.CreateLoad(VectorPtr,
619 Load->getName() + "_p_vec_full");
620 if (!Aligned)
621 VecLoad->setAlignment(8);
622
623 return VecLoad;
624}
625
626Value *VectorBlockGenerator::generateStrideZeroLoad(const LoadInst *Load,
627 ValueMapT &BBMap) {
628 const Value *Pointer = Load->getPointerOperand();
629 Type *VectorPtrType = getVectorPtrTy(Pointer, 1);
Tobias Grosser55d52082012-03-02 15:20:39 +0000630 Value *NewPointer = getNewValue(Pointer, BBMap, GlobalMaps[0]);
Tobias Grosser80998e72012-03-02 11:27:28 +0000631 Value *VectorPtr = Builder.CreateBitCast(NewPointer, VectorPtrType,
632 Load->getName() + "_p_vec_p");
633 LoadInst *ScalarLoad= Builder.CreateLoad(VectorPtr,
634 Load->getName() + "_p_splat_one");
635
636 if (!Aligned)
637 ScalarLoad->setAlignment(8);
638
639 Constant *SplatVector =
640 Constant::getNullValue(VectorType::get(Builder.getInt32Ty(),
641 getVectorWidth()));
642
643 Value *VectorLoad = Builder.CreateShuffleVector(ScalarLoad, ScalarLoad,
644 SplatVector,
645 Load->getName()
646 + "_p_splat");
647 return VectorLoad;
648}
649
650Value *VectorBlockGenerator::generateUnknownStrideLoad(const LoadInst *Load,
651 VectorValueMapT &ScalarMaps) {
652 int VectorWidth = getVectorWidth();
653 const Value *Pointer = Load->getPointerOperand();
654 VectorType *VectorType = VectorType::get(
655 dyn_cast<PointerType>(Pointer->getType())->getElementType(), VectorWidth);
656
657 Value *Vector = UndefValue::get(VectorType);
658
659 for (int i = 0; i < VectorWidth; i++) {
Tobias Grosser55d52082012-03-02 15:20:39 +0000660 Value *NewPointer = getNewValue(Pointer, ScalarMaps[i], GlobalMaps[i]);
Tobias Grosser80998e72012-03-02 11:27:28 +0000661 Value *ScalarLoad = Builder.CreateLoad(NewPointer,
662 Load->getName() + "_p_scalar_");
663 Vector = Builder.CreateInsertElement(Vector, ScalarLoad,
664 Builder.getInt32(i),
665 Load->getName() + "_p_vec_");
666 }
667
668 return Vector;
669}
670
671void VectorBlockGenerator::generateLoad(const LoadInst *Load,
672 ValueMapT &VectorMap,
673 VectorValueMapT &ScalarMaps) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000674 Value *NewLoad;
675
676 MemoryAccess &Access = Statement.getAccessFor(Load);
677
Tobias Grosser08a82382012-03-02 15:20:24 +0000678 if (Access.isStrideZero(isl_set_copy(Domain)))
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000679 NewLoad = generateStrideZeroLoad(Load, ScalarMaps[0]);
Tobias Grosser08a82382012-03-02 15:20:24 +0000680 else if (Access.isStrideOne(isl_set_copy(Domain)))
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000681 NewLoad = generateStrideOneLoad(Load, ScalarMaps[0]);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000682 else
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000683 NewLoad = generateUnknownStrideLoad(Load, ScalarMaps);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000684
685 VectorMap[Load] = NewLoad;
686}
687
Tobias Grosser80998e72012-03-02 11:27:28 +0000688void VectorBlockGenerator::copyUnaryInst(const UnaryInstruction *Inst,
Tobias Grosserdf382372012-03-02 15:20:35 +0000689 ValueMapT &VectorMap,
690 VectorValueMapT &ScalarMaps) {
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000691 int VectorWidth = getVectorWidth();
Tobias Grosser55d52082012-03-02 15:20:39 +0000692 Value *NewOperand = getVectorValue(Inst->getOperand(0), VectorMap,
693 ScalarMaps);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000694
695 assert(isa<CastInst>(Inst) && "Can not generate vector code for instruction");
696
697 const CastInst *Cast = dyn_cast<CastInst>(Inst);
698 VectorType *DestType = VectorType::get(Inst->getType(), VectorWidth);
699 VectorMap[Inst] = Builder.CreateCast(Cast->getOpcode(), NewOperand, DestType);
700}
701
Tobias Grosser80998e72012-03-02 11:27:28 +0000702void VectorBlockGenerator::copyBinaryInst(const BinaryOperator *Inst,
Tobias Grosserdf382372012-03-02 15:20:35 +0000703 ValueMapT &VectorMap,
704 VectorValueMapT &ScalarMaps) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000705 Value *OpZero = Inst->getOperand(0);
706 Value *OpOne = Inst->getOperand(1);
707
708 Value *NewOpZero, *NewOpOne;
Tobias Grosser55d52082012-03-02 15:20:39 +0000709 NewOpZero = getVectorValue(OpZero, VectorMap, ScalarMaps);
710 NewOpOne = getVectorValue(OpOne, VectorMap, ScalarMaps);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000711
712 Value *NewInst = Builder.CreateBinOp(Inst->getOpcode(), NewOpZero,
713 NewOpOne,
714 Inst->getName() + "p_vec");
715 VectorMap[Inst] = NewInst;
716}
717
Tobias Grosserdf382372012-03-02 15:20:35 +0000718void VectorBlockGenerator::copyStore(const StoreInst *Store,
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000719 ValueMapT &VectorMap,
Tobias Grosser8927a442012-03-02 11:27:05 +0000720 VectorValueMapT &ScalarMaps) {
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000721 int VectorWidth = getVectorWidth();
722
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000723 MemoryAccess &Access = Statement.getAccessFor(Store);
724
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000725 const Value *Pointer = Store->getPointerOperand();
Tobias Grosser55d52082012-03-02 15:20:39 +0000726 Value *Vector = getVectorValue(Store->getValueOperand(), VectorMap,
Tobias Grosserdf382372012-03-02 15:20:35 +0000727 ScalarMaps);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000728
Tobias Grosser08a82382012-03-02 15:20:24 +0000729 if (Access.isStrideOne(isl_set_copy(Domain))) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000730 Type *VectorPtrType = getVectorPtrTy(Pointer, VectorWidth);
Tobias Grosser55d52082012-03-02 15:20:39 +0000731 Value *NewPointer = getNewValue(Pointer, ScalarMaps[0], GlobalMaps[0]);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000732
733 Value *VectorPtr = Builder.CreateBitCast(NewPointer, VectorPtrType,
734 "vector_ptr");
735 StoreInst *Store = Builder.CreateStore(Vector, VectorPtr);
736
737 if (!Aligned)
738 Store->setAlignment(8);
739 } else {
740 for (unsigned i = 0; i < ScalarMaps.size(); i++) {
741 Value *Scalar = Builder.CreateExtractElement(Vector,
742 Builder.getInt32(i));
Tobias Grosser55d52082012-03-02 15:20:39 +0000743 Value *NewPointer = getNewValue(Pointer, ScalarMaps[i], GlobalMaps[i]);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000744 Builder.CreateStore(Scalar, NewPointer);
745 }
746 }
747}
748
Tobias Grosser80998e72012-03-02 11:27:28 +0000749bool VectorBlockGenerator::hasVectorOperands(const Instruction *Inst,
750 ValueMapT &VectorMap) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000751 for (Instruction::const_op_iterator OI = Inst->op_begin(),
752 OE = Inst->op_end(); OI != OE; ++OI)
753 if (VectorMap.count(*OI))
754 return true;
755 return false;
756}
757
Tobias Grosser80998e72012-03-02 11:27:28 +0000758int VectorBlockGenerator::getVectorWidth() {
Tobias Grosserdf382372012-03-02 15:20:35 +0000759 return GlobalMaps.size();
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000760}
761
Tobias Grosser80998e72012-03-02 11:27:28 +0000762void VectorBlockGenerator::copyInstruction(const Instruction *Inst,
Tobias Grosser32152cb2012-03-02 11:27:18 +0000763 ValueMapT &VectorMap,
764 VectorValueMapT &ScalarMaps) {
Tobias Grosser80998e72012-03-02 11:27:28 +0000765 // Terminator instructions control the control flow. They are explicitly
766 // expressed in the clast and do not need to be copied.
767 if (Inst->isTerminator())
768 return;
769
Tobias Grosser32152cb2012-03-02 11:27:18 +0000770 if (const LoadInst *Load = dyn_cast<LoadInst>(Inst)) {
Tobias Grosser80998e72012-03-02 11:27:28 +0000771 generateLoad(Load, VectorMap, ScalarMaps);
Tobias Grosser32152cb2012-03-02 11:27:18 +0000772 return;
773 }
774
775 if (hasVectorOperands(Inst, VectorMap)) {
776 if (const StoreInst *Store = dyn_cast<StoreInst>(Inst)) {
Tobias Grosserdf382372012-03-02 15:20:35 +0000777 copyStore(Store, VectorMap, ScalarMaps);
Tobias Grosser32152cb2012-03-02 11:27:18 +0000778 return;
779 }
780
781 if (const UnaryInstruction *Unary = dyn_cast<UnaryInstruction>(Inst)) {
Tobias Grosserdf382372012-03-02 15:20:35 +0000782 copyUnaryInst(Unary, VectorMap, ScalarMaps);
Tobias Grosser32152cb2012-03-02 11:27:18 +0000783 return;
784 }
785
786 if (const BinaryOperator *Binary = dyn_cast<BinaryOperator>(Inst)) {
Tobias Grosserdf382372012-03-02 15:20:35 +0000787 copyBinaryInst(Binary, VectorMap, ScalarMaps);
Tobias Grosser32152cb2012-03-02 11:27:18 +0000788 return;
789 }
790
791 llvm_unreachable("Cannot issue vector code for this instruction");
792 }
793
794 for (int VectorLane = 0; VectorLane < getVectorWidth(); VectorLane++)
Tobias Grosserdf382372012-03-02 15:20:35 +0000795 copyInstScalar(Inst, ScalarMaps[VectorLane], GlobalMaps[VectorLane]);
Tobias Grosser32152cb2012-03-02 11:27:18 +0000796}
797
Tobias Grosser80998e72012-03-02 11:27:28 +0000798void VectorBlockGenerator::copyBB() {
Tobias Grosser14bcbd52012-03-02 11:26:52 +0000799 BasicBlock *BB = Statement.getBasicBlock();
Tobias Grosser0ac92142012-02-14 14:02:27 +0000800 BasicBlock *CopyBB = SplitBlock(Builder.GetInsertBlock(),
801 Builder.GetInsertPoint(), P);
Tobias Grosserb61e6312012-02-15 09:58:46 +0000802 CopyBB->setName("polly.stmt." + BB->getName());
Tobias Grosser0ac92142012-02-14 14:02:27 +0000803 Builder.SetInsertPoint(CopyBB->begin());
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000804
805 // Create two maps that store the mapping from the original instructions of
806 // the old basic block to their copies in the new basic block. Those maps
807 // are basic block local.
808 //
809 // As vector code generation is supported there is one map for scalar values
810 // and one for vector values.
811 //
812 // In case we just do scalar code generation, the vectorMap is not used and
813 // the scalarMap has just one dimension, which contains the mapping.
814 //
815 // In case vector code generation is done, an instruction may either appear
816 // in the vector map once (as it is calculating >vectorwidth< values at a
817 // time. Or (if the values are calculated using scalar operations), it
818 // appears once in every dimension of the scalarMap.
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000819 VectorValueMapT ScalarBlockMap(getVectorWidth());
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000820 ValueMapT VectorBlockMap;
821
822 for (BasicBlock::const_iterator II = BB->begin(), IE = BB->end();
823 II != IE; ++II)
Tobias Grosserfc1153f2012-03-02 11:27:15 +0000824 copyInstruction(II, VectorBlockMap, ScalarBlockMap);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000825}
826
Tobias Grosser75805372011-04-29 06:27:02 +0000827/// Class to generate LLVM-IR that calculates the value of a clast_expr.
828class ClastExpCodeGen {
829 IRBuilder<> &Builder;
830 const CharMapT *IVS;
831
Tobias Grosserbb137e32012-01-24 16:42:28 +0000832 Value *codegen(const clast_name *e, Type *Ty);
833 Value *codegen(const clast_term *e, Type *Ty);
834 Value *codegen(const clast_binary *e, Type *Ty);
835 Value *codegen(const clast_reduction *r, Type *Ty);
Tobias Grosser75805372011-04-29 06:27:02 +0000836public:
837
838 // A generator for clast expressions.
839 //
840 // @param B The IRBuilder that defines where the code to calculate the
841 // clast expressions should be inserted.
842 // @param IVMAP A Map that translates strings describing the induction
843 // variables to the Values* that represent these variables
844 // on the LLVM side.
Tobias Grosserbb137e32012-01-24 16:42:28 +0000845 ClastExpCodeGen(IRBuilder<> &B, CharMapT *IVMap);
Tobias Grosser75805372011-04-29 06:27:02 +0000846
847 // Generates code to calculate a given clast expression.
848 //
849 // @param e The expression to calculate.
850 // @return The Value that holds the result.
Tobias Grosserbb137e32012-01-24 16:42:28 +0000851 Value *codegen(const clast_expr *e, Type *Ty);
Tobias Grosser75805372011-04-29 06:27:02 +0000852
853 // @brief Reset the CharMap.
854 //
855 // This function is called to reset the CharMap to new one, while generating
856 // OpenMP code.
Tobias Grosserbb137e32012-01-24 16:42:28 +0000857 void setIVS(CharMapT *IVSNew);
858};
859
860Value *ClastExpCodeGen::codegen(const clast_name *e, Type *Ty) {
861 CharMapT::const_iterator I = IVS->find(e->name);
862
863 assert(I != IVS->end() && "Clast name not found");
864
865 return Builder.CreateSExtOrBitCast(I->second, Ty);
866}
867
868Value *ClastExpCodeGen::codegen(const clast_term *e, Type *Ty) {
869 APInt a = APInt_from_MPZ(e->val);
870
871 Value *ConstOne = ConstantInt::get(Builder.getContext(), a);
872 ConstOne = Builder.CreateSExtOrBitCast(ConstOne, Ty);
873
874 if (!e->var)
875 return ConstOne;
876
877 Value *var = codegen(e->var, Ty);
878 return Builder.CreateMul(ConstOne, var);
879}
880
881Value *ClastExpCodeGen::codegen(const clast_binary *e, Type *Ty) {
882 Value *LHS = codegen(e->LHS, Ty);
883
884 APInt RHS_AP = APInt_from_MPZ(e->RHS);
885
886 Value *RHS = ConstantInt::get(Builder.getContext(), RHS_AP);
887 RHS = Builder.CreateSExtOrBitCast(RHS, Ty);
888
889 switch (e->type) {
890 case clast_bin_mod:
891 return Builder.CreateSRem(LHS, RHS);
892 case clast_bin_fdiv:
893 {
Tobias Grosser9a44b972012-02-16 14:13:19 +0000894 // floord(n,d) ((n < 0) ? (n - d + 1) : n) / d
Tobias Grosser906eafe2012-02-16 09:56:10 +0000895 Value *One = ConstantInt::get(Ty, 1);
896 Value *Zero = ConstantInt::get(Ty, 0);
Tobias Grosser9a44b972012-02-16 14:13:19 +0000897 Value *Sum1 = Builder.CreateSub(LHS, RHS);
898 Value *Sum2 = Builder.CreateAdd(Sum1, One);
899 Value *isNegative = Builder.CreateICmpSLT(LHS, Zero);
900 Value *Dividend = Builder.CreateSelect(isNegative, Sum2, LHS);
901 return Builder.CreateSDiv(Dividend, RHS);
Tobias Grosserbb137e32012-01-24 16:42:28 +0000902 }
903 case clast_bin_cdiv:
904 {
Tobias Grosser9a44b972012-02-16 14:13:19 +0000905 // ceild(n,d) ((n < 0) ? n : (n + d - 1)) / d
906 Value *One = ConstantInt::get(Ty, 1);
Tobias Grosser906eafe2012-02-16 09:56:10 +0000907 Value *Zero = ConstantInt::get(Ty, 0);
Tobias Grosser9a44b972012-02-16 14:13:19 +0000908 Value *Sum1 = Builder.CreateAdd(LHS, RHS);
909 Value *Sum2 = Builder.CreateSub(Sum1, One);
910 Value *isNegative = Builder.CreateICmpSLT(LHS, Zero);
911 Value *Dividend = Builder.CreateSelect(isNegative, LHS, Sum2);
912 return Builder.CreateSDiv(Dividend, RHS);
Tobias Grosserbb137e32012-01-24 16:42:28 +0000913 }
914 case clast_bin_div:
915 return Builder.CreateSDiv(LHS, RHS);
916 };
917
918 llvm_unreachable("Unknown clast binary expression type");
919}
920
921Value *ClastExpCodeGen::codegen(const clast_reduction *r, Type *Ty) {
922 assert(( r->type == clast_red_min
923 || r->type == clast_red_max
924 || r->type == clast_red_sum)
925 && "Clast reduction type not supported");
926 Value *old = codegen(r->elts[0], Ty);
927
928 for (int i=1; i < r->n; ++i) {
929 Value *exprValue = codegen(r->elts[i], Ty);
930
931 switch (r->type) {
932 case clast_red_min:
933 {
934 Value *cmp = Builder.CreateICmpSLT(old, exprValue);
935 old = Builder.CreateSelect(cmp, old, exprValue);
936 break;
937 }
938 case clast_red_max:
939 {
940 Value *cmp = Builder.CreateICmpSGT(old, exprValue);
941 old = Builder.CreateSelect(cmp, old, exprValue);
942 break;
943 }
944 case clast_red_sum:
945 old = Builder.CreateAdd(old, exprValue);
946 break;
Tobias Grosserbb137e32012-01-24 16:42:28 +0000947 }
Tobias Grosser75805372011-04-29 06:27:02 +0000948 }
949
Tobias Grosserbb137e32012-01-24 16:42:28 +0000950 return old;
951}
952
953ClastExpCodeGen::ClastExpCodeGen(IRBuilder<> &B, CharMapT *IVMap)
954 : Builder(B), IVS(IVMap) {}
955
956Value *ClastExpCodeGen::codegen(const clast_expr *e, Type *Ty) {
957 switch(e->type) {
958 case clast_expr_name:
959 return codegen((const clast_name *)e, Ty);
960 case clast_expr_term:
961 return codegen((const clast_term *)e, Ty);
962 case clast_expr_bin:
963 return codegen((const clast_binary *)e, Ty);
964 case clast_expr_red:
965 return codegen((const clast_reduction *)e, Ty);
966 }
967
968 llvm_unreachable("Unknown clast expression!");
969}
970
971void ClastExpCodeGen::setIVS(CharMapT *IVSNew) {
972 IVS = IVSNew;
973}
Tobias Grosser75805372011-04-29 06:27:02 +0000974
975class ClastStmtCodeGen {
Tobias Grosserf74a4cd2012-03-23 10:35:18 +0000976public:
977 const std::vector<std::string> &getParallelLoops();
978
979private:
Tobias Grosser75805372011-04-29 06:27:02 +0000980 // The Scop we code generate.
981 Scop *S;
Tobias Grosser0ac92142012-02-14 14:02:27 +0000982 Pass *P;
Tobias Grosser75805372011-04-29 06:27:02 +0000983
984 // The Builder specifies the current location to code generate at.
985 IRBuilder<> &Builder;
986
987 // Map the Values from the old code to their counterparts in the new code.
988 ValueMapT ValueMap;
989
990 // clastVars maps from the textual representation of a clast variable to its
991 // current *Value. clast variables are scheduling variables, original
992 // induction variables or parameters. They are used either in loop bounds or
993 // to define the statement instance that is executed.
994 //
995 // for (s = 0; s < n + 3; ++i)
996 // for (t = s; t < m; ++j)
997 // Stmt(i = s + 3 * m, j = t);
998 //
999 // {s,t,i,j,n,m} is the set of clast variables in this clast.
Tobias Grosser46fc9ca2012-03-23 08:24:10 +00001000 CharMapT *ClastVars;
Tobias Grosser75805372011-04-29 06:27:02 +00001001
1002 // Codegenerator for clast expressions.
1003 ClastExpCodeGen ExpGen;
1004
1005 // Do we currently generate parallel code?
1006 bool parallelCodeGeneration;
1007
1008 std::vector<std::string> parallelLoops;
1009
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001010 void codegen(const clast_assignment *a);
Tobias Grosser75805372011-04-29 06:27:02 +00001011
1012 void codegen(const clast_assignment *a, ScopStmt *Statement,
1013 unsigned Dimension, int vectorDim,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001014 std::vector<ValueMapT> *VectorVMap = 0);
Tobias Grosser75805372011-04-29 06:27:02 +00001015
1016 void codegenSubstitutions(const clast_stmt *Assignment,
1017 ScopStmt *Statement, int vectorDim = 0,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001018 std::vector<ValueMapT> *VectorVMap = 0);
Tobias Grosser75805372011-04-29 06:27:02 +00001019
1020 void codegen(const clast_user_stmt *u, std::vector<Value*> *IVS = NULL,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001021 const char *iterator = NULL, isl_set *scatteringDomain = 0);
Tobias Grosser75805372011-04-29 06:27:02 +00001022
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001023 void codegen(const clast_block *b);
Tobias Grosser75805372011-04-29 06:27:02 +00001024
1025 /// @brief Create a classical sequential loop.
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001026 void codegenForSequential(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +00001027
1028 /// @brief Create OpenMP structure values.
1029 ///
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001030 /// Create a list of values that has to be stored into the OpenMP subfuncition
Tobias Grosser75805372011-04-29 06:27:02 +00001031 /// structure.
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001032 SetVector<Value*> getOMPValues();
Tobias Grosser75805372011-04-29 06:27:02 +00001033
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001034 void updateWithValueMap(OMPGenerator::ValueToValueMapTy &VMap,
1035 CharMapT &ClastVarsNew);
Tobias Grosser75805372011-04-29 06:27:02 +00001036
1037 /// @brief Create an OpenMP parallel for loop.
1038 ///
1039 /// This loop reflects a loop as if it would have been created by an OpenMP
1040 /// statement.
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001041 void codegenForOpenMP(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +00001042
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001043 bool isInnermostLoop(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +00001044
1045 /// @brief Get the number of loop iterations for this loop.
1046 /// @param f The clast for loop to check.
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001047 int getNumberOfIterations(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +00001048
1049 /// @brief Create vector instructions for this loop.
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001050 void codegenForVector(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +00001051
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001052 void codegen(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +00001053
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001054 Value *codegen(const clast_equation *eq);
Tobias Grosser75805372011-04-29 06:27:02 +00001055
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001056 void codegen(const clast_guard *g);
Tobias Grosser75805372011-04-29 06:27:02 +00001057
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001058 void codegen(const clast_stmt *stmt);
Tobias Grosser75805372011-04-29 06:27:02 +00001059
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001060 void addParameters(const CloogNames *names);
Tobias Grosser75805372011-04-29 06:27:02 +00001061
Tobias Grossere9ffea22012-03-15 09:34:48 +00001062 IntegerType *getIntPtrTy();
1063
Tobias Grosser75805372011-04-29 06:27:02 +00001064 public:
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001065 void codegen(const clast_root *r);
Tobias Grosser75805372011-04-29 06:27:02 +00001066
Tobias Grosserd596b372012-03-15 09:34:52 +00001067 ClastStmtCodeGen(Scop *scop, IRBuilder<> &B, Pass *P);
Tobias Grosser75805372011-04-29 06:27:02 +00001068};
1069}
1070
Tobias Grossere9ffea22012-03-15 09:34:48 +00001071IntegerType *ClastStmtCodeGen::getIntPtrTy() {
1072 return P->getAnalysis<TargetData>().getIntPtrType(Builder.getContext());
1073}
1074
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001075const std::vector<std::string> &ClastStmtCodeGen::getParallelLoops() {
1076 return parallelLoops;
1077}
1078
1079void ClastStmtCodeGen::codegen(const clast_assignment *a) {
Tobias Grossere9ffea22012-03-15 09:34:48 +00001080 Value *V= ExpGen.codegen(a->RHS, getIntPtrTy());
Tobias Grosser46fc9ca2012-03-23 08:24:10 +00001081 (*ClastVars)[a->LHS] = V;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001082}
1083
1084void ClastStmtCodeGen::codegen(const clast_assignment *a, ScopStmt *Statement,
1085 unsigned Dimension, int vectorDim,
1086 std::vector<ValueMapT> *VectorVMap) {
Tobias Grossere9ffea22012-03-15 09:34:48 +00001087 Value *RHS = ExpGen.codegen(a->RHS, getIntPtrTy());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001088
1089 assert(!a->LHS && "Statement assignments do not have left hand side");
1090 const PHINode *PN;
1091 PN = Statement->getInductionVariableForDimension(Dimension);
1092 const Value *V = PN;
1093
1094 if (VectorVMap)
1095 (*VectorVMap)[vectorDim][V] = RHS;
1096
1097 ValueMap[V] = RHS;
1098}
1099
1100void ClastStmtCodeGen::codegenSubstitutions(const clast_stmt *Assignment,
1101 ScopStmt *Statement, int vectorDim,
1102 std::vector<ValueMapT> *VectorVMap) {
1103 int Dimension = 0;
1104
1105 while (Assignment) {
1106 assert(CLAST_STMT_IS_A(Assignment, stmt_ass)
1107 && "Substitions are expected to be assignments");
1108 codegen((const clast_assignment *)Assignment, Statement, Dimension,
1109 vectorDim, VectorVMap);
1110 Assignment = Assignment->next;
1111 Dimension++;
1112 }
1113}
1114
1115void ClastStmtCodeGen::codegen(const clast_user_stmt *u,
1116 std::vector<Value*> *IVS , const char *iterator,
Tobias Grosser14bcbd52012-03-02 11:26:52 +00001117 isl_set *Domain) {
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001118 ScopStmt *Statement = (ScopStmt *)u->statement->usr;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001119
1120 if (u->substitutions)
1121 codegenSubstitutions(u->substitutions, Statement);
1122
Tobias Grosser80998e72012-03-02 11:27:28 +00001123 int VectorDimensions = IVS ? IVS->size() : 1;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001124
Tobias Grosser80998e72012-03-02 11:27:28 +00001125 if (VectorDimensions == 1) {
Tobias Grosser55d52082012-03-02 15:20:39 +00001126 BlockGenerator::generate(Builder, *Statement, ValueMap, P);
Tobias Grosser80998e72012-03-02 11:27:28 +00001127 return;
1128 }
1129
1130 VectorValueMapT VectorMap(VectorDimensions);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001131
1132 if (IVS) {
1133 assert (u->substitutions && "Substitutions expected!");
1134 int i = 0;
1135 for (std::vector<Value*>::iterator II = IVS->begin(), IE = IVS->end();
1136 II != IE; ++II) {
Tobias Grosser46fc9ca2012-03-23 08:24:10 +00001137 (*ClastVars)[iterator] = *II;
Tobias Grosser14bcbd52012-03-02 11:26:52 +00001138 codegenSubstitutions(u->substitutions, Statement, i, &VectorMap);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001139 i++;
1140 }
1141 }
1142
Tobias Grosser55d52082012-03-02 15:20:39 +00001143 VectorBlockGenerator::generate(Builder, *Statement, VectorMap, Domain, P);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001144}
1145
1146void ClastStmtCodeGen::codegen(const clast_block *b) {
1147 if (b->body)
1148 codegen(b->body);
1149}
1150
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001151void ClastStmtCodeGen::codegenForSequential(const clast_for *f) {
1152 Value *LowerBound, *UpperBound, *IV, *Stride;
Tobias Grosser0ac92142012-02-14 14:02:27 +00001153 BasicBlock *AfterBB;
Tobias Grossere9ffea22012-03-15 09:34:48 +00001154 Type *IntPtrTy = getIntPtrTy();
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001155
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001156 LowerBound = ExpGen.codegen(f->LB, IntPtrTy);
1157 UpperBound = ExpGen.codegen(f->UB, IntPtrTy);
1158 Stride = Builder.getInt(APInt_from_MPZ(f->stride));
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001159
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001160 IV = createLoop(LowerBound, UpperBound, Stride, &Builder, P, &AfterBB);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001161
1162 // Add loop iv to symbols.
Tobias Grosser46fc9ca2012-03-23 08:24:10 +00001163 (*ClastVars)[f->iterator] = IV;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001164
1165 if (f->body)
1166 codegen(f->body);
1167
1168 // Loop is finished, so remove its iv from the live symbols.
Tobias Grosser46fc9ca2012-03-23 08:24:10 +00001169 ClastVars->erase(f->iterator);
Tobias Grosser0ac92142012-02-14 14:02:27 +00001170 Builder.SetInsertPoint(AfterBB->begin());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001171}
1172
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001173SetVector<Value*> ClastStmtCodeGen::getOMPValues() {
1174 SetVector<Value*> Values;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001175
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001176 // The clast variables
Tobias Grosser46fc9ca2012-03-23 08:24:10 +00001177 for (CharMapT::iterator I = ClastVars->begin(), E = ClastVars->end();
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001178 I != E; I++)
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001179 Values.insert(I->second);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001180
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001181 // The memory reference base addresses
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001182 for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI) {
1183 ScopStmt *Stmt = *SI;
1184 for (SmallVector<MemoryAccess*, 8>::iterator I = Stmt->memacc_begin(),
1185 E = Stmt->memacc_end(); I != E; ++I) {
1186 Value *BaseAddr = const_cast<Value*>((*I)->getBaseAddr());
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001187 Values.insert((BaseAddr));
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001188 }
1189 }
1190
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001191 return Values;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001192}
1193
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001194void ClastStmtCodeGen::updateWithValueMap(OMPGenerator::ValueToValueMapTy &VMap,
1195 CharMapT &ClastVarsNew) {
1196 std::set<Value*> Inserted;
1197
Tobias Grosser46fc9ca2012-03-23 08:24:10 +00001198 for (CharMapT::iterator I = ClastVars->begin(), E = ClastVars->end();
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001199 I != E; I++) {
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001200 ClastVarsNew[I->first] = VMap[I->second];
1201 Inserted.insert(I->second);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001202 }
1203
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001204 for (std::map<Value*, Value*>::iterator I = VMap.begin(), E = VMap.end();
1205 I != E; ++I) {
1206 if (Inserted.count(I->first))
1207 continue;
1208
1209 ValueMap[I->first] = I->second;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001210 }
1211}
1212
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001213void ClastStmtCodeGen::codegenForOpenMP(const clast_for *For) {
Tobias Grosserebf30082012-03-23 12:20:32 +00001214 Value *Stride, *LB, *UB, *IV;
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001215 BasicBlock::iterator LoopBody;
1216 IntegerType *IntPtrTy = getIntPtrTy();
1217 SetVector<Value*> Values;
1218 OMPGenerator::ValueToValueMapTy VMap;
1219 OMPGenerator OMPGen(Builder, P);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001220
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001221
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001222 Stride = Builder.getInt(APInt_from_MPZ(For->stride));
1223 Stride = Builder.CreateSExtOrBitCast(Stride, IntPtrTy);
Tobias Grosserebf30082012-03-23 12:20:32 +00001224 LB = ExpGen.codegen(For->LB, IntPtrTy);
1225 UB = ExpGen.codegen(For->UB, IntPtrTy);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001226
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001227 Values = getOMPValues();
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001228
Tobias Grosserebf30082012-03-23 12:20:32 +00001229 IV = OMPGen.createParallelLoop(LB, UB, Stride, Values, VMap, &LoopBody);
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001230 BasicBlock::iterator AfterLoop = Builder.GetInsertPoint();
1231 Builder.SetInsertPoint(LoopBody);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001232
1233 // Use clastVarsOMP during code generation of the OpenMP subfunction.
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001234 CharMapT ClastVarsOMP;
1235 updateWithValueMap(VMap, ClastVarsOMP);
Tobias Grosser46fc9ca2012-03-23 08:24:10 +00001236 CharMapT *OldClastVars = ClastVars;
1237 ClastVars = &ClastVarsOMP;
1238 ExpGen.setIVS(&ClastVarsOMP);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001239
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001240 // Add loop iv to symbols.
1241 (*ClastVars)[For->iterator] = IV;
1242
1243 if (For->body)
1244 codegen(For->body);
1245
1246 // Loop is finished, so remove its iv from the live symbols.
1247 ClastVars->erase(For->iterator);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001248
1249 // Restore the old clastVars.
Tobias Grosser46fc9ca2012-03-23 08:24:10 +00001250 ClastVars = OldClastVars;
1251 ExpGen.setIVS(OldClastVars);
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001252 Builder.SetInsertPoint(AfterLoop);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001253}
1254
1255bool ClastStmtCodeGen::isInnermostLoop(const clast_for *f) {
1256 const clast_stmt *stmt = f->body;
1257
1258 while (stmt) {
1259 if (!CLAST_STMT_IS_A(stmt, stmt_user))
1260 return false;
1261
1262 stmt = stmt->next;
1263 }
1264
1265 return true;
1266}
1267
1268int ClastStmtCodeGen::getNumberOfIterations(const clast_for *f) {
1269 isl_set *loopDomain = isl_set_copy(isl_set_from_cloog_domain(f->domain));
1270 isl_set *tmp = isl_set_copy(loopDomain);
1271
1272 // Calculate a map similar to the identity map, but with the last input
1273 // and output dimension not related.
1274 // [i0, i1, i2, i3] -> [i0, i1, i2, o0]
1275 isl_space *Space = isl_set_get_space(loopDomain);
1276 Space = isl_space_drop_outputs(Space,
1277 isl_set_dim(loopDomain, isl_dim_set) - 2, 1);
1278 Space = isl_space_map_from_set(Space);
1279 isl_map *identity = isl_map_identity(Space);
1280 identity = isl_map_add_dims(identity, isl_dim_in, 1);
1281 identity = isl_map_add_dims(identity, isl_dim_out, 1);
1282
1283 isl_map *map = isl_map_from_domain_and_range(tmp, loopDomain);
1284 map = isl_map_intersect(map, identity);
1285
1286 isl_map *lexmax = isl_map_lexmax(isl_map_copy(map));
1287 isl_map *lexmin = isl_map_lexmin(map);
1288 isl_map *sub = isl_map_sum(lexmax, isl_map_neg(lexmin));
1289
1290 isl_set *elements = isl_map_range(sub);
1291
1292 if (!isl_set_is_singleton(elements)) {
1293 isl_set_free(elements);
1294 return -1;
1295 }
1296
1297 isl_point *p = isl_set_sample_point(elements);
1298
1299 isl_int v;
1300 isl_int_init(v);
1301 isl_point_get_coordinate(p, isl_dim_set, isl_set_n_dim(loopDomain) - 1, &v);
1302 int numberIterations = isl_int_get_si(v);
1303 isl_int_clear(v);
1304 isl_point_free(p);
1305
1306 return (numberIterations) / isl_int_get_si(f->stride) + 1;
1307}
1308
Tobias Grosser2da263e2012-03-15 09:34:55 +00001309void ClastStmtCodeGen::codegenForVector(const clast_for *F) {
1310 DEBUG(dbgs() << "Vectorizing loop '" << F->iterator << "'\n";);
1311 int VectorWidth = getNumberOfIterations(F);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001312
Tobias Grosser2da263e2012-03-15 09:34:55 +00001313 Value *LB = ExpGen.codegen(F->LB, getIntPtrTy());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001314
Tobias Grosser2da263e2012-03-15 09:34:55 +00001315 APInt Stride = APInt_from_MPZ(F->stride);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001316 IntegerType *LoopIVType = dyn_cast<IntegerType>(LB->getType());
1317 Stride = Stride.zext(LoopIVType->getBitWidth());
1318 Value *StrideValue = ConstantInt::get(LoopIVType, Stride);
1319
Tobias Grosser2da263e2012-03-15 09:34:55 +00001320 std::vector<Value*> IVS(VectorWidth);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001321 IVS[0] = LB;
1322
Tobias Grosser2da263e2012-03-15 09:34:55 +00001323 for (int i = 1; i < VectorWidth; i++)
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001324 IVS[i] = Builder.CreateAdd(IVS[i-1], StrideValue, "p_vector_iv");
1325
Tobias Grosser00d898d2012-03-15 09:34:58 +00001326 isl_set *Domain = isl_set_from_cloog_domain(F->domain);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001327
1328 // Add loop iv to symbols.
Tobias Grosser46fc9ca2012-03-23 08:24:10 +00001329 (*ClastVars)[F->iterator] = LB;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001330
Tobias Grosser2da263e2012-03-15 09:34:55 +00001331 const clast_stmt *Stmt = F->body;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001332
Tobias Grosser2da263e2012-03-15 09:34:55 +00001333 while (Stmt) {
Tobias Grosser00d898d2012-03-15 09:34:58 +00001334 codegen((const clast_user_stmt *)Stmt, &IVS, F->iterator,
1335 isl_set_copy(Domain));
Tobias Grosser2da263e2012-03-15 09:34:55 +00001336 Stmt = Stmt->next;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001337 }
1338
1339 // Loop is finished, so remove its iv from the live symbols.
Tobias Grosser00d898d2012-03-15 09:34:58 +00001340 isl_set_free(Domain);
Tobias Grosser46fc9ca2012-03-23 08:24:10 +00001341 ClastVars->erase(F->iterator);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001342}
1343
1344void ClastStmtCodeGen::codegen(const clast_for *f) {
Tobias Grosserd596b372012-03-15 09:34:52 +00001345 if ((Vector || OpenMP) && P->getAnalysis<Dependences>().isParallelFor(f)) {
Tobias Grosserce3f5372012-03-02 11:26:42 +00001346 if (Vector && isInnermostLoop(f) && (-1 != getNumberOfIterations(f))
1347 && (getNumberOfIterations(f) <= 16)) {
1348 codegenForVector(f);
1349 return;
1350 }
1351
1352 if (OpenMP && !parallelCodeGeneration) {
1353 parallelCodeGeneration = true;
1354 parallelLoops.push_back(f->iterator);
1355 codegenForOpenMP(f);
1356 parallelCodeGeneration = false;
1357 return;
1358 }
1359 }
1360
1361 codegenForSequential(f);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001362}
1363
1364Value *ClastStmtCodeGen::codegen(const clast_equation *eq) {
Tobias Grossere9ffea22012-03-15 09:34:48 +00001365 Value *LHS = ExpGen.codegen(eq->LHS, getIntPtrTy());
1366 Value *RHS = ExpGen.codegen(eq->RHS, getIntPtrTy());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001367 CmpInst::Predicate P;
1368
1369 if (eq->sign == 0)
1370 P = ICmpInst::ICMP_EQ;
1371 else if (eq->sign > 0)
1372 P = ICmpInst::ICMP_SGE;
1373 else
1374 P = ICmpInst::ICMP_SLE;
1375
1376 return Builder.CreateICmp(P, LHS, RHS);
1377}
1378
1379void ClastStmtCodeGen::codegen(const clast_guard *g) {
1380 Function *F = Builder.GetInsertBlock()->getParent();
1381 LLVMContext &Context = F->getContext();
Tobias Grosser0ac92142012-02-14 14:02:27 +00001382
1383 BasicBlock *CondBB = SplitBlock(Builder.GetInsertBlock(),
1384 Builder.GetInsertPoint(), P);
1385 CondBB->setName("polly.cond");
1386 BasicBlock *MergeBB = SplitBlock(CondBB, CondBB->begin(), P);
1387 MergeBB->setName("polly.merge");
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001388 BasicBlock *ThenBB = BasicBlock::Create(Context, "polly.then", F);
Tobias Grosser0ac92142012-02-14 14:02:27 +00001389
Tobias Grosserd596b372012-03-15 09:34:52 +00001390 DominatorTree &DT = P->getAnalysis<DominatorTree>();
1391 DT.addNewBlock(ThenBB, CondBB);
1392 DT.changeImmediateDominator(MergeBB, CondBB);
Tobias Grosser0ac92142012-02-14 14:02:27 +00001393
1394 CondBB->getTerminator()->eraseFromParent();
1395
1396 Builder.SetInsertPoint(CondBB);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001397
1398 Value *Predicate = codegen(&(g->eq[0]));
1399
1400 for (int i = 1; i < g->n; ++i) {
1401 Value *TmpPredicate = codegen(&(g->eq[i]));
1402 Predicate = Builder.CreateAnd(Predicate, TmpPredicate);
1403 }
1404
1405 Builder.CreateCondBr(Predicate, ThenBB, MergeBB);
1406 Builder.SetInsertPoint(ThenBB);
Tobias Grosser0ac92142012-02-14 14:02:27 +00001407 Builder.CreateBr(MergeBB);
1408 Builder.SetInsertPoint(ThenBB->begin());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001409
1410 codegen(g->then);
Tobias Grosser62a3c962012-02-16 09:56:21 +00001411
1412 Builder.SetInsertPoint(MergeBB->begin());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001413}
1414
1415void ClastStmtCodeGen::codegen(const clast_stmt *stmt) {
1416 if (CLAST_STMT_IS_A(stmt, stmt_root))
1417 assert(false && "No second root statement expected");
1418 else if (CLAST_STMT_IS_A(stmt, stmt_ass))
1419 codegen((const clast_assignment *)stmt);
1420 else if (CLAST_STMT_IS_A(stmt, stmt_user))
1421 codegen((const clast_user_stmt *)stmt);
1422 else if (CLAST_STMT_IS_A(stmt, stmt_block))
1423 codegen((const clast_block *)stmt);
1424 else if (CLAST_STMT_IS_A(stmt, stmt_for))
1425 codegen((const clast_for *)stmt);
1426 else if (CLAST_STMT_IS_A(stmt, stmt_guard))
1427 codegen((const clast_guard *)stmt);
1428
1429 if (stmt->next)
1430 codegen(stmt->next);
1431}
1432
1433void ClastStmtCodeGen::addParameters(const CloogNames *names) {
Tobias Grosserd596b372012-03-15 09:34:52 +00001434 SCEVExpander Rewriter(P->getAnalysis<ScalarEvolution>(), "polly");
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001435
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001436 int i = 0;
1437 for (Scop::param_iterator PI = S->param_begin(), PE = S->param_end();
1438 PI != PE; ++PI) {
1439 assert(i < names->nb_parameters && "Not enough parameter names");
1440
1441 const SCEV *Param = *PI;
1442 Type *Ty = Param->getType();
1443
1444 Instruction *insertLocation = --(Builder.GetInsertBlock()->end());
1445 Value *V = Rewriter.expandCodeFor(Param, Ty, insertLocation);
Tobias Grosser46fc9ca2012-03-23 08:24:10 +00001446 (*ClastVars)[names->parameters[i]] = V;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001447
1448 ++i;
1449 }
1450}
1451
1452void ClastStmtCodeGen::codegen(const clast_root *r) {
Tobias Grosser46fc9ca2012-03-23 08:24:10 +00001453 ClastVars = new CharMapT();
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001454 addParameters(r->names);
Tobias Grosser46fc9ca2012-03-23 08:24:10 +00001455 ExpGen.setIVS(ClastVars);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001456
1457 parallelCodeGeneration = false;
1458
1459 const clast_stmt *stmt = (const clast_stmt*) r;
1460 if (stmt->next)
1461 codegen(stmt->next);
1462
Tobias Grosser46fc9ca2012-03-23 08:24:10 +00001463 delete ClastVars;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001464}
1465
Tobias Grosserd596b372012-03-15 09:34:52 +00001466ClastStmtCodeGen::ClastStmtCodeGen(Scop *scop, IRBuilder<> &B, Pass *P) :
1467 S(scop), P(P), Builder(B), ExpGen(Builder, NULL) {}
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001468
Tobias Grosser75805372011-04-29 06:27:02 +00001469namespace {
1470class CodeGeneration : public ScopPass {
1471 Region *region;
1472 Scop *S;
1473 DominatorTree *DT;
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001474 RegionInfo *RI;
Tobias Grosser75805372011-04-29 06:27:02 +00001475
1476 std::vector<std::string> parallelLoops;
1477
1478 public:
1479 static char ID;
1480
1481 CodeGeneration() : ScopPass(ID) {}
1482
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001483 // Split the entry edge of the region and generate a new basic block on this
1484 // edge. This function also updates ScopInfo and RegionInfo.
1485 //
1486 // @param region The region where the entry edge will be splitted.
1487 BasicBlock *splitEdgeAdvanced(Region *region) {
1488 BasicBlock *newBlock;
1489 BasicBlock *splitBlock;
1490
1491 newBlock = SplitEdge(region->getEnteringBlock(), region->getEntry(), this);
1492
1493 if (DT->dominates(region->getEntry(), newBlock)) {
Tobias Grossercb47dfe2012-02-15 09:58:50 +00001494 BasicBlock *OldBlock = region->getEntry();
1495 std::string OldName = OldBlock->getName();
1496
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001497 // Update ScopInfo.
1498 for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI)
Tobias Grosserf12cea42012-02-15 09:58:53 +00001499 if ((*SI)->getBasicBlock() == OldBlock) {
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001500 (*SI)->setBasicBlock(newBlock);
1501 break;
1502 }
1503
1504 // Update RegionInfo.
Tobias Grossercb47dfe2012-02-15 09:58:50 +00001505 splitBlock = OldBlock;
1506 OldBlock->setName("polly.split");
1507 newBlock->setName(OldName);
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001508 region->replaceEntry(newBlock);
Tobias Grosser7a16c892011-05-14 19:01:55 +00001509 RI->setRegionFor(newBlock, region);
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001510 } else {
1511 RI->setRegionFor(newBlock, region->getParent());
1512 splitBlock = newBlock;
1513 }
1514
1515 return splitBlock;
1516 }
1517
1518 // Create a split block that branches either to the old code or to a new basic
1519 // block where the new code can be inserted.
1520 //
Tobias Grosserbd608a82012-02-12 12:09:41 +00001521 // @param Builder A builder that will be set to point to a basic block, where
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001522 // the new code can be generated.
1523 // @return The split basic block.
Tobias Grosserbd608a82012-02-12 12:09:41 +00001524 BasicBlock *addSplitAndStartBlock(IRBuilder<> *Builder) {
1525 BasicBlock *StartBlock, *SplitBlock;
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001526
Tobias Grosserbd608a82012-02-12 12:09:41 +00001527 SplitBlock = splitEdgeAdvanced(region);
1528 SplitBlock->setName("polly.split_new_and_old");
1529 Function *F = SplitBlock->getParent();
1530 StartBlock = BasicBlock::Create(F->getContext(), "polly.start", F);
1531 SplitBlock->getTerminator()->eraseFromParent();
1532 Builder->SetInsertPoint(SplitBlock);
1533 Builder->CreateCondBr(Builder->getTrue(), StartBlock, region->getEntry());
1534 DT->addNewBlock(StartBlock, SplitBlock);
1535 Builder->SetInsertPoint(StartBlock);
1536 return SplitBlock;
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001537 }
1538
1539 // Merge the control flow of the newly generated code with the existing code.
1540 //
Tobias Grosserbd608a82012-02-12 12:09:41 +00001541 // @param SplitBlock The basic block where the control flow was split between
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001542 // old and new version of the Scop.
Tobias Grosserbd608a82012-02-12 12:09:41 +00001543 // @param Builder An IRBuilder that points to the last instruction of the
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001544 // newly generated code.
Tobias Grosserbd608a82012-02-12 12:09:41 +00001545 void mergeControlFlow(BasicBlock *SplitBlock, IRBuilder<> *Builder) {
1546 BasicBlock *MergeBlock;
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001547 Region *R = region;
1548
1549 if (R->getExit()->getSinglePredecessor())
1550 // No splitEdge required. A block with a single predecessor cannot have
1551 // PHI nodes that would complicate life.
Tobias Grosserbd608a82012-02-12 12:09:41 +00001552 MergeBlock = R->getExit();
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001553 else {
Tobias Grosserbd608a82012-02-12 12:09:41 +00001554 MergeBlock = SplitEdge(R->getExitingBlock(), R->getExit(), this);
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001555 // SplitEdge will never split R->getExit(), as R->getExit() has more than
1556 // one predecessor. Hence, mergeBlock is always a newly generated block.
Tobias Grosserbd608a82012-02-12 12:09:41 +00001557 R->replaceExit(MergeBlock);
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001558 }
1559
Tobias Grosserbd608a82012-02-12 12:09:41 +00001560 Builder->CreateBr(MergeBlock);
Tobias Grosser8518bbe2012-02-12 12:09:46 +00001561 MergeBlock->setName("polly.merge_new_and_old");
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001562
Tobias Grosserbd608a82012-02-12 12:09:41 +00001563 if (DT->dominates(SplitBlock, MergeBlock))
1564 DT->changeImmediateDominator(MergeBlock, SplitBlock);
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001565 }
1566
Tobias Grosser75805372011-04-29 06:27:02 +00001567 bool runOnScop(Scop &scop) {
1568 S = &scop;
1569 region = &S->getRegion();
Tobias Grosser75805372011-04-29 06:27:02 +00001570 DT = &getAnalysis<DominatorTree>();
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001571 RI = &getAnalysis<RegionInfo>();
Tobias Grosser75805372011-04-29 06:27:02 +00001572
1573 parallelLoops.clear();
1574
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001575 assert(region->isSimple() && "Only simple regions are supported");
Tobias Grosser76d7c522011-05-14 19:01:37 +00001576
Tobias Grosser5772e652012-02-01 14:23:33 +00001577 // In the CFG the optimized code of the SCoP is generated next to the
1578 // original code. Both the new and the original version of the code remain
1579 // in the CFG. A branch statement decides which version is executed.
1580 // For now, we always execute the new version (the old one is dead code
1581 // eliminated by the cleanup passes). In the future we may decide to execute
1582 // the new version only if certain run time checks succeed. This will be
1583 // useful to support constructs for which we cannot prove all assumptions at
1584 // compile time.
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001585 //
1586 // Before transformation:
1587 //
1588 // bb0
1589 // |
1590 // orig_scop
1591 // |
1592 // bb1
1593 //
1594 // After transformation:
1595 // bb0
1596 // |
1597 // polly.splitBlock
Tobias Grosser2bd3af12011-08-01 22:39:00 +00001598 // / \.
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001599 // | startBlock
1600 // | |
1601 // orig_scop new_scop
1602 // \ /
1603 // \ /
1604 // bb1 (joinBlock)
1605 IRBuilder<> builder(region->getEntry());
Tobias Grosser75805372011-04-29 06:27:02 +00001606
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001607 // The builder will be set to startBlock.
1608 BasicBlock *splitBlock = addSplitAndStartBlock(&builder);
Tobias Grosser0ac92142012-02-14 14:02:27 +00001609 BasicBlock *StartBlock = builder.GetInsertBlock();
Tobias Grosser75805372011-04-29 06:27:02 +00001610
Tobias Grosser0ac92142012-02-14 14:02:27 +00001611 mergeControlFlow(splitBlock, &builder);
1612 builder.SetInsertPoint(StartBlock->begin());
1613
Tobias Grosserd596b372012-03-15 09:34:52 +00001614 ClastStmtCodeGen CodeGen(S, builder, this);
Tobias Grosser3fdecae2011-05-14 19:02:39 +00001615 CloogInfo &C = getAnalysis<CloogInfo>();
1616 CodeGen.codegen(C.getClast());
Tobias Grosser75805372011-04-29 06:27:02 +00001617
Tobias Grosser75805372011-04-29 06:27:02 +00001618 parallelLoops.insert(parallelLoops.begin(),
1619 CodeGen.getParallelLoops().begin(),
1620 CodeGen.getParallelLoops().end());
1621
Tobias Grosserabb6dcd2011-05-14 19:02:34 +00001622 return true;
Tobias Grosser75805372011-04-29 06:27:02 +00001623 }
1624
1625 virtual void printScop(raw_ostream &OS) const {
1626 for (std::vector<std::string>::const_iterator PI = parallelLoops.begin(),
1627 PE = parallelLoops.end(); PI != PE; ++PI)
1628 OS << "Parallel loop with iterator '" << *PI << "' generated\n";
1629 }
1630
1631 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
1632 AU.addRequired<CloogInfo>();
1633 AU.addRequired<Dependences>();
1634 AU.addRequired<DominatorTree>();
Tobias Grosser75805372011-04-29 06:27:02 +00001635 AU.addRequired<RegionInfo>();
Tobias Grosser73600b82011-10-08 00:30:40 +00001636 AU.addRequired<ScalarEvolution>();
Tobias Grosser75805372011-04-29 06:27:02 +00001637 AU.addRequired<ScopDetection>();
1638 AU.addRequired<ScopInfo>();
1639 AU.addRequired<TargetData>();
1640
1641 AU.addPreserved<CloogInfo>();
1642 AU.addPreserved<Dependences>();
Tobias Grosser5d6eb862011-05-14 19:02:45 +00001643
Tobias Grosser4e3f9a42011-05-23 15:23:36 +00001644 // FIXME: We do not create LoopInfo for the newly generated loops.
Tobias Grosser75805372011-04-29 06:27:02 +00001645 AU.addPreserved<LoopInfo>();
1646 AU.addPreserved<DominatorTree>();
Tobias Grosser75805372011-04-29 06:27:02 +00001647 AU.addPreserved<ScopDetection>();
1648 AU.addPreserved<ScalarEvolution>();
Tobias Grosser5d6eb862011-05-14 19:02:45 +00001649
Tobias Grosser4e3f9a42011-05-23 15:23:36 +00001650 // FIXME: We do not yet add regions for the newly generated code to the
1651 // region tree.
Tobias Grosser75805372011-04-29 06:27:02 +00001652 AU.addPreserved<RegionInfo>();
1653 AU.addPreserved<TempScopInfo>();
1654 AU.addPreserved<ScopInfo>();
1655 AU.addPreservedID(IndependentBlocksID);
1656 }
1657};
1658}
1659
1660char CodeGeneration::ID = 1;
1661
Tobias Grosser73600b82011-10-08 00:30:40 +00001662INITIALIZE_PASS_BEGIN(CodeGeneration, "polly-codegen",
Tobias Grosser3c2efba2012-03-06 07:38:57 +00001663 "Polly - Create LLVM-IR from SCoPs", false, false)
Tobias Grosser73600b82011-10-08 00:30:40 +00001664INITIALIZE_PASS_DEPENDENCY(CloogInfo)
1665INITIALIZE_PASS_DEPENDENCY(Dependences)
1666INITIALIZE_PASS_DEPENDENCY(DominatorTree)
1667INITIALIZE_PASS_DEPENDENCY(RegionInfo)
1668INITIALIZE_PASS_DEPENDENCY(ScalarEvolution)
1669INITIALIZE_PASS_DEPENDENCY(ScopDetection)
1670INITIALIZE_PASS_DEPENDENCY(TargetData)
1671INITIALIZE_PASS_END(CodeGeneration, "polly-codegen",
Tobias Grosser3c2efba2012-03-06 07:38:57 +00001672 "Polly - Create LLVM-IR from SCoPs", false, false)
Tobias Grosser75805372011-04-29 06:27:02 +00001673
Tobias Grosser7ffe4e82011-11-17 12:56:10 +00001674Pass *polly::createCodeGenerationPass() {
Tobias Grosser75805372011-04-29 06:27:02 +00001675 return new CodeGeneration();
1676}