blob: 3a0e7f0ee1157b6ac86bb7f5ea2446383e78a36a [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"
Tobias Grosser900893d2012-03-29 13:10:26 +000036#include "llvm/ADT/PostOrderIterator.h"
Tobias Grosserbda1f8f2012-02-01 14:23:29 +000037#include "llvm/Analysis/LoopInfo.h"
38#include "llvm/Analysis/ScalarEvolutionExpander.h"
Tobias Grosser75805372011-04-29 06:27:02 +000039#include "llvm/Support/CommandLine.h"
40#include "llvm/Support/Debug.h"
41#include "llvm/Support/IRBuilder.h"
Tobias Grosser75805372011-04-29 06:27:02 +000042#include "llvm/Target/TargetData.h"
Tobias Grosserbda1f8f2012-02-01 14:23:29 +000043#include "llvm/Transforms/Utils/BasicBlockUtils.h"
Tobias Grosser75805372011-04-29 06:27:02 +000044
45#define CLOOG_INT_GMP 1
46#include "cloog/cloog.h"
47#include "cloog/isl/cloog.h"
48
Raghesh Aloora71989c2011-12-28 02:48:26 +000049#include "isl/aff.h"
50
Tobias Grosser75805372011-04-29 06:27:02 +000051#include <vector>
52#include <utility>
53
54using namespace polly;
55using namespace llvm;
56
57struct isl_set;
58
59namespace polly {
60
Tobias Grosser67707b72011-10-23 20:59:40 +000061bool EnablePollyVector;
62
63static cl::opt<bool, true>
Tobias Grosser75805372011-04-29 06:27:02 +000064Vector("enable-polly-vector",
65 cl::desc("Enable polly vector code generation"), cl::Hidden,
Tobias Grosser0acfcdb2012-03-16 17:17:16 +000066 cl::location(EnablePollyVector), cl::init(false), cl::ZeroOrMore);
Tobias Grosser75805372011-04-29 06:27:02 +000067
68static cl::opt<bool>
69OpenMP("enable-polly-openmp",
70 cl::desc("Generate OpenMP parallel code"), cl::Hidden,
71 cl::value_desc("OpenMP code generation enabled if true"),
Tobias Grosser0acfcdb2012-03-16 17:17:16 +000072 cl::init(false), cl::ZeroOrMore);
Tobias Grosser75805372011-04-29 06:27:02 +000073
74static cl::opt<bool>
75AtLeastOnce("enable-polly-atLeastOnce",
76 cl::desc("Give polly the hint, that every loop is executed at least"
77 "once"), cl::Hidden,
78 cl::value_desc("OpenMP code generation enabled if true"),
Tobias Grosser0acfcdb2012-03-16 17:17:16 +000079 cl::init(false), cl::ZeroOrMore);
Tobias Grosser75805372011-04-29 06:27:02 +000080
81static cl::opt<bool>
82Aligned("enable-polly-aligned",
83 cl::desc("Assumed aligned memory accesses."), cl::Hidden,
84 cl::value_desc("OpenMP code generation enabled if true"),
Tobias Grosser0acfcdb2012-03-16 17:17:16 +000085 cl::init(false), cl::ZeroOrMore);
Tobias Grosser75805372011-04-29 06:27:02 +000086
Tobias Grosser75805372011-04-29 06:27:02 +000087typedef DenseMap<const Value*, Value*> ValueMapT;
88typedef DenseMap<const char*, Value*> CharMapT;
89typedef std::vector<ValueMapT> VectorValueMapT;
90
Tobias Grosser642c4112012-03-02 11:27:25 +000091class IslGenerator;
92
93class IslGenerator {
94public:
Tobias Grosserd6adda32012-03-23 08:21:22 +000095 IslGenerator(IRBuilder<> &Builder, std::vector<Value *> &IVS) :
96 Builder(Builder), IVS(IVS) {}
Tobias Grosser642c4112012-03-02 11:27:25 +000097 Value *generateIslInt(__isl_take isl_int Int);
98 Value *generateIslAff(__isl_take isl_aff *Aff);
99 Value *generateIslPwAff(__isl_take isl_pw_aff *PwAff);
100
101private:
102 typedef struct {
103 Value *Result;
104 class IslGenerator *Generator;
105 } IslGenInfo;
106
107 IRBuilder<> &Builder;
Tobias Grosserd6adda32012-03-23 08:21:22 +0000108 std::vector<Value *> &IVS;
Tobias Grosser642c4112012-03-02 11:27:25 +0000109 static int mergeIslAffValues(__isl_take isl_set *Set,
110 __isl_take isl_aff *Aff, void *User);
111};
112
113Value *IslGenerator::generateIslInt(isl_int Int) {
114 mpz_t IntMPZ;
115 mpz_init(IntMPZ);
116 isl_int_get_gmp(Int, IntMPZ);
117 Value *IntValue = Builder.getInt(APInt_from_MPZ(IntMPZ));
118 mpz_clear(IntMPZ);
119 return IntValue;
120}
121
122Value *IslGenerator::generateIslAff(__isl_take isl_aff *Aff) {
Tobias Grosserd6adda32012-03-23 08:21:22 +0000123 Value *Result;
Tobias Grosser642c4112012-03-02 11:27:25 +0000124 Value *ConstValue;
125 isl_int ConstIsl;
126
127 isl_int_init(ConstIsl);
128 isl_aff_get_constant(Aff, &ConstIsl);
129 ConstValue = generateIslInt(ConstIsl);
Tobias Grosserd6adda32012-03-23 08:21:22 +0000130 Type *Ty = Builder.getInt64Ty();
Tobias Grosser642c4112012-03-02 11:27:25 +0000131
Tobias Grosserd6adda32012-03-23 08:21:22 +0000132 // FIXME: We should give the constant and coefficients the right type. Here
133 // we force it into i64.
134 Result = Builder.CreateSExtOrBitCast(ConstValue, Ty);
135
136 unsigned int NbInputDims = isl_aff_dim(Aff, isl_dim_in);
137
138 assert((IVS.size() == NbInputDims) && "The Dimension of Induction Variables"
139 "must match the dimension of the affine space.");
140
141 isl_int CoefficientIsl;
142 isl_int_init(CoefficientIsl);
143
144 for (unsigned int i = 0; i < NbInputDims; ++i) {
145 Value *CoefficientValue;
146 isl_aff_get_coefficient(Aff, isl_dim_in, i, &CoefficientIsl);
147
148 if (isl_int_is_zero(CoefficientIsl))
149 continue;
150
151 CoefficientValue = generateIslInt(CoefficientIsl);
152 CoefficientValue = Builder.CreateIntCast(CoefficientValue, Ty, true);
153 Value *IV = Builder.CreateIntCast(IVS[i], Ty, true);
154 Value *PAdd = Builder.CreateMul(CoefficientValue, IV, "p_mul_coeff");
155 Result = Builder.CreateAdd(Result, PAdd, "p_sum_coeff");
156 }
157
158 isl_int_clear(CoefficientIsl);
Tobias Grosser642c4112012-03-02 11:27:25 +0000159 isl_int_clear(ConstIsl);
160 isl_aff_free(Aff);
161
Tobias Grosserd6adda32012-03-23 08:21:22 +0000162 return Result;
Tobias Grosser642c4112012-03-02 11:27:25 +0000163}
164
165int IslGenerator::mergeIslAffValues(__isl_take isl_set *Set,
166 __isl_take isl_aff *Aff, void *User) {
167 IslGenInfo *GenInfo = (IslGenInfo *)User;
168
169 assert((GenInfo->Result == NULL) && "Result is already set."
170 "Currently only single isl_aff is supported");
171 assert(isl_set_plain_is_universe(Set)
172 && "Code generation failed because the set is not universe");
173
174 GenInfo->Result = GenInfo->Generator->generateIslAff(Aff);
175
176 isl_set_free(Set);
177 return 0;
178}
179
180Value *IslGenerator::generateIslPwAff(__isl_take isl_pw_aff *PwAff) {
181 IslGenInfo User;
182 User.Result = NULL;
183 User.Generator = this;
184 isl_pw_aff_foreach_piece(PwAff, mergeIslAffValues, &User);
185 assert(User.Result && "Code generation for isl_pw_aff failed");
186
187 isl_pw_aff_free(PwAff);
188 return User.Result;
189}
190
Tobias Grosser55d52082012-03-02 15:20:39 +0000191/// @brief Generate a new basic block for a polyhedral statement.
192///
193/// The only public function exposed is generate().
Tobias Grosser75805372011-04-29 06:27:02 +0000194class BlockGenerator {
Tobias Grosserc941ede2012-03-02 11:26:49 +0000195public:
Tobias Grosser55d52082012-03-02 15:20:39 +0000196 /// @brief Generate a new BasicBlock for a ScopStmt.
197 ///
198 /// @param Builder The LLVM-IR Builder used to generate the statement. The
199 /// code is generated at the location, the Builder points to.
200 /// @param Stmt The statement to code generate.
201 /// @param GlobalMap A map that defines for certain Values referenced from the
202 /// original code new Values they should be replaced with.
203 /// @param P A reference to the pass this function is called from.
204 /// The pass is needed to update other analysis.
205 static void generate(IRBuilder<> &Builder, ScopStmt &Stmt,
206 ValueMapT &GlobalMap, Pass *P) {
207 BlockGenerator Generator(Builder, Stmt, P);
208 Generator.copyBB(GlobalMap);
Tobias Grosserc941ede2012-03-02 11:26:49 +0000209 }
210
Tobias Grosser80998e72012-03-02 11:27:28 +0000211protected:
Tobias Grosser75805372011-04-29 06:27:02 +0000212 IRBuilder<> &Builder;
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000213 ScopStmt &Statement;
Tobias Grosser8412cda2012-03-02 11:26:55 +0000214 Pass *P;
Tobias Grosser75805372011-04-29 06:27:02 +0000215
Tobias Grosser55d52082012-03-02 15:20:39 +0000216 BlockGenerator(IRBuilder<> &B, ScopStmt &Stmt, Pass *P);
Tobias Grosser75805372011-04-29 06:27:02 +0000217
Tobias Grosser55d52082012-03-02 15:20:39 +0000218 /// @brief Get the new version of a Value.
219 ///
220 /// @param Old The old Value.
Tobias Grosser3c2efba2012-03-06 07:38:57 +0000221 /// @param BBMap A mapping from old values to their new values
Tobias Grosser55d52082012-03-02 15:20:39 +0000222 /// (for values recalculated within this basic block).
223 /// @param GlobalMap A mapping from old values to their new values
224 /// (for values recalculated in the new ScoP, but not
225 /// within this basic block).
226 ///
227 /// @returns o The old value, if it is still valid.
228 /// o The new value, if available.
229 /// o NULL, if no value is found.
230 Value *getNewValue(const Value *Old, ValueMapT &BBMap, ValueMapT &GlobalMap);
Tobias Grosser75805372011-04-29 06:27:02 +0000231
Tobias Grosserdf382372012-03-02 15:20:35 +0000232 void copyInstScalar(const Instruction *Inst, ValueMapT &BBMap,
233 ValueMapT &GlobalMap);
Tobias Grosser75805372011-04-29 06:27:02 +0000234
Raghesh Aloor129e8672011-08-15 02:33:39 +0000235 /// @brief Get the memory access offset to be added to the base address
Tobias Grosser80998e72012-03-02 11:27:28 +0000236 std::vector<Value*> getMemoryAccessIndex(__isl_keep isl_map *AccessRelation,
Tobias Grosserd6adda32012-03-23 08:21:22 +0000237 Value *BaseAddress, ValueMapT &BBMap,
238 ValueMapT &GlobalMap);
Raghesh Aloor129e8672011-08-15 02:33:39 +0000239
Raghesh Aloor62b13122011-08-03 17:02:50 +0000240 /// @brief Get the new operand address according to the changed access in
241 /// JSCOP file.
Raghesh Aloor46eceba2011-12-09 14:27:17 +0000242 Value *getNewAccessOperand(__isl_keep isl_map *NewAccessRelation,
Tobias Grosserd6d7d7e2012-04-01 16:55:30 +0000243 Value *BaseAddress, ValueMapT &BBMap,
244 ValueMapT &GlobalMap);
Raghesh Aloor62b13122011-08-03 17:02:50 +0000245
246 /// @brief Generate the operand address
247 Value *generateLocationAccessed(const Instruction *Inst,
Tobias Grosserdf382372012-03-02 15:20:35 +0000248 const Value *Pointer, ValueMapT &BBMap,
249 ValueMapT &GlobalMap);
Raghesh Aloor129e8672011-08-15 02:33:39 +0000250
Tobias Grosserdf382372012-03-02 15:20:35 +0000251 Value *generateScalarLoad(const LoadInst *load, ValueMapT &BBMap,
252 ValueMapT &GlobalMap);
Tobias Grosser75805372011-04-29 06:27:02 +0000253
Tobias Grosserd6adda32012-03-23 08:21:22 +0000254 Value *generateScalarStore(const StoreInst *store, ValueMapT &BBMap,
255 ValueMapT &GlobalMap);
256
Tobias Grosser55d52082012-03-02 15:20:39 +0000257 /// @brief Copy a single Instruction.
258 ///
259 /// This copies a single Instruction and updates references to old values
260 /// with references to new values, as defined by GlobalMap and BBMap.
261 ///
Tobias Grosser3c2efba2012-03-06 07:38:57 +0000262 /// @param BBMap A mapping from old values to their new values
Tobias Grosser55d52082012-03-02 15:20:39 +0000263 /// (for values recalculated within this basic block).
264 /// @param GlobalMap A mapping from old values to their new values
265 /// (for values recalculated in the new ScoP, but not
266 /// within this basic block).
267 void copyInstruction(const Instruction *Inst, ValueMapT &BBMap,
Tobias Grosserdf382372012-03-02 15:20:35 +0000268 ValueMapT &GlobalMap);
Tobias Grosser75805372011-04-29 06:27:02 +0000269
Tobias Grosser55d52082012-03-02 15:20:39 +0000270 /// @brief Copy the basic block.
271 ///
272 /// This copies the entire basic block and updates references to old values
273 /// with references to new values, as defined by GlobalMap.
274 ///
275 /// @param GlobalMap A mapping from old values to their new values
276 /// (for values recalculated in the new ScoP, but not
277 /// within this basic block).
278 void copyBB(ValueMapT &GlobalMap);
Tobias Grosser75805372011-04-29 06:27:02 +0000279};
280
Tobias Grosser55d52082012-03-02 15:20:39 +0000281BlockGenerator::BlockGenerator(IRBuilder<> &B, ScopStmt &Stmt, Pass *P):
282 Builder(B), Statement(Stmt), P(P) {}
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000283
Tobias Grosser55d52082012-03-02 15:20:39 +0000284Value *BlockGenerator::getNewValue(const Value *Old, ValueMapT &BBMap,
285 ValueMapT &GlobalMap) {
Tobias Grosser89339062012-04-01 16:49:45 +0000286 // We assume constants never change.
287 // This avoids map lookups for many calls to this function.
288 if (isa<Constant>(Old))
Tobias Grosser55d52082012-03-02 15:20:39 +0000289 return const_cast<Value*>(Old);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000290
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 Grosser55d52082012-03-02 15:20:39 +0000301 if (BBMap.count(Old)) {
302 return BBMap[Old];
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000303 }
304
Tobias Grosser89339062012-04-01 16:49:45 +0000305 // 'Old' is within the original SCoP, but was not rewritten.
306 //
307 // Such values appear, if they only calculate information already available in
308 // the polyhedral description (e.g. an induction variable increment). They
309 // can be safely ignored.
310 if (const Instruction *Inst = dyn_cast<Instruction>(Old))
311 if (Statement.getParent()->getRegion().contains(Inst->getParent()))
312 return NULL;
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000313
Tobias Grosser89339062012-04-01 16:49:45 +0000314 // Everything else is probably a scop-constant value defined as global,
315 // function parameter or an instruction not within the scop.
316 return const_cast<Value*>(Old);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000317}
318
Tobias Grosserdf382372012-03-02 15:20:35 +0000319void BlockGenerator::copyInstScalar(const Instruction *Inst, ValueMapT &BBMap,
320 ValueMapT &GlobalMap) {
Tobias Grosser80998e72012-03-02 11:27:28 +0000321 Instruction *NewInst = Inst->clone();
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000322
Tobias Grosser80998e72012-03-02 11:27:28 +0000323 // Replace old operands with the new ones.
324 for (Instruction::const_op_iterator OI = Inst->op_begin(),
325 OE = Inst->op_end(); OI != OE; ++OI) {
326 Value *OldOperand = *OI;
Tobias Grosser55d52082012-03-02 15:20:39 +0000327 Value *NewOperand = getNewValue(OldOperand, BBMap, GlobalMap);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000328
Tobias Grosser80998e72012-03-02 11:27:28 +0000329 if (!NewOperand) {
330 assert(!isa<StoreInst>(NewInst)
331 && "Store instructions are always needed!");
332 delete NewInst;
333 return;
334 }
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000335
Tobias Grosser80998e72012-03-02 11:27:28 +0000336 NewInst->replaceUsesOfWith(OldOperand, NewOperand);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000337 }
338
Tobias Grosser80998e72012-03-02 11:27:28 +0000339 Builder.Insert(NewInst);
340 BBMap[Inst] = NewInst;
341
342 if (!NewInst->getType()->isVoidTy())
343 NewInst->setName("p_" + Inst->getName());
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000344}
345
Tobias Grosserd6adda32012-03-23 08:21:22 +0000346std::vector<Value*> BlockGenerator::getMemoryAccessIndex(
347 __isl_keep isl_map *AccessRelation, Value *BaseAddress,
348 ValueMapT &BBMap, ValueMapT &GlobalMap) {
349
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000350 assert((isl_map_dim(AccessRelation, isl_dim_out) == 1)
351 && "Only single dimensional access functions supported");
352
Tobias Grosserd6adda32012-03-23 08:21:22 +0000353 std::vector<Value *> IVS;
354 for (unsigned i = 0; i < Statement.getNumIterators(); ++i) {
355 const Value *OriginalIV = Statement.getInductionVariableForDimension(i);
356 Value *NewIV = getNewValue(OriginalIV, BBMap, GlobalMap);
357 IVS.push_back(NewIV);
358 }
359
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000360 isl_pw_aff *PwAff = isl_map_dim_max(isl_map_copy(AccessRelation), 0);
Tobias Grosserd6adda32012-03-23 08:21:22 +0000361 IslGenerator IslGen(Builder, IVS);
Tobias Grosser642c4112012-03-02 11:27:25 +0000362 Value *OffsetValue = IslGen.generateIslPwAff(PwAff);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000363
Tobias Grosserd6adda32012-03-23 08:21:22 +0000364 Type *Ty = Builder.getInt64Ty();
365 OffsetValue = Builder.CreateIntCast(OffsetValue, Ty, true);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000366
367 std::vector<Value*> IndexArray;
Tobias Grosserd6adda32012-03-23 08:21:22 +0000368 Value *NullValue = Constant::getNullValue(Ty);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000369 IndexArray.push_back(NullValue);
370 IndexArray.push_back(OffsetValue);
371 return IndexArray;
372}
373
374Value *BlockGenerator::getNewAccessOperand(
Tobias Grosserd6d7d7e2012-04-01 16:55:30 +0000375 __isl_keep isl_map *NewAccessRelation, Value *BaseAddress,
376 ValueMapT &BBMap, ValueMapT &GlobalMap) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000377 std::vector<Value*> IndexArray = getMemoryAccessIndex(NewAccessRelation,
Tobias Grosserd6adda32012-03-23 08:21:22 +0000378 BaseAddress,
379 BBMap, GlobalMap);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000380 Value *NewOperand = Builder.CreateGEP(BaseAddress, IndexArray,
381 "p_newarrayidx_");
382 return NewOperand;
383}
384
385Value *BlockGenerator::generateLocationAccessed(const Instruction *Inst,
386 const Value *Pointer,
Tobias Grosserdf382372012-03-02 15:20:35 +0000387 ValueMapT &BBMap,
388 ValueMapT &GlobalMap) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000389 MemoryAccess &Access = Statement.getAccessFor(Inst);
390 isl_map *CurrentAccessRelation = Access.getAccessRelation();
391 isl_map *NewAccessRelation = Access.getNewAccessRelation();
392
393 assert(isl_map_has_equal_space(CurrentAccessRelation, NewAccessRelation)
394 && "Current and new access function use different spaces");
395
396 Value *NewPointer;
397
398 if (!NewAccessRelation) {
Tobias Grosser55d52082012-03-02 15:20:39 +0000399 NewPointer = getNewValue(Pointer, BBMap, GlobalMap);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000400 } else {
401 Value *BaseAddress = const_cast<Value*>(Access.getBaseAddr());
Tobias Grosserd6d7d7e2012-04-01 16:55:30 +0000402 NewPointer = getNewAccessOperand(NewAccessRelation, BaseAddress,
Tobias Grosserd6adda32012-03-23 08:21:22 +0000403 BBMap, GlobalMap);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000404 }
405
406 isl_map_free(CurrentAccessRelation);
407 isl_map_free(NewAccessRelation);
408 return NewPointer;
409}
410
411Value *BlockGenerator::generateScalarLoad(const LoadInst *Load,
Tobias Grosserdf382372012-03-02 15:20:35 +0000412 ValueMapT &BBMap,
413 ValueMapT &GlobalMap) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000414 const Value *Pointer = Load->getPointerOperand();
415 const Instruction *Inst = dyn_cast<Instruction>(Load);
Tobias Grosserdf382372012-03-02 15:20:35 +0000416 Value *NewPointer = generateLocationAccessed(Inst, Pointer, BBMap, GlobalMap);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000417 Value *ScalarLoad = Builder.CreateLoad(NewPointer,
418 Load->getName() + "_p_scalar_");
419 return ScalarLoad;
420}
421
Tobias Grosserd6adda32012-03-23 08:21:22 +0000422Value *BlockGenerator::generateScalarStore(const StoreInst *Store,
423 ValueMapT &BBMap,
424 ValueMapT &GlobalMap) {
425 const Value *Pointer = Store->getPointerOperand();
426 Value *NewPointer = generateLocationAccessed(Store, Pointer, BBMap,
427 GlobalMap);
428 Value *ValueOperand = getNewValue(Store->getValueOperand(), BBMap, GlobalMap);
429
430 return Builder.CreateStore(ValueOperand, NewPointer);
431}
432
Tobias Grosser80998e72012-03-02 11:27:28 +0000433void BlockGenerator::copyInstruction(const Instruction *Inst,
Tobias Grosserdf382372012-03-02 15:20:35 +0000434 ValueMapT &BBMap, ValueMapT &GlobalMap) {
Tobias Grosser80998e72012-03-02 11:27:28 +0000435 // Terminator instructions control the control flow. They are explicitly
436 // expressed in the clast and do not need to be copied.
437 if (Inst->isTerminator())
438 return;
439
440 if (const LoadInst *Load = dyn_cast<LoadInst>(Inst)) {
Tobias Grosserdf382372012-03-02 15:20:35 +0000441 BBMap[Load] = generateScalarLoad(Load, BBMap, GlobalMap);
Tobias Grosser80998e72012-03-02 11:27:28 +0000442 return;
443 }
444
Tobias Grosserd6adda32012-03-23 08:21:22 +0000445 if (const StoreInst *Store = dyn_cast<StoreInst>(Inst)) {
446 BBMap[Store] = generateScalarStore(Store, BBMap, GlobalMap);
447 return;
448 }
449
Tobias Grosserdf382372012-03-02 15:20:35 +0000450 copyInstScalar(Inst, BBMap, GlobalMap);
Tobias Grosser80998e72012-03-02 11:27:28 +0000451}
452
453
Tobias Grosser55d52082012-03-02 15:20:39 +0000454void BlockGenerator::copyBB(ValueMapT &GlobalMap) {
Tobias Grosser80998e72012-03-02 11:27:28 +0000455 BasicBlock *BB = Statement.getBasicBlock();
456 BasicBlock *CopyBB = SplitBlock(Builder.GetInsertBlock(),
457 Builder.GetInsertPoint(), P);
458 CopyBB->setName("polly.stmt." + BB->getName());
459 Builder.SetInsertPoint(CopyBB->begin());
460
Tobias Grosserdf382372012-03-02 15:20:35 +0000461 ValueMapT BBMap;
Tobias Grosser80998e72012-03-02 11:27:28 +0000462
463 for (BasicBlock::const_iterator II = BB->begin(), IE = BB->end(); II != IE;
464 ++II)
Tobias Grosserdf382372012-03-02 15:20:35 +0000465 copyInstruction(II, BBMap, GlobalMap);
Tobias Grosser80998e72012-03-02 11:27:28 +0000466}
467
Tobias Grosser55d52082012-03-02 15:20:39 +0000468/// @brief Generate a new vector basic block for a polyhedral statement.
469///
470/// The only public function exposed is generate().
Tobias Grosser80998e72012-03-02 11:27:28 +0000471class VectorBlockGenerator : BlockGenerator {
472public:
Tobias Grosser55d52082012-03-02 15:20:39 +0000473 /// @brief Generate a new vector basic block for a ScoPStmt.
474 ///
475 /// This code generation is similar to the normal, scalar code generation,
476 /// except that each instruction is code generated for several vector lanes
477 /// at a time. If possible instructions are issued as actual vector
478 /// instructions, but e.g. for address calculation instructions we currently
479 /// generate scalar instructions for each vector lane.
480 ///
481 /// @param Builder The LLVM-IR Builder used to generate the statement. The
482 /// code is generated at the location, the builder points
483 /// to.
484 /// @param Stmt The statement to code generate.
485 /// @param GlobalMaps A vector of maps that define for certain Values
486 /// referenced from the original code new Values they should
487 /// be replaced with. Each map in the vector of maps is
488 /// used for one vector lane. The number of elements in the
489 /// vector defines the width of the generated vector
490 /// instructions.
491 /// @param P A reference to the pass this function is called from.
492 /// The pass is needed to update other analysis.
493 static void generate(IRBuilder<> &B, ScopStmt &Stmt,
494 VectorValueMapT &GlobalMaps, __isl_keep isl_set *Domain,
495 Pass *P) {
496 VectorBlockGenerator Generator(B, GlobalMaps, Stmt, Domain, P);
Tobias Grosser80998e72012-03-02 11:27:28 +0000497 Generator.copyBB();
498 }
499
500private:
Tobias Grosser55d52082012-03-02 15:20:39 +0000501 // This is a vector of global value maps. The first map is used for the first
502 // vector lane, ...
503 // Each map, contains information about Instructions in the old ScoP, which
504 // are recalculated in the new SCoP. When copying the basic block, we replace
505 // all referenes to the old instructions with their recalculated values.
Tobias Grosserdf382372012-03-02 15:20:35 +0000506 VectorValueMapT &GlobalMaps;
Tobias Grosser80998e72012-03-02 11:27:28 +0000507
Tobias Grosser08a82382012-03-02 15:20:24 +0000508 isl_set *Domain;
509
Tobias Grosser55d52082012-03-02 15:20:39 +0000510 VectorBlockGenerator(IRBuilder<> &B, VectorValueMapT &GlobalMaps,
511 ScopStmt &Stmt, __isl_keep isl_set *Domain, Pass *P);
Tobias Grosser80998e72012-03-02 11:27:28 +0000512
513 int getVectorWidth();
514
Tobias Grosser55d52082012-03-02 15:20:39 +0000515 Value *getVectorValue(const Value *Old, ValueMapT &VectorMap,
516 VectorValueMapT &ScalarMaps);
Tobias Grosser80998e72012-03-02 11:27:28 +0000517
518 Type *getVectorPtrTy(const Value *V, int Width);
519
520 /// @brief Load a vector from a set of adjacent scalars
521 ///
522 /// In case a set of scalars is known to be next to each other in memory,
523 /// create a vector load that loads those scalars
524 ///
525 /// %vector_ptr= bitcast double* %p to <4 x double>*
526 /// %vec_full = load <4 x double>* %vector_ptr
527 ///
528 Value *generateStrideOneLoad(const LoadInst *Load, ValueMapT &BBMap);
529
530 /// @brief Load a vector initialized from a single scalar in memory
531 ///
532 /// In case all elements of a vector are initialized to the same
533 /// scalar value, this value is loaded and shuffeled into all elements
534 /// of the vector.
535 ///
536 /// %splat_one = load <1 x double>* %p
537 /// %splat = shufflevector <1 x double> %splat_one, <1 x
538 /// double> %splat_one, <4 x i32> zeroinitializer
539 ///
540 Value *generateStrideZeroLoad(const LoadInst *Load, ValueMapT &BBMap);
541
542 /// @Load a vector from scalars distributed in memory
543 ///
544 /// In case some scalars a distributed randomly in memory. Create a vector
545 /// by loading each scalar and by inserting one after the other into the
546 /// vector.
547 ///
548 /// %scalar_1= load double* %p_1
549 /// %vec_1 = insertelement <2 x double> undef, double %scalar_1, i32 0
550 /// %scalar 2 = load double* %p_2
551 /// %vec_2 = insertelement <2 x double> %vec_1, double %scalar_1, i32 1
552 ///
553 Value *generateUnknownStrideLoad(const LoadInst *Load,
554 VectorValueMapT &ScalarMaps);
555
Tobias Grosser80998e72012-03-02 11:27:28 +0000556 void generateLoad(const LoadInst *Load, ValueMapT &VectorMap,
557 VectorValueMapT &ScalarMaps);
558
Tobias Grosserdf382372012-03-02 15:20:35 +0000559 void copyUnaryInst(const UnaryInstruction *Inst, ValueMapT &VectorMap,
560 VectorValueMapT &ScalarMaps);
Tobias Grosser80998e72012-03-02 11:27:28 +0000561
Tobias Grosserdf382372012-03-02 15:20:35 +0000562 void copyBinaryInst(const BinaryOperator *Inst, ValueMapT &VectorMap,
563 VectorValueMapT &ScalarMaps);
Tobias Grosser80998e72012-03-02 11:27:28 +0000564
Tobias Grosserdf382372012-03-02 15:20:35 +0000565 void copyStore(const StoreInst *Store, ValueMapT &VectorMap,
Tobias Grosser260e86d2012-03-02 15:20:28 +0000566 VectorValueMapT &ScalarMaps);
Tobias Grosser80998e72012-03-02 11:27:28 +0000567
568 bool hasVectorOperands(const Instruction *Inst, ValueMapT &VectorMap);
569
570 void copyInstruction(const Instruction *Inst, ValueMapT &VectorMap,
571 VectorValueMapT &ScalarMaps);
572
Tobias Grosser80998e72012-03-02 11:27:28 +0000573 void copyBB();
574};
575
Tobias Grosser55d52082012-03-02 15:20:39 +0000576VectorBlockGenerator::VectorBlockGenerator(IRBuilder<> &B,
577 VectorValueMapT &GlobalMaps, ScopStmt &Stmt, __isl_keep isl_set *Domain,
578 Pass *P) : BlockGenerator(B, Stmt, P), GlobalMaps(GlobalMaps),
579 Domain(Domain) {
Tobias Grosserdf382372012-03-02 15:20:35 +0000580 assert(GlobalMaps.size() > 1 && "Only one vector lane found");
Tobias Grosser08a82382012-03-02 15:20:24 +0000581 assert(Domain && "No statement domain provided");
Tobias Grosser80998e72012-03-02 11:27:28 +0000582 }
583
Tobias Grosser55d52082012-03-02 15:20:39 +0000584Value *VectorBlockGenerator::getVectorValue(const Value *Old,
585 ValueMapT &VectorMap,
586 VectorValueMapT &ScalarMaps) {
587 if (VectorMap.count(Old))
588 return VectorMap[Old];
Tobias Grosser80998e72012-03-02 11:27:28 +0000589
Tobias Grosserdf382372012-03-02 15:20:35 +0000590 int Width = getVectorWidth();
Tobias Grosser80998e72012-03-02 11:27:28 +0000591
Tobias Grosser55d52082012-03-02 15:20:39 +0000592 Value *Vector = UndefValue::get(VectorType::get(Old->getType(), Width));
Tobias Grosser80998e72012-03-02 11:27:28 +0000593
Tobias Grosserdf382372012-03-02 15:20:35 +0000594 for (int Lane = 0; Lane < Width; Lane++)
595 Vector = Builder.CreateInsertElement(Vector,
Tobias Grosser55d52082012-03-02 15:20:39 +0000596 getNewValue(Old,
597 ScalarMaps[Lane],
598 GlobalMaps[Lane]),
Tobias Grosserdf382372012-03-02 15:20:35 +0000599 Builder.getInt32(Lane));
Tobias Grosser80998e72012-03-02 11:27:28 +0000600
Tobias Grosser55d52082012-03-02 15:20:39 +0000601 VectorMap[Old] = Vector;
Tobias Grosserdf382372012-03-02 15:20:35 +0000602
603 return Vector;
Tobias Grosser80998e72012-03-02 11:27:28 +0000604}
605
606Type *VectorBlockGenerator::getVectorPtrTy(const Value *Val, int Width) {
607 PointerType *PointerTy = dyn_cast<PointerType>(Val->getType());
608 assert(PointerTy && "PointerType expected");
609
610 Type *ScalarType = PointerTy->getElementType();
611 VectorType *VectorType = VectorType::get(ScalarType, Width);
612
613 return PointerType::getUnqual(VectorType);
614}
615
616Value *VectorBlockGenerator::generateStrideOneLoad(const LoadInst *Load,
617 ValueMapT &BBMap) {
618 const Value *Pointer = Load->getPointerOperand();
619 Type *VectorPtrType = getVectorPtrTy(Pointer, getVectorWidth());
Tobias Grosser55d52082012-03-02 15:20:39 +0000620 Value *NewPointer = getNewValue(Pointer, BBMap, GlobalMaps[0]);
Tobias Grosser80998e72012-03-02 11:27:28 +0000621 Value *VectorPtr = Builder.CreateBitCast(NewPointer, VectorPtrType,
622 "vector_ptr");
623 LoadInst *VecLoad = Builder.CreateLoad(VectorPtr,
624 Load->getName() + "_p_vec_full");
625 if (!Aligned)
626 VecLoad->setAlignment(8);
627
628 return VecLoad;
629}
630
631Value *VectorBlockGenerator::generateStrideZeroLoad(const LoadInst *Load,
632 ValueMapT &BBMap) {
633 const Value *Pointer = Load->getPointerOperand();
634 Type *VectorPtrType = getVectorPtrTy(Pointer, 1);
Tobias Grosser55d52082012-03-02 15:20:39 +0000635 Value *NewPointer = getNewValue(Pointer, BBMap, GlobalMaps[0]);
Tobias Grosser80998e72012-03-02 11:27:28 +0000636 Value *VectorPtr = Builder.CreateBitCast(NewPointer, VectorPtrType,
637 Load->getName() + "_p_vec_p");
638 LoadInst *ScalarLoad= Builder.CreateLoad(VectorPtr,
639 Load->getName() + "_p_splat_one");
640
641 if (!Aligned)
642 ScalarLoad->setAlignment(8);
643
644 Constant *SplatVector =
645 Constant::getNullValue(VectorType::get(Builder.getInt32Ty(),
646 getVectorWidth()));
647
648 Value *VectorLoad = Builder.CreateShuffleVector(ScalarLoad, ScalarLoad,
649 SplatVector,
650 Load->getName()
651 + "_p_splat");
652 return VectorLoad;
653}
654
655Value *VectorBlockGenerator::generateUnknownStrideLoad(const LoadInst *Load,
656 VectorValueMapT &ScalarMaps) {
657 int VectorWidth = getVectorWidth();
658 const Value *Pointer = Load->getPointerOperand();
659 VectorType *VectorType = VectorType::get(
660 dyn_cast<PointerType>(Pointer->getType())->getElementType(), VectorWidth);
661
662 Value *Vector = UndefValue::get(VectorType);
663
664 for (int i = 0; i < VectorWidth; i++) {
Tobias Grosser55d52082012-03-02 15:20:39 +0000665 Value *NewPointer = getNewValue(Pointer, ScalarMaps[i], GlobalMaps[i]);
Tobias Grosser80998e72012-03-02 11:27:28 +0000666 Value *ScalarLoad = Builder.CreateLoad(NewPointer,
667 Load->getName() + "_p_scalar_");
668 Vector = Builder.CreateInsertElement(Vector, ScalarLoad,
669 Builder.getInt32(i),
670 Load->getName() + "_p_vec_");
671 }
672
673 return Vector;
674}
675
676void VectorBlockGenerator::generateLoad(const LoadInst *Load,
677 ValueMapT &VectorMap,
678 VectorValueMapT &ScalarMaps) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000679 Value *NewLoad;
680
681 MemoryAccess &Access = Statement.getAccessFor(Load);
682
Tobias Grosser08a82382012-03-02 15:20:24 +0000683 if (Access.isStrideZero(isl_set_copy(Domain)))
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000684 NewLoad = generateStrideZeroLoad(Load, ScalarMaps[0]);
Tobias Grosser08a82382012-03-02 15:20:24 +0000685 else if (Access.isStrideOne(isl_set_copy(Domain)))
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000686 NewLoad = generateStrideOneLoad(Load, ScalarMaps[0]);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000687 else
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000688 NewLoad = generateUnknownStrideLoad(Load, ScalarMaps);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000689
690 VectorMap[Load] = NewLoad;
691}
692
Tobias Grosser80998e72012-03-02 11:27:28 +0000693void VectorBlockGenerator::copyUnaryInst(const UnaryInstruction *Inst,
Tobias Grosserdf382372012-03-02 15:20:35 +0000694 ValueMapT &VectorMap,
695 VectorValueMapT &ScalarMaps) {
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000696 int VectorWidth = getVectorWidth();
Tobias Grosser55d52082012-03-02 15:20:39 +0000697 Value *NewOperand = getVectorValue(Inst->getOperand(0), VectorMap,
698 ScalarMaps);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000699
700 assert(isa<CastInst>(Inst) && "Can not generate vector code for instruction");
701
702 const CastInst *Cast = dyn_cast<CastInst>(Inst);
703 VectorType *DestType = VectorType::get(Inst->getType(), VectorWidth);
704 VectorMap[Inst] = Builder.CreateCast(Cast->getOpcode(), NewOperand, DestType);
705}
706
Tobias Grosser80998e72012-03-02 11:27:28 +0000707void VectorBlockGenerator::copyBinaryInst(const BinaryOperator *Inst,
Tobias Grosserdf382372012-03-02 15:20:35 +0000708 ValueMapT &VectorMap,
709 VectorValueMapT &ScalarMaps) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000710 Value *OpZero = Inst->getOperand(0);
711 Value *OpOne = Inst->getOperand(1);
712
713 Value *NewOpZero, *NewOpOne;
Tobias Grosser55d52082012-03-02 15:20:39 +0000714 NewOpZero = getVectorValue(OpZero, VectorMap, ScalarMaps);
715 NewOpOne = getVectorValue(OpOne, VectorMap, ScalarMaps);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000716
717 Value *NewInst = Builder.CreateBinOp(Inst->getOpcode(), NewOpZero,
718 NewOpOne,
719 Inst->getName() + "p_vec");
720 VectorMap[Inst] = NewInst;
721}
722
Tobias Grosserdf382372012-03-02 15:20:35 +0000723void VectorBlockGenerator::copyStore(const StoreInst *Store,
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000724 ValueMapT &VectorMap,
Tobias Grosser8927a442012-03-02 11:27:05 +0000725 VectorValueMapT &ScalarMaps) {
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000726 int VectorWidth = getVectorWidth();
727
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000728 MemoryAccess &Access = Statement.getAccessFor(Store);
729
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000730 const Value *Pointer = Store->getPointerOperand();
Tobias Grosser55d52082012-03-02 15:20:39 +0000731 Value *Vector = getVectorValue(Store->getValueOperand(), VectorMap,
Tobias Grosserdf382372012-03-02 15:20:35 +0000732 ScalarMaps);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000733
Tobias Grosser08a82382012-03-02 15:20:24 +0000734 if (Access.isStrideOne(isl_set_copy(Domain))) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000735 Type *VectorPtrType = getVectorPtrTy(Pointer, VectorWidth);
Tobias Grosser55d52082012-03-02 15:20:39 +0000736 Value *NewPointer = getNewValue(Pointer, ScalarMaps[0], GlobalMaps[0]);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000737
738 Value *VectorPtr = Builder.CreateBitCast(NewPointer, VectorPtrType,
739 "vector_ptr");
740 StoreInst *Store = Builder.CreateStore(Vector, VectorPtr);
741
742 if (!Aligned)
743 Store->setAlignment(8);
744 } else {
745 for (unsigned i = 0; i < ScalarMaps.size(); i++) {
746 Value *Scalar = Builder.CreateExtractElement(Vector,
747 Builder.getInt32(i));
Tobias Grosser55d52082012-03-02 15:20:39 +0000748 Value *NewPointer = getNewValue(Pointer, ScalarMaps[i], GlobalMaps[i]);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000749 Builder.CreateStore(Scalar, NewPointer);
750 }
751 }
752}
753
Tobias Grosser80998e72012-03-02 11:27:28 +0000754bool VectorBlockGenerator::hasVectorOperands(const Instruction *Inst,
755 ValueMapT &VectorMap) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000756 for (Instruction::const_op_iterator OI = Inst->op_begin(),
757 OE = Inst->op_end(); OI != OE; ++OI)
758 if (VectorMap.count(*OI))
759 return true;
760 return false;
761}
762
Tobias Grosser80998e72012-03-02 11:27:28 +0000763int VectorBlockGenerator::getVectorWidth() {
Tobias Grosserdf382372012-03-02 15:20:35 +0000764 return GlobalMaps.size();
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000765}
766
Tobias Grosser80998e72012-03-02 11:27:28 +0000767void VectorBlockGenerator::copyInstruction(const Instruction *Inst,
Tobias Grosser32152cb2012-03-02 11:27:18 +0000768 ValueMapT &VectorMap,
769 VectorValueMapT &ScalarMaps) {
Tobias Grosser80998e72012-03-02 11:27:28 +0000770 // Terminator instructions control the control flow. They are explicitly
771 // expressed in the clast and do not need to be copied.
772 if (Inst->isTerminator())
773 return;
774
Tobias Grosser32152cb2012-03-02 11:27:18 +0000775 if (const LoadInst *Load = dyn_cast<LoadInst>(Inst)) {
Tobias Grosser80998e72012-03-02 11:27:28 +0000776 generateLoad(Load, VectorMap, ScalarMaps);
Tobias Grosser32152cb2012-03-02 11:27:18 +0000777 return;
778 }
779
780 if (hasVectorOperands(Inst, VectorMap)) {
781 if (const StoreInst *Store = dyn_cast<StoreInst>(Inst)) {
Tobias Grosserdf382372012-03-02 15:20:35 +0000782 copyStore(Store, VectorMap, ScalarMaps);
Tobias Grosser32152cb2012-03-02 11:27:18 +0000783 return;
784 }
785
786 if (const UnaryInstruction *Unary = dyn_cast<UnaryInstruction>(Inst)) {
Tobias Grosserdf382372012-03-02 15:20:35 +0000787 copyUnaryInst(Unary, VectorMap, ScalarMaps);
Tobias Grosser32152cb2012-03-02 11:27:18 +0000788 return;
789 }
790
791 if (const BinaryOperator *Binary = dyn_cast<BinaryOperator>(Inst)) {
Tobias Grosserdf382372012-03-02 15:20:35 +0000792 copyBinaryInst(Binary, VectorMap, ScalarMaps);
Tobias Grosser32152cb2012-03-02 11:27:18 +0000793 return;
794 }
795
796 llvm_unreachable("Cannot issue vector code for this instruction");
797 }
798
799 for (int VectorLane = 0; VectorLane < getVectorWidth(); VectorLane++)
Tobias Grosserdf382372012-03-02 15:20:35 +0000800 copyInstScalar(Inst, ScalarMaps[VectorLane], GlobalMaps[VectorLane]);
Tobias Grosser32152cb2012-03-02 11:27:18 +0000801}
802
Tobias Grosser80998e72012-03-02 11:27:28 +0000803void VectorBlockGenerator::copyBB() {
Tobias Grosser14bcbd52012-03-02 11:26:52 +0000804 BasicBlock *BB = Statement.getBasicBlock();
Tobias Grosser0ac92142012-02-14 14:02:27 +0000805 BasicBlock *CopyBB = SplitBlock(Builder.GetInsertBlock(),
806 Builder.GetInsertPoint(), P);
Tobias Grosserb61e6312012-02-15 09:58:46 +0000807 CopyBB->setName("polly.stmt." + BB->getName());
Tobias Grosser0ac92142012-02-14 14:02:27 +0000808 Builder.SetInsertPoint(CopyBB->begin());
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000809
810 // Create two maps that store the mapping from the original instructions of
811 // the old basic block to their copies in the new basic block. Those maps
812 // are basic block local.
813 //
814 // As vector code generation is supported there is one map for scalar values
815 // and one for vector values.
816 //
817 // In case we just do scalar code generation, the vectorMap is not used and
818 // the scalarMap has just one dimension, which contains the mapping.
819 //
820 // In case vector code generation is done, an instruction may either appear
821 // in the vector map once (as it is calculating >vectorwidth< values at a
822 // time. Or (if the values are calculated using scalar operations), it
823 // appears once in every dimension of the scalarMap.
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000824 VectorValueMapT ScalarBlockMap(getVectorWidth());
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000825 ValueMapT VectorBlockMap;
826
827 for (BasicBlock::const_iterator II = BB->begin(), IE = BB->end();
828 II != IE; ++II)
Tobias Grosserfc1153f2012-03-02 11:27:15 +0000829 copyInstruction(II, VectorBlockMap, ScalarBlockMap);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000830}
831
Tobias Grosser75805372011-04-29 06:27:02 +0000832/// Class to generate LLVM-IR that calculates the value of a clast_expr.
833class ClastExpCodeGen {
834 IRBuilder<> &Builder;
Tobias Grosser5e8ffa82012-03-23 12:20:36 +0000835 const CharMapT &IVS;
Tobias Grosser75805372011-04-29 06:27:02 +0000836
Tobias Grosserbb137e32012-01-24 16:42:28 +0000837 Value *codegen(const clast_name *e, Type *Ty);
838 Value *codegen(const clast_term *e, Type *Ty);
839 Value *codegen(const clast_binary *e, Type *Ty);
840 Value *codegen(const clast_reduction *r, Type *Ty);
Tobias Grosser75805372011-04-29 06:27:02 +0000841public:
842
843 // A generator for clast expressions.
844 //
845 // @param B The IRBuilder that defines where the code to calculate the
846 // clast expressions should be inserted.
847 // @param IVMAP A Map that translates strings describing the induction
848 // variables to the Values* that represent these variables
849 // on the LLVM side.
Tobias Grosser5e8ffa82012-03-23 12:20:36 +0000850 ClastExpCodeGen(IRBuilder<> &B, CharMapT &IVMap);
Tobias Grosser75805372011-04-29 06:27:02 +0000851
852 // Generates code to calculate a given clast expression.
853 //
854 // @param e The expression to calculate.
855 // @return The Value that holds the result.
Tobias Grosserbb137e32012-01-24 16:42:28 +0000856 Value *codegen(const clast_expr *e, Type *Ty);
Tobias Grosserbb137e32012-01-24 16:42:28 +0000857};
858
859Value *ClastExpCodeGen::codegen(const clast_name *e, Type *Ty) {
Tobias Grosser5e8ffa82012-03-23 12:20:36 +0000860 CharMapT::const_iterator I = IVS.find(e->name);
Tobias Grosserbb137e32012-01-24 16:42:28 +0000861
Tobias Grosser5e8ffa82012-03-23 12:20:36 +0000862 assert(I != IVS.end() && "Clast name not found");
Tobias Grosserbb137e32012-01-24 16:42:28 +0000863
864 return Builder.CreateSExtOrBitCast(I->second, Ty);
865}
866
867Value *ClastExpCodeGen::codegen(const clast_term *e, Type *Ty) {
868 APInt a = APInt_from_MPZ(e->val);
869
870 Value *ConstOne = ConstantInt::get(Builder.getContext(), a);
871 ConstOne = Builder.CreateSExtOrBitCast(ConstOne, Ty);
872
873 if (!e->var)
874 return ConstOne;
875
876 Value *var = codegen(e->var, Ty);
877 return Builder.CreateMul(ConstOne, var);
878}
879
880Value *ClastExpCodeGen::codegen(const clast_binary *e, Type *Ty) {
881 Value *LHS = codegen(e->LHS, Ty);
882
883 APInt RHS_AP = APInt_from_MPZ(e->RHS);
884
885 Value *RHS = ConstantInt::get(Builder.getContext(), RHS_AP);
886 RHS = Builder.CreateSExtOrBitCast(RHS, Ty);
887
888 switch (e->type) {
889 case clast_bin_mod:
890 return Builder.CreateSRem(LHS, RHS);
891 case clast_bin_fdiv:
892 {
Tobias Grosser9a44b972012-02-16 14:13:19 +0000893 // floord(n,d) ((n < 0) ? (n - d + 1) : n) / d
Tobias Grosser906eafe2012-02-16 09:56:10 +0000894 Value *One = ConstantInt::get(Ty, 1);
895 Value *Zero = ConstantInt::get(Ty, 0);
Tobias Grosser9a44b972012-02-16 14:13:19 +0000896 Value *Sum1 = Builder.CreateSub(LHS, RHS);
897 Value *Sum2 = Builder.CreateAdd(Sum1, One);
898 Value *isNegative = Builder.CreateICmpSLT(LHS, Zero);
899 Value *Dividend = Builder.CreateSelect(isNegative, Sum2, LHS);
900 return Builder.CreateSDiv(Dividend, RHS);
Tobias Grosserbb137e32012-01-24 16:42:28 +0000901 }
902 case clast_bin_cdiv:
903 {
Tobias Grosser9a44b972012-02-16 14:13:19 +0000904 // ceild(n,d) ((n < 0) ? n : (n + d - 1)) / d
905 Value *One = ConstantInt::get(Ty, 1);
Tobias Grosser906eafe2012-02-16 09:56:10 +0000906 Value *Zero = ConstantInt::get(Ty, 0);
Tobias Grosser9a44b972012-02-16 14:13:19 +0000907 Value *Sum1 = Builder.CreateAdd(LHS, RHS);
908 Value *Sum2 = Builder.CreateSub(Sum1, One);
909 Value *isNegative = Builder.CreateICmpSLT(LHS, Zero);
910 Value *Dividend = Builder.CreateSelect(isNegative, LHS, Sum2);
911 return Builder.CreateSDiv(Dividend, RHS);
Tobias Grosserbb137e32012-01-24 16:42:28 +0000912 }
913 case clast_bin_div:
914 return Builder.CreateSDiv(LHS, RHS);
915 };
916
917 llvm_unreachable("Unknown clast binary expression type");
918}
919
920Value *ClastExpCodeGen::codegen(const clast_reduction *r, Type *Ty) {
921 assert(( r->type == clast_red_min
922 || r->type == clast_red_max
923 || r->type == clast_red_sum)
924 && "Clast reduction type not supported");
925 Value *old = codegen(r->elts[0], Ty);
926
927 for (int i=1; i < r->n; ++i) {
928 Value *exprValue = codegen(r->elts[i], Ty);
929
930 switch (r->type) {
931 case clast_red_min:
932 {
933 Value *cmp = Builder.CreateICmpSLT(old, exprValue);
934 old = Builder.CreateSelect(cmp, old, exprValue);
935 break;
936 }
937 case clast_red_max:
938 {
939 Value *cmp = Builder.CreateICmpSGT(old, exprValue);
940 old = Builder.CreateSelect(cmp, old, exprValue);
941 break;
942 }
943 case clast_red_sum:
944 old = Builder.CreateAdd(old, exprValue);
945 break;
Tobias Grosserbb137e32012-01-24 16:42:28 +0000946 }
Tobias Grosser75805372011-04-29 06:27:02 +0000947 }
948
Tobias Grosserbb137e32012-01-24 16:42:28 +0000949 return old;
950}
951
Tobias Grosser5e8ffa82012-03-23 12:20:36 +0000952ClastExpCodeGen::ClastExpCodeGen(IRBuilder<> &B, CharMapT &IVMap)
Tobias Grosserbb137e32012-01-24 16:42:28 +0000953 : Builder(B), IVS(IVMap) {}
954
955Value *ClastExpCodeGen::codegen(const clast_expr *e, Type *Ty) {
956 switch(e->type) {
957 case clast_expr_name:
958 return codegen((const clast_name *)e, Ty);
959 case clast_expr_term:
960 return codegen((const clast_term *)e, Ty);
961 case clast_expr_bin:
962 return codegen((const clast_binary *)e, Ty);
963 case clast_expr_red:
964 return codegen((const clast_reduction *)e, Ty);
965 }
966
967 llvm_unreachable("Unknown clast expression!");
968}
969
Tobias Grosser75805372011-04-29 06:27:02 +0000970class ClastStmtCodeGen {
Tobias Grosserf74a4cd2012-03-23 10:35:18 +0000971public:
972 const std::vector<std::string> &getParallelLoops();
973
974private:
Tobias Grosser75805372011-04-29 06:27:02 +0000975 // The Scop we code generate.
976 Scop *S;
Tobias Grosser0ac92142012-02-14 14:02:27 +0000977 Pass *P;
Tobias Grosser75805372011-04-29 06:27:02 +0000978
979 // The Builder specifies the current location to code generate at.
980 IRBuilder<> &Builder;
981
982 // Map the Values from the old code to their counterparts in the new code.
983 ValueMapT ValueMap;
984
985 // clastVars maps from the textual representation of a clast variable to its
986 // current *Value. clast variables are scheduling variables, original
987 // induction variables or parameters. They are used either in loop bounds or
988 // to define the statement instance that is executed.
989 //
990 // for (s = 0; s < n + 3; ++i)
991 // for (t = s; t < m; ++j)
992 // Stmt(i = s + 3 * m, j = t);
993 //
994 // {s,t,i,j,n,m} is the set of clast variables in this clast.
Tobias Grosser5e8ffa82012-03-23 12:20:36 +0000995 CharMapT ClastVars;
Tobias Grosser75805372011-04-29 06:27:02 +0000996
997 // Codegenerator for clast expressions.
998 ClastExpCodeGen ExpGen;
999
1000 // Do we currently generate parallel code?
1001 bool parallelCodeGeneration;
1002
1003 std::vector<std::string> parallelLoops;
1004
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001005 void codegen(const clast_assignment *a);
Tobias Grosser75805372011-04-29 06:27:02 +00001006
1007 void codegen(const clast_assignment *a, ScopStmt *Statement,
1008 unsigned Dimension, int vectorDim,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001009 std::vector<ValueMapT> *VectorVMap = 0);
Tobias Grosser75805372011-04-29 06:27:02 +00001010
1011 void codegenSubstitutions(const clast_stmt *Assignment,
1012 ScopStmt *Statement, int vectorDim = 0,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001013 std::vector<ValueMapT> *VectorVMap = 0);
Tobias Grosser75805372011-04-29 06:27:02 +00001014
1015 void codegen(const clast_user_stmt *u, std::vector<Value*> *IVS = NULL,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001016 const char *iterator = NULL, isl_set *scatteringDomain = 0);
Tobias Grosser75805372011-04-29 06:27:02 +00001017
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001018 void codegen(const clast_block *b);
Tobias Grosser75805372011-04-29 06:27:02 +00001019
1020 /// @brief Create a classical sequential loop.
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001021 void codegenForSequential(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +00001022
1023 /// @brief Create OpenMP structure values.
1024 ///
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001025 /// Create a list of values that has to be stored into the OpenMP subfuncition
Tobias Grosser75805372011-04-29 06:27:02 +00001026 /// structure.
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001027 SetVector<Value*> getOMPValues();
Tobias Grosser75805372011-04-29 06:27:02 +00001028
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001029 /// @brief Update the internal structures according to a Value Map.
1030 ///
1031 /// @param VMap A map from old to new values.
1032 /// @param Reverse If true, we assume the update should be reversed.
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001033 void updateWithValueMap(OMPGenerator::ValueToValueMapTy &VMap,
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001034 bool Reverse);
Tobias Grosser75805372011-04-29 06:27:02 +00001035
1036 /// @brief Create an OpenMP parallel for loop.
1037 ///
1038 /// This loop reflects a loop as if it would have been created by an OpenMP
1039 /// statement.
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001040 void codegenForOpenMP(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +00001041
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001042 bool isInnermostLoop(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +00001043
1044 /// @brief Get the number of loop iterations for this loop.
1045 /// @param f The clast for loop to check.
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001046 int getNumberOfIterations(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +00001047
1048 /// @brief Create vector instructions for this loop.
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001049 void codegenForVector(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +00001050
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001051 void codegen(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +00001052
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001053 Value *codegen(const clast_equation *eq);
Tobias Grosser75805372011-04-29 06:27:02 +00001054
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001055 void codegen(const clast_guard *g);
Tobias Grosser75805372011-04-29 06:27:02 +00001056
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001057 void codegen(const clast_stmt *stmt);
Tobias Grosser75805372011-04-29 06:27:02 +00001058
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001059 void addParameters(const CloogNames *names);
Tobias Grosser75805372011-04-29 06:27:02 +00001060
Tobias Grossere9ffea22012-03-15 09:34:48 +00001061 IntegerType *getIntPtrTy();
1062
Tobias Grosser75805372011-04-29 06:27:02 +00001063 public:
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001064 void codegen(const clast_root *r);
Tobias Grosser75805372011-04-29 06:27:02 +00001065
Tobias Grosserd596b372012-03-15 09:34:52 +00001066 ClastStmtCodeGen(Scop *scop, IRBuilder<> &B, Pass *P);
Tobias Grosser75805372011-04-29 06:27:02 +00001067};
1068}
1069
Tobias Grossere9ffea22012-03-15 09:34:48 +00001070IntegerType *ClastStmtCodeGen::getIntPtrTy() {
1071 return P->getAnalysis<TargetData>().getIntPtrType(Builder.getContext());
1072}
1073
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001074const std::vector<std::string> &ClastStmtCodeGen::getParallelLoops() {
1075 return parallelLoops;
1076}
1077
1078void ClastStmtCodeGen::codegen(const clast_assignment *a) {
Tobias Grossere9ffea22012-03-15 09:34:48 +00001079 Value *V= ExpGen.codegen(a->RHS, getIntPtrTy());
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001080 ClastVars[a->LHS] = V;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001081}
1082
Tobias Grosserf00bd962012-04-02 12:26:13 +00001083void ClastStmtCodeGen::codegen(const clast_assignment *A, ScopStmt *Stmt,
1084 unsigned Dim, int VectorDim,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001085 std::vector<ValueMapT> *VectorVMap) {
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001086 const PHINode *PN;
Tobias Grosserf00bd962012-04-02 12:26:13 +00001087 Value *RHS;
1088
1089 assert(!A->LHS && "Statement assignments do not have left hand side");
1090
1091 RHS = ExpGen.codegen(A->RHS, getIntPtrTy());
1092 PN = Stmt->getInductionVariableForDimension(Dim);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001093
1094 if (VectorVMap)
Tobias Grosserf00bd962012-04-02 12:26:13 +00001095 (*VectorVMap)[VectorDim][PN] = RHS;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001096
Tobias Grosserf00bd962012-04-02 12:26:13 +00001097 ValueMap[PN] = RHS;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001098}
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 Grosser5e8ffa82012-03-23 12:20:36 +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 Grosser5e8ffa82012-03-23 12:20:36 +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 Grosser5e8ffa82012-03-23 12:20:36 +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 Grosser5e8ffa82012-03-23 12:20:36 +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,
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001195 bool Reverse) {
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001196 std::set<Value*> Inserted;
1197
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001198 if (Reverse) {
1199 OMPGenerator::ValueToValueMapTy ReverseMap;
1200
1201 for (std::map<Value*, Value*>::iterator I = VMap.begin(), E = VMap.end();
1202 I != E; ++I)
1203 ReverseMap.insert(std::make_pair(I->second, I->first));
1204
1205 for (CharMapT::iterator I = ClastVars.begin(), E = ClastVars.end();
1206 I != E; I++) {
1207 ClastVars[I->first] = ReverseMap[I->second];
1208 Inserted.insert(I->second);
1209 }
1210
1211 /// FIXME: At the moment we do not reverse the update of the ValueMap.
1212 /// This is incomplet, but the failure should be obvious, such that
1213 /// we can fix this later.
1214 return;
1215 }
1216
1217 for (CharMapT::iterator I = ClastVars.begin(), E = ClastVars.end();
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001218 I != E; I++) {
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001219 ClastVars[I->first] = VMap[I->second];
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001220 Inserted.insert(I->second);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001221 }
1222
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001223 for (std::map<Value*, Value*>::iterator I = VMap.begin(), E = VMap.end();
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001224 I != E; ++I) {
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001225 if (Inserted.count(I->first))
1226 continue;
1227
1228 ValueMap[I->first] = I->second;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001229 }
1230}
1231
Tobias Grosser900893d2012-03-29 13:10:26 +00001232static void clearDomtree(Function *F, DominatorTree &DT) {
1233 DomTreeNode *N = DT.getNode(&F->getEntryBlock());
1234 std::vector<BasicBlock*> Nodes;
1235 for (po_iterator<DomTreeNode*> I = po_begin(N), E = po_end(N); I != E; ++I)
1236 Nodes.push_back(I->getBlock());
1237
1238 for (std::vector<BasicBlock*>::iterator I = Nodes.begin(), E = Nodes.end();
1239 I != E; ++I)
1240 DT.eraseNode(*I);
1241}
1242
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001243void ClastStmtCodeGen::codegenForOpenMP(const clast_for *For) {
Tobias Grosserebf30082012-03-23 12:20:32 +00001244 Value *Stride, *LB, *UB, *IV;
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001245 BasicBlock::iterator LoopBody;
1246 IntegerType *IntPtrTy = getIntPtrTy();
1247 SetVector<Value*> Values;
1248 OMPGenerator::ValueToValueMapTy VMap;
1249 OMPGenerator OMPGen(Builder, P);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001250
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001251 Stride = Builder.getInt(APInt_from_MPZ(For->stride));
1252 Stride = Builder.CreateSExtOrBitCast(Stride, IntPtrTy);
Tobias Grosserebf30082012-03-23 12:20:32 +00001253 LB = ExpGen.codegen(For->LB, IntPtrTy);
1254 UB = ExpGen.codegen(For->UB, IntPtrTy);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001255
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001256 Values = getOMPValues();
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001257
Tobias Grosserebf30082012-03-23 12:20:32 +00001258 IV = OMPGen.createParallelLoop(LB, UB, Stride, Values, VMap, &LoopBody);
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001259 BasicBlock::iterator AfterLoop = Builder.GetInsertPoint();
1260 Builder.SetInsertPoint(LoopBody);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001261
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001262 updateWithValueMap(VMap, /* reverse */ false);
1263 ClastVars[For->iterator] = IV;
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001264
1265 if (For->body)
1266 codegen(For->body);
1267
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001268 ClastVars.erase(For->iterator);
1269 updateWithValueMap(VMap, /* reverse */ true);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001270
Tobias Grosser900893d2012-03-29 13:10:26 +00001271 clearDomtree((*LoopBody).getParent()->getParent(),
1272 P->getAnalysis<DominatorTree>());
1273
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001274 Builder.SetInsertPoint(AfterLoop);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001275}
1276
1277bool ClastStmtCodeGen::isInnermostLoop(const clast_for *f) {
1278 const clast_stmt *stmt = f->body;
1279
1280 while (stmt) {
1281 if (!CLAST_STMT_IS_A(stmt, stmt_user))
1282 return false;
1283
1284 stmt = stmt->next;
1285 }
1286
1287 return true;
1288}
1289
1290int ClastStmtCodeGen::getNumberOfIterations(const clast_for *f) {
1291 isl_set *loopDomain = isl_set_copy(isl_set_from_cloog_domain(f->domain));
1292 isl_set *tmp = isl_set_copy(loopDomain);
1293
1294 // Calculate a map similar to the identity map, but with the last input
1295 // and output dimension not related.
1296 // [i0, i1, i2, i3] -> [i0, i1, i2, o0]
1297 isl_space *Space = isl_set_get_space(loopDomain);
1298 Space = isl_space_drop_outputs(Space,
1299 isl_set_dim(loopDomain, isl_dim_set) - 2, 1);
1300 Space = isl_space_map_from_set(Space);
1301 isl_map *identity = isl_map_identity(Space);
1302 identity = isl_map_add_dims(identity, isl_dim_in, 1);
1303 identity = isl_map_add_dims(identity, isl_dim_out, 1);
1304
1305 isl_map *map = isl_map_from_domain_and_range(tmp, loopDomain);
1306 map = isl_map_intersect(map, identity);
1307
1308 isl_map *lexmax = isl_map_lexmax(isl_map_copy(map));
1309 isl_map *lexmin = isl_map_lexmin(map);
1310 isl_map *sub = isl_map_sum(lexmax, isl_map_neg(lexmin));
1311
1312 isl_set *elements = isl_map_range(sub);
1313
1314 if (!isl_set_is_singleton(elements)) {
1315 isl_set_free(elements);
1316 return -1;
1317 }
1318
1319 isl_point *p = isl_set_sample_point(elements);
1320
1321 isl_int v;
1322 isl_int_init(v);
1323 isl_point_get_coordinate(p, isl_dim_set, isl_set_n_dim(loopDomain) - 1, &v);
1324 int numberIterations = isl_int_get_si(v);
1325 isl_int_clear(v);
1326 isl_point_free(p);
1327
1328 return (numberIterations) / isl_int_get_si(f->stride) + 1;
1329}
1330
Tobias Grosser2da263e2012-03-15 09:34:55 +00001331void ClastStmtCodeGen::codegenForVector(const clast_for *F) {
1332 DEBUG(dbgs() << "Vectorizing loop '" << F->iterator << "'\n";);
1333 int VectorWidth = getNumberOfIterations(F);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001334
Tobias Grosser2da263e2012-03-15 09:34:55 +00001335 Value *LB = ExpGen.codegen(F->LB, getIntPtrTy());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001336
Tobias Grosser2da263e2012-03-15 09:34:55 +00001337 APInt Stride = APInt_from_MPZ(F->stride);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001338 IntegerType *LoopIVType = dyn_cast<IntegerType>(LB->getType());
1339 Stride = Stride.zext(LoopIVType->getBitWidth());
1340 Value *StrideValue = ConstantInt::get(LoopIVType, Stride);
1341
Tobias Grosser2da263e2012-03-15 09:34:55 +00001342 std::vector<Value*> IVS(VectorWidth);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001343 IVS[0] = LB;
1344
Tobias Grosser2da263e2012-03-15 09:34:55 +00001345 for (int i = 1; i < VectorWidth; i++)
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001346 IVS[i] = Builder.CreateAdd(IVS[i-1], StrideValue, "p_vector_iv");
1347
Tobias Grosser00d898d2012-03-15 09:34:58 +00001348 isl_set *Domain = isl_set_from_cloog_domain(F->domain);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001349
1350 // Add loop iv to symbols.
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001351 ClastVars[F->iterator] = LB;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001352
Tobias Grosser2da263e2012-03-15 09:34:55 +00001353 const clast_stmt *Stmt = F->body;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001354
Tobias Grosser2da263e2012-03-15 09:34:55 +00001355 while (Stmt) {
Tobias Grosser00d898d2012-03-15 09:34:58 +00001356 codegen((const clast_user_stmt *)Stmt, &IVS, F->iterator,
1357 isl_set_copy(Domain));
Tobias Grosser2da263e2012-03-15 09:34:55 +00001358 Stmt = Stmt->next;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001359 }
1360
1361 // Loop is finished, so remove its iv from the live symbols.
Tobias Grosser00d898d2012-03-15 09:34:58 +00001362 isl_set_free(Domain);
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001363 ClastVars.erase(F->iterator);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001364}
1365
1366void ClastStmtCodeGen::codegen(const clast_for *f) {
Tobias Grosserd596b372012-03-15 09:34:52 +00001367 if ((Vector || OpenMP) && P->getAnalysis<Dependences>().isParallelFor(f)) {
Tobias Grosserce3f5372012-03-02 11:26:42 +00001368 if (Vector && isInnermostLoop(f) && (-1 != getNumberOfIterations(f))
1369 && (getNumberOfIterations(f) <= 16)) {
1370 codegenForVector(f);
1371 return;
1372 }
1373
1374 if (OpenMP && !parallelCodeGeneration) {
1375 parallelCodeGeneration = true;
1376 parallelLoops.push_back(f->iterator);
1377 codegenForOpenMP(f);
1378 parallelCodeGeneration = false;
1379 return;
1380 }
1381 }
1382
1383 codegenForSequential(f);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001384}
1385
1386Value *ClastStmtCodeGen::codegen(const clast_equation *eq) {
Tobias Grossere9ffea22012-03-15 09:34:48 +00001387 Value *LHS = ExpGen.codegen(eq->LHS, getIntPtrTy());
1388 Value *RHS = ExpGen.codegen(eq->RHS, getIntPtrTy());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001389 CmpInst::Predicate P;
1390
1391 if (eq->sign == 0)
1392 P = ICmpInst::ICMP_EQ;
1393 else if (eq->sign > 0)
1394 P = ICmpInst::ICMP_SGE;
1395 else
1396 P = ICmpInst::ICMP_SLE;
1397
1398 return Builder.CreateICmp(P, LHS, RHS);
1399}
1400
1401void ClastStmtCodeGen::codegen(const clast_guard *g) {
1402 Function *F = Builder.GetInsertBlock()->getParent();
1403 LLVMContext &Context = F->getContext();
Tobias Grosser0ac92142012-02-14 14:02:27 +00001404
1405 BasicBlock *CondBB = SplitBlock(Builder.GetInsertBlock(),
1406 Builder.GetInsertPoint(), P);
1407 CondBB->setName("polly.cond");
1408 BasicBlock *MergeBB = SplitBlock(CondBB, CondBB->begin(), P);
1409 MergeBB->setName("polly.merge");
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001410 BasicBlock *ThenBB = BasicBlock::Create(Context, "polly.then", F);
Tobias Grosser0ac92142012-02-14 14:02:27 +00001411
Tobias Grosserd596b372012-03-15 09:34:52 +00001412 DominatorTree &DT = P->getAnalysis<DominatorTree>();
1413 DT.addNewBlock(ThenBB, CondBB);
1414 DT.changeImmediateDominator(MergeBB, CondBB);
Tobias Grosser0ac92142012-02-14 14:02:27 +00001415
1416 CondBB->getTerminator()->eraseFromParent();
1417
1418 Builder.SetInsertPoint(CondBB);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001419
1420 Value *Predicate = codegen(&(g->eq[0]));
1421
1422 for (int i = 1; i < g->n; ++i) {
1423 Value *TmpPredicate = codegen(&(g->eq[i]));
1424 Predicate = Builder.CreateAnd(Predicate, TmpPredicate);
1425 }
1426
1427 Builder.CreateCondBr(Predicate, ThenBB, MergeBB);
1428 Builder.SetInsertPoint(ThenBB);
Tobias Grosser0ac92142012-02-14 14:02:27 +00001429 Builder.CreateBr(MergeBB);
1430 Builder.SetInsertPoint(ThenBB->begin());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001431
1432 codegen(g->then);
Tobias Grosser62a3c962012-02-16 09:56:21 +00001433
1434 Builder.SetInsertPoint(MergeBB->begin());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001435}
1436
1437void ClastStmtCodeGen::codegen(const clast_stmt *stmt) {
1438 if (CLAST_STMT_IS_A(stmt, stmt_root))
1439 assert(false && "No second root statement expected");
1440 else if (CLAST_STMT_IS_A(stmt, stmt_ass))
1441 codegen((const clast_assignment *)stmt);
1442 else if (CLAST_STMT_IS_A(stmt, stmt_user))
1443 codegen((const clast_user_stmt *)stmt);
1444 else if (CLAST_STMT_IS_A(stmt, stmt_block))
1445 codegen((const clast_block *)stmt);
1446 else if (CLAST_STMT_IS_A(stmt, stmt_for))
1447 codegen((const clast_for *)stmt);
1448 else if (CLAST_STMT_IS_A(stmt, stmt_guard))
1449 codegen((const clast_guard *)stmt);
1450
1451 if (stmt->next)
1452 codegen(stmt->next);
1453}
1454
1455void ClastStmtCodeGen::addParameters(const CloogNames *names) {
Tobias Grosserd596b372012-03-15 09:34:52 +00001456 SCEVExpander Rewriter(P->getAnalysis<ScalarEvolution>(), "polly");
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001457
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001458 int i = 0;
1459 for (Scop::param_iterator PI = S->param_begin(), PE = S->param_end();
1460 PI != PE; ++PI) {
1461 assert(i < names->nb_parameters && "Not enough parameter names");
1462
1463 const SCEV *Param = *PI;
1464 Type *Ty = Param->getType();
1465
1466 Instruction *insertLocation = --(Builder.GetInsertBlock()->end());
1467 Value *V = Rewriter.expandCodeFor(Param, Ty, insertLocation);
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001468 ClastVars[names->parameters[i]] = V;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001469
1470 ++i;
1471 }
1472}
1473
1474void ClastStmtCodeGen::codegen(const clast_root *r) {
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001475 addParameters(r->names);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001476
1477 parallelCodeGeneration = false;
1478
1479 const clast_stmt *stmt = (const clast_stmt*) r;
1480 if (stmt->next)
1481 codegen(stmt->next);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001482}
1483
Tobias Grosserd596b372012-03-15 09:34:52 +00001484ClastStmtCodeGen::ClastStmtCodeGen(Scop *scop, IRBuilder<> &B, Pass *P) :
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001485 S(scop), P(P), Builder(B), ExpGen(Builder, ClastVars) {}
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001486
Tobias Grosser75805372011-04-29 06:27:02 +00001487namespace {
1488class CodeGeneration : public ScopPass {
1489 Region *region;
1490 Scop *S;
1491 DominatorTree *DT;
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001492 RegionInfo *RI;
Tobias Grosser75805372011-04-29 06:27:02 +00001493
1494 std::vector<std::string> parallelLoops;
1495
1496 public:
1497 static char ID;
1498
1499 CodeGeneration() : ScopPass(ID) {}
1500
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001501 // Split the entry edge of the region and generate a new basic block on this
1502 // edge. This function also updates ScopInfo and RegionInfo.
1503 //
1504 // @param region The region where the entry edge will be splitted.
1505 BasicBlock *splitEdgeAdvanced(Region *region) {
1506 BasicBlock *newBlock;
1507 BasicBlock *splitBlock;
1508
1509 newBlock = SplitEdge(region->getEnteringBlock(), region->getEntry(), this);
1510
1511 if (DT->dominates(region->getEntry(), newBlock)) {
Tobias Grossercb47dfe2012-02-15 09:58:50 +00001512 BasicBlock *OldBlock = region->getEntry();
1513 std::string OldName = OldBlock->getName();
1514
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001515 // Update ScopInfo.
1516 for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI)
Tobias Grosserf12cea42012-02-15 09:58:53 +00001517 if ((*SI)->getBasicBlock() == OldBlock) {
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001518 (*SI)->setBasicBlock(newBlock);
1519 break;
1520 }
1521
1522 // Update RegionInfo.
Tobias Grossercb47dfe2012-02-15 09:58:50 +00001523 splitBlock = OldBlock;
1524 OldBlock->setName("polly.split");
1525 newBlock->setName(OldName);
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001526 region->replaceEntry(newBlock);
Tobias Grosser7a16c892011-05-14 19:01:55 +00001527 RI->setRegionFor(newBlock, region);
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001528 } else {
1529 RI->setRegionFor(newBlock, region->getParent());
1530 splitBlock = newBlock;
1531 }
1532
1533 return splitBlock;
1534 }
1535
1536 // Create a split block that branches either to the old code or to a new basic
1537 // block where the new code can be inserted.
1538 //
Tobias Grosserbd608a82012-02-12 12:09:41 +00001539 // @param Builder A builder that will be set to point to a basic block, where
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001540 // the new code can be generated.
1541 // @return The split basic block.
Tobias Grosserbd608a82012-02-12 12:09:41 +00001542 BasicBlock *addSplitAndStartBlock(IRBuilder<> *Builder) {
1543 BasicBlock *StartBlock, *SplitBlock;
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001544
Tobias Grosserbd608a82012-02-12 12:09:41 +00001545 SplitBlock = splitEdgeAdvanced(region);
1546 SplitBlock->setName("polly.split_new_and_old");
1547 Function *F = SplitBlock->getParent();
1548 StartBlock = BasicBlock::Create(F->getContext(), "polly.start", F);
1549 SplitBlock->getTerminator()->eraseFromParent();
1550 Builder->SetInsertPoint(SplitBlock);
1551 Builder->CreateCondBr(Builder->getTrue(), StartBlock, region->getEntry());
1552 DT->addNewBlock(StartBlock, SplitBlock);
1553 Builder->SetInsertPoint(StartBlock);
1554 return SplitBlock;
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001555 }
1556
1557 // Merge the control flow of the newly generated code with the existing code.
1558 //
Tobias Grosserbd608a82012-02-12 12:09:41 +00001559 // @param SplitBlock The basic block where the control flow was split between
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001560 // old and new version of the Scop.
Tobias Grosserbd608a82012-02-12 12:09:41 +00001561 // @param Builder An IRBuilder that points to the last instruction of the
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001562 // newly generated code.
Tobias Grosserbd608a82012-02-12 12:09:41 +00001563 void mergeControlFlow(BasicBlock *SplitBlock, IRBuilder<> *Builder) {
1564 BasicBlock *MergeBlock;
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001565 Region *R = region;
1566
1567 if (R->getExit()->getSinglePredecessor())
1568 // No splitEdge required. A block with a single predecessor cannot have
1569 // PHI nodes that would complicate life.
Tobias Grosserbd608a82012-02-12 12:09:41 +00001570 MergeBlock = R->getExit();
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001571 else {
Tobias Grosserbd608a82012-02-12 12:09:41 +00001572 MergeBlock = SplitEdge(R->getExitingBlock(), R->getExit(), this);
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001573 // SplitEdge will never split R->getExit(), as R->getExit() has more than
1574 // one predecessor. Hence, mergeBlock is always a newly generated block.
Tobias Grosserbd608a82012-02-12 12:09:41 +00001575 R->replaceExit(MergeBlock);
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001576 }
1577
Tobias Grosserbd608a82012-02-12 12:09:41 +00001578 Builder->CreateBr(MergeBlock);
Tobias Grosser8518bbe2012-02-12 12:09:46 +00001579 MergeBlock->setName("polly.merge_new_and_old");
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001580
Tobias Grosserbd608a82012-02-12 12:09:41 +00001581 if (DT->dominates(SplitBlock, MergeBlock))
1582 DT->changeImmediateDominator(MergeBlock, SplitBlock);
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001583 }
1584
Tobias Grosser75805372011-04-29 06:27:02 +00001585 bool runOnScop(Scop &scop) {
1586 S = &scop;
1587 region = &S->getRegion();
Tobias Grosser75805372011-04-29 06:27:02 +00001588 DT = &getAnalysis<DominatorTree>();
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001589 RI = &getAnalysis<RegionInfo>();
Tobias Grosser75805372011-04-29 06:27:02 +00001590
1591 parallelLoops.clear();
1592
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001593 assert(region->isSimple() && "Only simple regions are supported");
Tobias Grosser76d7c522011-05-14 19:01:37 +00001594
Tobias Grosser5772e652012-02-01 14:23:33 +00001595 // In the CFG the optimized code of the SCoP is generated next to the
1596 // original code. Both the new and the original version of the code remain
1597 // in the CFG. A branch statement decides which version is executed.
1598 // For now, we always execute the new version (the old one is dead code
1599 // eliminated by the cleanup passes). In the future we may decide to execute
1600 // the new version only if certain run time checks succeed. This will be
1601 // useful to support constructs for which we cannot prove all assumptions at
1602 // compile time.
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001603 //
1604 // Before transformation:
1605 //
1606 // bb0
1607 // |
1608 // orig_scop
1609 // |
1610 // bb1
1611 //
1612 // After transformation:
1613 // bb0
1614 // |
1615 // polly.splitBlock
Tobias Grosser2bd3af12011-08-01 22:39:00 +00001616 // / \.
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001617 // | startBlock
1618 // | |
1619 // orig_scop new_scop
1620 // \ /
1621 // \ /
1622 // bb1 (joinBlock)
1623 IRBuilder<> builder(region->getEntry());
Tobias Grosser75805372011-04-29 06:27:02 +00001624
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001625 // The builder will be set to startBlock.
1626 BasicBlock *splitBlock = addSplitAndStartBlock(&builder);
Tobias Grosser0ac92142012-02-14 14:02:27 +00001627 BasicBlock *StartBlock = builder.GetInsertBlock();
Tobias Grosser75805372011-04-29 06:27:02 +00001628
Tobias Grosser0ac92142012-02-14 14:02:27 +00001629 mergeControlFlow(splitBlock, &builder);
1630 builder.SetInsertPoint(StartBlock->begin());
1631
Tobias Grosserd596b372012-03-15 09:34:52 +00001632 ClastStmtCodeGen CodeGen(S, builder, this);
Tobias Grosser3fdecae2011-05-14 19:02:39 +00001633 CloogInfo &C = getAnalysis<CloogInfo>();
1634 CodeGen.codegen(C.getClast());
Tobias Grosser75805372011-04-29 06:27:02 +00001635
Tobias Grosser75805372011-04-29 06:27:02 +00001636 parallelLoops.insert(parallelLoops.begin(),
1637 CodeGen.getParallelLoops().begin(),
1638 CodeGen.getParallelLoops().end());
1639
Tobias Grosserabb6dcd2011-05-14 19:02:34 +00001640 return true;
Tobias Grosser75805372011-04-29 06:27:02 +00001641 }
1642
1643 virtual void printScop(raw_ostream &OS) const {
1644 for (std::vector<std::string>::const_iterator PI = parallelLoops.begin(),
1645 PE = parallelLoops.end(); PI != PE; ++PI)
1646 OS << "Parallel loop with iterator '" << *PI << "' generated\n";
1647 }
1648
1649 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
1650 AU.addRequired<CloogInfo>();
1651 AU.addRequired<Dependences>();
1652 AU.addRequired<DominatorTree>();
Tobias Grosser75805372011-04-29 06:27:02 +00001653 AU.addRequired<RegionInfo>();
Tobias Grosser73600b82011-10-08 00:30:40 +00001654 AU.addRequired<ScalarEvolution>();
Tobias Grosser75805372011-04-29 06:27:02 +00001655 AU.addRequired<ScopDetection>();
1656 AU.addRequired<ScopInfo>();
1657 AU.addRequired<TargetData>();
1658
1659 AU.addPreserved<CloogInfo>();
1660 AU.addPreserved<Dependences>();
Tobias Grosser5d6eb862011-05-14 19:02:45 +00001661
Tobias Grosser4e3f9a42011-05-23 15:23:36 +00001662 // FIXME: We do not create LoopInfo for the newly generated loops.
Tobias Grosser75805372011-04-29 06:27:02 +00001663 AU.addPreserved<LoopInfo>();
1664 AU.addPreserved<DominatorTree>();
Tobias Grosser75805372011-04-29 06:27:02 +00001665 AU.addPreserved<ScopDetection>();
1666 AU.addPreserved<ScalarEvolution>();
Tobias Grosser5d6eb862011-05-14 19:02:45 +00001667
Tobias Grosser4e3f9a42011-05-23 15:23:36 +00001668 // FIXME: We do not yet add regions for the newly generated code to the
1669 // region tree.
Tobias Grosser75805372011-04-29 06:27:02 +00001670 AU.addPreserved<RegionInfo>();
1671 AU.addPreserved<TempScopInfo>();
1672 AU.addPreserved<ScopInfo>();
1673 AU.addPreservedID(IndependentBlocksID);
1674 }
1675};
1676}
1677
1678char CodeGeneration::ID = 1;
1679
Tobias Grosser73600b82011-10-08 00:30:40 +00001680INITIALIZE_PASS_BEGIN(CodeGeneration, "polly-codegen",
Tobias Grosser3c2efba2012-03-06 07:38:57 +00001681 "Polly - Create LLVM-IR from SCoPs", false, false)
Tobias Grosser73600b82011-10-08 00:30:40 +00001682INITIALIZE_PASS_DEPENDENCY(CloogInfo)
1683INITIALIZE_PASS_DEPENDENCY(Dependences)
1684INITIALIZE_PASS_DEPENDENCY(DominatorTree)
1685INITIALIZE_PASS_DEPENDENCY(RegionInfo)
1686INITIALIZE_PASS_DEPENDENCY(ScalarEvolution)
1687INITIALIZE_PASS_DEPENDENCY(ScopDetection)
1688INITIALIZE_PASS_DEPENDENCY(TargetData)
1689INITIALIZE_PASS_END(CodeGeneration, "polly-codegen",
Tobias Grosser3c2efba2012-03-06 07:38:57 +00001690 "Polly - Create LLVM-IR from SCoPs", false, false)
Tobias Grosser75805372011-04-29 06:27:02 +00001691
Tobias Grosser7ffe4e82011-11-17 12:56:10 +00001692Pass *polly::createCodeGenerationPass() {
Tobias Grosser75805372011-04-29 06:27:02 +00001693 return new CodeGeneration();
1694}