blob: 32e7a256319d19f4d345e8564a36ab90d2f87f1e [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 {
92public:
Tobias Grosserd6adda32012-03-23 08:21:22 +000093 IslGenerator(IRBuilder<> &Builder, std::vector<Value *> &IVS) :
94 Builder(Builder), IVS(IVS) {}
Tobias Grosser642c4112012-03-02 11:27:25 +000095 Value *generateIslInt(__isl_take isl_int Int);
96 Value *generateIslAff(__isl_take isl_aff *Aff);
97 Value *generateIslPwAff(__isl_take isl_pw_aff *PwAff);
98
99private:
100 typedef struct {
101 Value *Result;
102 class IslGenerator *Generator;
103 } IslGenInfo;
104
105 IRBuilder<> &Builder;
Tobias Grosserd6adda32012-03-23 08:21:22 +0000106 std::vector<Value *> &IVS;
Tobias Grosser642c4112012-03-02 11:27:25 +0000107 static int mergeIslAffValues(__isl_take isl_set *Set,
108 __isl_take isl_aff *Aff, void *User);
109};
110
111Value *IslGenerator::generateIslInt(isl_int Int) {
112 mpz_t IntMPZ;
113 mpz_init(IntMPZ);
114 isl_int_get_gmp(Int, IntMPZ);
115 Value *IntValue = Builder.getInt(APInt_from_MPZ(IntMPZ));
116 mpz_clear(IntMPZ);
117 return IntValue;
118}
119
120Value *IslGenerator::generateIslAff(__isl_take isl_aff *Aff) {
Tobias Grosserd6adda32012-03-23 08:21:22 +0000121 Value *Result;
Tobias Grosser642c4112012-03-02 11:27:25 +0000122 Value *ConstValue;
123 isl_int ConstIsl;
124
125 isl_int_init(ConstIsl);
126 isl_aff_get_constant(Aff, &ConstIsl);
127 ConstValue = generateIslInt(ConstIsl);
Tobias Grosserd6adda32012-03-23 08:21:22 +0000128 Type *Ty = Builder.getInt64Ty();
Tobias Grosser642c4112012-03-02 11:27:25 +0000129
Tobias Grosserd6adda32012-03-23 08:21:22 +0000130 // FIXME: We should give the constant and coefficients the right type. Here
131 // we force it into i64.
132 Result = Builder.CreateSExtOrBitCast(ConstValue, Ty);
133
134 unsigned int NbInputDims = isl_aff_dim(Aff, isl_dim_in);
135
136 assert((IVS.size() == NbInputDims) && "The Dimension of Induction Variables"
137 "must match the dimension of the affine space.");
138
139 isl_int CoefficientIsl;
140 isl_int_init(CoefficientIsl);
141
142 for (unsigned int i = 0; i < NbInputDims; ++i) {
143 Value *CoefficientValue;
144 isl_aff_get_coefficient(Aff, isl_dim_in, i, &CoefficientIsl);
145
146 if (isl_int_is_zero(CoefficientIsl))
147 continue;
148
149 CoefficientValue = generateIslInt(CoefficientIsl);
150 CoefficientValue = Builder.CreateIntCast(CoefficientValue, Ty, true);
151 Value *IV = Builder.CreateIntCast(IVS[i], Ty, true);
152 Value *PAdd = Builder.CreateMul(CoefficientValue, IV, "p_mul_coeff");
153 Result = Builder.CreateAdd(Result, PAdd, "p_sum_coeff");
154 }
155
156 isl_int_clear(CoefficientIsl);
Tobias Grosser642c4112012-03-02 11:27:25 +0000157 isl_int_clear(ConstIsl);
158 isl_aff_free(Aff);
159
Tobias Grosserd6adda32012-03-23 08:21:22 +0000160 return Result;
Tobias Grosser642c4112012-03-02 11:27:25 +0000161}
162
163int IslGenerator::mergeIslAffValues(__isl_take isl_set *Set,
164 __isl_take isl_aff *Aff, void *User) {
165 IslGenInfo *GenInfo = (IslGenInfo *)User;
166
167 assert((GenInfo->Result == NULL) && "Result is already set."
168 "Currently only single isl_aff is supported");
169 assert(isl_set_plain_is_universe(Set)
170 && "Code generation failed because the set is not universe");
171
172 GenInfo->Result = GenInfo->Generator->generateIslAff(Aff);
173
174 isl_set_free(Set);
175 return 0;
176}
177
178Value *IslGenerator::generateIslPwAff(__isl_take isl_pw_aff *PwAff) {
179 IslGenInfo User;
180 User.Result = NULL;
181 User.Generator = this;
182 isl_pw_aff_foreach_piece(PwAff, mergeIslAffValues, &User);
183 assert(User.Result && "Code generation for isl_pw_aff failed");
184
185 isl_pw_aff_free(PwAff);
186 return User.Result;
187}
188
Tobias Grosser55d52082012-03-02 15:20:39 +0000189/// @brief Generate a new basic block for a polyhedral statement.
190///
191/// The only public function exposed is generate().
Tobias Grosser75805372011-04-29 06:27:02 +0000192class BlockGenerator {
Tobias Grosserc941ede2012-03-02 11:26:49 +0000193public:
Tobias Grosser55d52082012-03-02 15:20:39 +0000194 /// @brief Generate a new BasicBlock for a ScopStmt.
195 ///
196 /// @param Builder The LLVM-IR Builder used to generate the statement. The
197 /// code is generated at the location, the Builder points to.
198 /// @param Stmt The statement to code generate.
199 /// @param GlobalMap A map that defines for certain Values referenced from the
200 /// original code new Values they should be replaced with.
201 /// @param P A reference to the pass this function is called from.
202 /// The pass is needed to update other analysis.
203 static void generate(IRBuilder<> &Builder, ScopStmt &Stmt,
204 ValueMapT &GlobalMap, Pass *P) {
205 BlockGenerator Generator(Builder, Stmt, P);
206 Generator.copyBB(GlobalMap);
Tobias Grosserc941ede2012-03-02 11:26:49 +0000207 }
208
Tobias Grosser80998e72012-03-02 11:27:28 +0000209protected:
Tobias Grosser75805372011-04-29 06:27:02 +0000210 IRBuilder<> &Builder;
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000211 ScopStmt &Statement;
Tobias Grosser8412cda2012-03-02 11:26:55 +0000212 Pass *P;
Tobias Grosser75805372011-04-29 06:27:02 +0000213
Tobias Grosser55d52082012-03-02 15:20:39 +0000214 BlockGenerator(IRBuilder<> &B, ScopStmt &Stmt, Pass *P);
Tobias Grosser75805372011-04-29 06:27:02 +0000215
Tobias Grosser55d52082012-03-02 15:20:39 +0000216 /// @brief Get the new version of a Value.
217 ///
218 /// @param Old The old Value.
Tobias Grosser3c2efba2012-03-06 07:38:57 +0000219 /// @param BBMap A mapping from old values to their new values
Tobias Grosser55d52082012-03-02 15:20:39 +0000220 /// (for values recalculated within this basic block).
221 /// @param GlobalMap A mapping from old values to their new values
222 /// (for values recalculated in the new ScoP, but not
223 /// within this basic block).
224 ///
225 /// @returns o The old value, if it is still valid.
226 /// o The new value, if available.
227 /// o NULL, if no value is found.
228 Value *getNewValue(const Value *Old, ValueMapT &BBMap, ValueMapT &GlobalMap);
Tobias Grosser75805372011-04-29 06:27:02 +0000229
Tobias Grosserdf382372012-03-02 15:20:35 +0000230 void copyInstScalar(const Instruction *Inst, ValueMapT &BBMap,
231 ValueMapT &GlobalMap);
Tobias Grosser75805372011-04-29 06:27:02 +0000232
Raghesh Aloor129e8672011-08-15 02:33:39 +0000233 /// @brief Get the memory access offset to be added to the base address
Tobias Grosser80998e72012-03-02 11:27:28 +0000234 std::vector<Value*> getMemoryAccessIndex(__isl_keep isl_map *AccessRelation,
Tobias Grosserd6adda32012-03-23 08:21:22 +0000235 Value *BaseAddress, ValueMapT &BBMap,
236 ValueMapT &GlobalMap);
Raghesh Aloor129e8672011-08-15 02:33:39 +0000237
Raghesh Aloor62b13122011-08-03 17:02:50 +0000238 /// @brief Get the new operand address according to the changed access in
239 /// JSCOP file.
Raghesh Aloor46eceba2011-12-09 14:27:17 +0000240 Value *getNewAccessOperand(__isl_keep isl_map *NewAccessRelation,
Tobias Grosserd6d7d7e2012-04-01 16:55:30 +0000241 Value *BaseAddress, ValueMapT &BBMap,
242 ValueMapT &GlobalMap);
Raghesh Aloor62b13122011-08-03 17:02:50 +0000243
244 /// @brief Generate the operand address
245 Value *generateLocationAccessed(const Instruction *Inst,
Tobias Grosserdf382372012-03-02 15:20:35 +0000246 const Value *Pointer, ValueMapT &BBMap,
247 ValueMapT &GlobalMap);
Raghesh Aloor129e8672011-08-15 02:33:39 +0000248
Tobias Grosserdf382372012-03-02 15:20:35 +0000249 Value *generateScalarLoad(const LoadInst *load, ValueMapT &BBMap,
250 ValueMapT &GlobalMap);
Tobias Grosser75805372011-04-29 06:27:02 +0000251
Tobias Grosserd6adda32012-03-23 08:21:22 +0000252 Value *generateScalarStore(const StoreInst *store, ValueMapT &BBMap,
253 ValueMapT &GlobalMap);
254
Tobias Grosser55d52082012-03-02 15:20:39 +0000255 /// @brief Copy a single Instruction.
256 ///
257 /// This copies a single Instruction and updates references to old values
258 /// with references to new values, as defined by GlobalMap and BBMap.
259 ///
Tobias Grosser3c2efba2012-03-06 07:38:57 +0000260 /// @param BBMap A mapping from old values to their new values
Tobias Grosser55d52082012-03-02 15:20:39 +0000261 /// (for values recalculated within this basic block).
262 /// @param GlobalMap A mapping from old values to their new values
263 /// (for values recalculated in the new ScoP, but not
264 /// within this basic block).
265 void copyInstruction(const Instruction *Inst, ValueMapT &BBMap,
Tobias Grosserdf382372012-03-02 15:20:35 +0000266 ValueMapT &GlobalMap);
Tobias Grosser75805372011-04-29 06:27:02 +0000267
Tobias Grosser55d52082012-03-02 15:20:39 +0000268 /// @brief Copy the basic block.
269 ///
270 /// This copies the entire basic block and updates references to old values
271 /// with references to new values, as defined by GlobalMap.
272 ///
273 /// @param GlobalMap A mapping from old values to their new values
274 /// (for values recalculated in the new ScoP, but not
275 /// within this basic block).
276 void copyBB(ValueMapT &GlobalMap);
Tobias Grosser75805372011-04-29 06:27:02 +0000277};
278
Tobias Grosser55d52082012-03-02 15:20:39 +0000279BlockGenerator::BlockGenerator(IRBuilder<> &B, ScopStmt &Stmt, Pass *P):
280 Builder(B), Statement(Stmt), P(P) {}
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000281
Tobias Grosser55d52082012-03-02 15:20:39 +0000282Value *BlockGenerator::getNewValue(const Value *Old, ValueMapT &BBMap,
283 ValueMapT &GlobalMap) {
Tobias Grosser89339062012-04-01 16:49:45 +0000284 // We assume constants never change.
285 // This avoids map lookups for many calls to this function.
286 if (isa<Constant>(Old))
Tobias Grosser55d52082012-03-02 15:20:39 +0000287 return const_cast<Value*>(Old);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000288
Tobias Grosser55d52082012-03-02 15:20:39 +0000289 if (GlobalMap.count(Old)) {
290 Value *New = GlobalMap[Old];
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000291
Tobias Grosser55d52082012-03-02 15:20:39 +0000292 if (Old->getType()->getScalarSizeInBits()
293 < New->getType()->getScalarSizeInBits())
294 New = Builder.CreateTruncOrBitCast(New, Old->getType());
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000295
Tobias Grosser55d52082012-03-02 15:20:39 +0000296 return New;
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000297 }
298
Tobias Grosser55d52082012-03-02 15:20:39 +0000299 if (BBMap.count(Old)) {
300 return BBMap[Old];
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000301 }
302
Tobias Grosser89339062012-04-01 16:49:45 +0000303 // 'Old' is within the original SCoP, but was not rewritten.
304 //
305 // Such values appear, if they only calculate information already available in
306 // the polyhedral description (e.g. an induction variable increment). They
307 // can be safely ignored.
308 if (const Instruction *Inst = dyn_cast<Instruction>(Old))
309 if (Statement.getParent()->getRegion().contains(Inst->getParent()))
310 return NULL;
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000311
Tobias Grosser89339062012-04-01 16:49:45 +0000312 // Everything else is probably a scop-constant value defined as global,
313 // function parameter or an instruction not within the scop.
314 return const_cast<Value*>(Old);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000315}
316
Tobias Grosserdf382372012-03-02 15:20:35 +0000317void BlockGenerator::copyInstScalar(const Instruction *Inst, ValueMapT &BBMap,
318 ValueMapT &GlobalMap) {
Tobias Grosser80998e72012-03-02 11:27:28 +0000319 Instruction *NewInst = Inst->clone();
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000320
Tobias Grosser80998e72012-03-02 11:27:28 +0000321 // Replace old operands with the new ones.
322 for (Instruction::const_op_iterator OI = Inst->op_begin(),
323 OE = Inst->op_end(); OI != OE; ++OI) {
324 Value *OldOperand = *OI;
Tobias Grosser55d52082012-03-02 15:20:39 +0000325 Value *NewOperand = getNewValue(OldOperand, BBMap, GlobalMap);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000326
Tobias Grosser80998e72012-03-02 11:27:28 +0000327 if (!NewOperand) {
328 assert(!isa<StoreInst>(NewInst)
329 && "Store instructions are always needed!");
330 delete NewInst;
331 return;
332 }
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000333
Tobias Grosser80998e72012-03-02 11:27:28 +0000334 NewInst->replaceUsesOfWith(OldOperand, NewOperand);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000335 }
336
Tobias Grosser80998e72012-03-02 11:27:28 +0000337 Builder.Insert(NewInst);
338 BBMap[Inst] = NewInst;
339
340 if (!NewInst->getType()->isVoidTy())
341 NewInst->setName("p_" + Inst->getName());
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000342}
343
Tobias Grosserd6adda32012-03-23 08:21:22 +0000344std::vector<Value*> BlockGenerator::getMemoryAccessIndex(
345 __isl_keep isl_map *AccessRelation, Value *BaseAddress,
346 ValueMapT &BBMap, ValueMapT &GlobalMap) {
347
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000348 assert((isl_map_dim(AccessRelation, isl_dim_out) == 1)
349 && "Only single dimensional access functions supported");
350
Tobias Grosserd6adda32012-03-23 08:21:22 +0000351 std::vector<Value *> IVS;
352 for (unsigned i = 0; i < Statement.getNumIterators(); ++i) {
353 const Value *OriginalIV = Statement.getInductionVariableForDimension(i);
354 Value *NewIV = getNewValue(OriginalIV, BBMap, GlobalMap);
355 IVS.push_back(NewIV);
356 }
357
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000358 isl_pw_aff *PwAff = isl_map_dim_max(isl_map_copy(AccessRelation), 0);
Tobias Grosserd6adda32012-03-23 08:21:22 +0000359 IslGenerator IslGen(Builder, IVS);
Tobias Grosser642c4112012-03-02 11:27:25 +0000360 Value *OffsetValue = IslGen.generateIslPwAff(PwAff);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000361
Tobias Grosserd6adda32012-03-23 08:21:22 +0000362 Type *Ty = Builder.getInt64Ty();
363 OffsetValue = Builder.CreateIntCast(OffsetValue, Ty, true);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000364
365 std::vector<Value*> IndexArray;
Tobias Grosserd6adda32012-03-23 08:21:22 +0000366 Value *NullValue = Constant::getNullValue(Ty);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000367 IndexArray.push_back(NullValue);
368 IndexArray.push_back(OffsetValue);
369 return IndexArray;
370}
371
372Value *BlockGenerator::getNewAccessOperand(
Tobias Grosserd6d7d7e2012-04-01 16:55:30 +0000373 __isl_keep isl_map *NewAccessRelation, Value *BaseAddress,
374 ValueMapT &BBMap, ValueMapT &GlobalMap) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000375 std::vector<Value*> IndexArray = getMemoryAccessIndex(NewAccessRelation,
Tobias Grosserd6adda32012-03-23 08:21:22 +0000376 BaseAddress,
377 BBMap, GlobalMap);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000378 Value *NewOperand = Builder.CreateGEP(BaseAddress, IndexArray,
379 "p_newarrayidx_");
380 return NewOperand;
381}
382
383Value *BlockGenerator::generateLocationAccessed(const Instruction *Inst,
384 const Value *Pointer,
Tobias Grosserdf382372012-03-02 15:20:35 +0000385 ValueMapT &BBMap,
386 ValueMapT &GlobalMap) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000387 MemoryAccess &Access = Statement.getAccessFor(Inst);
388 isl_map *CurrentAccessRelation = Access.getAccessRelation();
389 isl_map *NewAccessRelation = Access.getNewAccessRelation();
390
391 assert(isl_map_has_equal_space(CurrentAccessRelation, NewAccessRelation)
392 && "Current and new access function use different spaces");
393
394 Value *NewPointer;
395
396 if (!NewAccessRelation) {
Tobias Grosser55d52082012-03-02 15:20:39 +0000397 NewPointer = getNewValue(Pointer, BBMap, GlobalMap);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000398 } else {
399 Value *BaseAddress = const_cast<Value*>(Access.getBaseAddr());
Tobias Grosserd6d7d7e2012-04-01 16:55:30 +0000400 NewPointer = getNewAccessOperand(NewAccessRelation, BaseAddress,
Tobias Grosserd6adda32012-03-23 08:21:22 +0000401 BBMap, GlobalMap);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000402 }
403
404 isl_map_free(CurrentAccessRelation);
405 isl_map_free(NewAccessRelation);
406 return NewPointer;
407}
408
409Value *BlockGenerator::generateScalarLoad(const LoadInst *Load,
Tobias Grosserdf382372012-03-02 15:20:35 +0000410 ValueMapT &BBMap,
411 ValueMapT &GlobalMap) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000412 const Value *Pointer = Load->getPointerOperand();
413 const Instruction *Inst = dyn_cast<Instruction>(Load);
Tobias Grosserdf382372012-03-02 15:20:35 +0000414 Value *NewPointer = generateLocationAccessed(Inst, Pointer, BBMap, GlobalMap);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000415 Value *ScalarLoad = Builder.CreateLoad(NewPointer,
416 Load->getName() + "_p_scalar_");
417 return ScalarLoad;
418}
419
Tobias Grosserd6adda32012-03-23 08:21:22 +0000420Value *BlockGenerator::generateScalarStore(const StoreInst *Store,
421 ValueMapT &BBMap,
422 ValueMapT &GlobalMap) {
423 const Value *Pointer = Store->getPointerOperand();
424 Value *NewPointer = generateLocationAccessed(Store, Pointer, BBMap,
425 GlobalMap);
426 Value *ValueOperand = getNewValue(Store->getValueOperand(), BBMap, GlobalMap);
427
428 return Builder.CreateStore(ValueOperand, NewPointer);
429}
430
Tobias Grosser80998e72012-03-02 11:27:28 +0000431void BlockGenerator::copyInstruction(const Instruction *Inst,
Tobias Grosserdf382372012-03-02 15:20:35 +0000432 ValueMapT &BBMap, ValueMapT &GlobalMap) {
Tobias Grosser80998e72012-03-02 11:27:28 +0000433 // Terminator instructions control the control flow. They are explicitly
434 // expressed in the clast and do not need to be copied.
435 if (Inst->isTerminator())
436 return;
437
438 if (const LoadInst *Load = dyn_cast<LoadInst>(Inst)) {
Tobias Grosserdf382372012-03-02 15:20:35 +0000439 BBMap[Load] = generateScalarLoad(Load, BBMap, GlobalMap);
Tobias Grosser80998e72012-03-02 11:27:28 +0000440 return;
441 }
442
Tobias Grosserd6adda32012-03-23 08:21:22 +0000443 if (const StoreInst *Store = dyn_cast<StoreInst>(Inst)) {
444 BBMap[Store] = generateScalarStore(Store, BBMap, GlobalMap);
445 return;
446 }
447
Tobias Grosserdf382372012-03-02 15:20:35 +0000448 copyInstScalar(Inst, BBMap, GlobalMap);
Tobias Grosser80998e72012-03-02 11:27:28 +0000449}
450
451
Tobias Grosser55d52082012-03-02 15:20:39 +0000452void BlockGenerator::copyBB(ValueMapT &GlobalMap) {
Tobias Grosser80998e72012-03-02 11:27:28 +0000453 BasicBlock *BB = Statement.getBasicBlock();
454 BasicBlock *CopyBB = SplitBlock(Builder.GetInsertBlock(),
455 Builder.GetInsertPoint(), P);
456 CopyBB->setName("polly.stmt." + BB->getName());
457 Builder.SetInsertPoint(CopyBB->begin());
458
Tobias Grosserdf382372012-03-02 15:20:35 +0000459 ValueMapT BBMap;
Tobias Grosser80998e72012-03-02 11:27:28 +0000460
461 for (BasicBlock::const_iterator II = BB->begin(), IE = BB->end(); II != IE;
462 ++II)
Tobias Grosserdf382372012-03-02 15:20:35 +0000463 copyInstruction(II, BBMap, GlobalMap);
Tobias Grosser80998e72012-03-02 11:27:28 +0000464}
465
Tobias Grosser55d52082012-03-02 15:20:39 +0000466/// @brief Generate a new vector basic block for a polyhedral statement.
467///
468/// The only public function exposed is generate().
Tobias Grosser80998e72012-03-02 11:27:28 +0000469class VectorBlockGenerator : BlockGenerator {
470public:
Tobias Grosser55d52082012-03-02 15:20:39 +0000471 /// @brief Generate a new vector basic block for a ScoPStmt.
472 ///
473 /// This code generation is similar to the normal, scalar code generation,
474 /// except that each instruction is code generated for several vector lanes
475 /// at a time. If possible instructions are issued as actual vector
476 /// instructions, but e.g. for address calculation instructions we currently
477 /// generate scalar instructions for each vector lane.
478 ///
479 /// @param Builder The LLVM-IR Builder used to generate the statement. The
480 /// code is generated at the location, the builder points
481 /// to.
482 /// @param Stmt The statement to code generate.
483 /// @param GlobalMaps A vector of maps that define for certain Values
484 /// referenced from the original code new Values they should
485 /// be replaced with. Each map in the vector of maps is
486 /// used for one vector lane. The number of elements in the
487 /// vector defines the width of the generated vector
488 /// instructions.
489 /// @param P A reference to the pass this function is called from.
490 /// The pass is needed to update other analysis.
491 static void generate(IRBuilder<> &B, ScopStmt &Stmt,
492 VectorValueMapT &GlobalMaps, __isl_keep isl_set *Domain,
493 Pass *P) {
494 VectorBlockGenerator Generator(B, GlobalMaps, Stmt, Domain, P);
Tobias Grosser80998e72012-03-02 11:27:28 +0000495 Generator.copyBB();
496 }
497
498private:
Tobias Grosser55d52082012-03-02 15:20:39 +0000499 // This is a vector of global value maps. The first map is used for the first
500 // vector lane, ...
501 // Each map, contains information about Instructions in the old ScoP, which
502 // are recalculated in the new SCoP. When copying the basic block, we replace
503 // all referenes to the old instructions with their recalculated values.
Tobias Grosserdf382372012-03-02 15:20:35 +0000504 VectorValueMapT &GlobalMaps;
Tobias Grosser80998e72012-03-02 11:27:28 +0000505
Tobias Grosser08a82382012-03-02 15:20:24 +0000506 isl_set *Domain;
507
Tobias Grosser55d52082012-03-02 15:20:39 +0000508 VectorBlockGenerator(IRBuilder<> &B, VectorValueMapT &GlobalMaps,
509 ScopStmt &Stmt, __isl_keep isl_set *Domain, Pass *P);
Tobias Grosser80998e72012-03-02 11:27:28 +0000510
511 int getVectorWidth();
512
Tobias Grosser55d52082012-03-02 15:20:39 +0000513 Value *getVectorValue(const Value *Old, ValueMapT &VectorMap,
514 VectorValueMapT &ScalarMaps);
Tobias Grosser80998e72012-03-02 11:27:28 +0000515
516 Type *getVectorPtrTy(const Value *V, int Width);
517
518 /// @brief Load a vector from a set of adjacent scalars
519 ///
520 /// In case a set of scalars is known to be next to each other in memory,
521 /// create a vector load that loads those scalars
522 ///
523 /// %vector_ptr= bitcast double* %p to <4 x double>*
524 /// %vec_full = load <4 x double>* %vector_ptr
525 ///
526 Value *generateStrideOneLoad(const LoadInst *Load, ValueMapT &BBMap);
527
528 /// @brief Load a vector initialized from a single scalar in memory
529 ///
530 /// In case all elements of a vector are initialized to the same
531 /// scalar value, this value is loaded and shuffeled into all elements
532 /// of the vector.
533 ///
534 /// %splat_one = load <1 x double>* %p
535 /// %splat = shufflevector <1 x double> %splat_one, <1 x
536 /// double> %splat_one, <4 x i32> zeroinitializer
537 ///
538 Value *generateStrideZeroLoad(const LoadInst *Load, ValueMapT &BBMap);
539
540 /// @Load a vector from scalars distributed in memory
541 ///
542 /// In case some scalars a distributed randomly in memory. Create a vector
543 /// by loading each scalar and by inserting one after the other into the
544 /// vector.
545 ///
546 /// %scalar_1= load double* %p_1
547 /// %vec_1 = insertelement <2 x double> undef, double %scalar_1, i32 0
548 /// %scalar 2 = load double* %p_2
549 /// %vec_2 = insertelement <2 x double> %vec_1, double %scalar_1, i32 1
550 ///
551 Value *generateUnknownStrideLoad(const LoadInst *Load,
552 VectorValueMapT &ScalarMaps);
553
Tobias Grosser80998e72012-03-02 11:27:28 +0000554 void generateLoad(const LoadInst *Load, ValueMapT &VectorMap,
555 VectorValueMapT &ScalarMaps);
556
Tobias Grosserdf382372012-03-02 15:20:35 +0000557 void copyUnaryInst(const UnaryInstruction *Inst, ValueMapT &VectorMap,
558 VectorValueMapT &ScalarMaps);
Tobias Grosser80998e72012-03-02 11:27:28 +0000559
Tobias Grosserdf382372012-03-02 15:20:35 +0000560 void copyBinaryInst(const BinaryOperator *Inst, ValueMapT &VectorMap,
561 VectorValueMapT &ScalarMaps);
Tobias Grosser80998e72012-03-02 11:27:28 +0000562
Tobias Grosserdf382372012-03-02 15:20:35 +0000563 void copyStore(const StoreInst *Store, ValueMapT &VectorMap,
Tobias Grosser260e86d2012-03-02 15:20:28 +0000564 VectorValueMapT &ScalarMaps);
Tobias Grosser80998e72012-03-02 11:27:28 +0000565
566 bool hasVectorOperands(const Instruction *Inst, ValueMapT &VectorMap);
567
568 void copyInstruction(const Instruction *Inst, ValueMapT &VectorMap,
569 VectorValueMapT &ScalarMaps);
570
Tobias Grosser80998e72012-03-02 11:27:28 +0000571 void copyBB();
572};
573
Tobias Grosser55d52082012-03-02 15:20:39 +0000574VectorBlockGenerator::VectorBlockGenerator(IRBuilder<> &B,
575 VectorValueMapT &GlobalMaps, ScopStmt &Stmt, __isl_keep isl_set *Domain,
576 Pass *P) : BlockGenerator(B, Stmt, P), GlobalMaps(GlobalMaps),
577 Domain(Domain) {
Tobias Grosserdf382372012-03-02 15:20:35 +0000578 assert(GlobalMaps.size() > 1 && "Only one vector lane found");
Tobias Grosser08a82382012-03-02 15:20:24 +0000579 assert(Domain && "No statement domain provided");
Tobias Grosser80998e72012-03-02 11:27:28 +0000580 }
581
Tobias Grosser55d52082012-03-02 15:20:39 +0000582Value *VectorBlockGenerator::getVectorValue(const Value *Old,
583 ValueMapT &VectorMap,
584 VectorValueMapT &ScalarMaps) {
585 if (VectorMap.count(Old))
586 return VectorMap[Old];
Tobias Grosser80998e72012-03-02 11:27:28 +0000587
Tobias Grosserdf382372012-03-02 15:20:35 +0000588 int Width = getVectorWidth();
Tobias Grosser80998e72012-03-02 11:27:28 +0000589
Tobias Grosser55d52082012-03-02 15:20:39 +0000590 Value *Vector = UndefValue::get(VectorType::get(Old->getType(), Width));
Tobias Grosser80998e72012-03-02 11:27:28 +0000591
Tobias Grosserdf382372012-03-02 15:20:35 +0000592 for (int Lane = 0; Lane < Width; Lane++)
593 Vector = Builder.CreateInsertElement(Vector,
Tobias Grosser55d52082012-03-02 15:20:39 +0000594 getNewValue(Old,
595 ScalarMaps[Lane],
596 GlobalMaps[Lane]),
Tobias Grosserdf382372012-03-02 15:20:35 +0000597 Builder.getInt32(Lane));
Tobias Grosser80998e72012-03-02 11:27:28 +0000598
Tobias Grosser55d52082012-03-02 15:20:39 +0000599 VectorMap[Old] = Vector;
Tobias Grosserdf382372012-03-02 15:20:35 +0000600
601 return Vector;
Tobias Grosser80998e72012-03-02 11:27:28 +0000602}
603
604Type *VectorBlockGenerator::getVectorPtrTy(const Value *Val, int Width) {
605 PointerType *PointerTy = dyn_cast<PointerType>(Val->getType());
606 assert(PointerTy && "PointerType expected");
607
608 Type *ScalarType = PointerTy->getElementType();
609 VectorType *VectorType = VectorType::get(ScalarType, Width);
610
611 return PointerType::getUnqual(VectorType);
612}
613
614Value *VectorBlockGenerator::generateStrideOneLoad(const LoadInst *Load,
615 ValueMapT &BBMap) {
616 const Value *Pointer = Load->getPointerOperand();
617 Type *VectorPtrType = getVectorPtrTy(Pointer, getVectorWidth());
Tobias Grosser55d52082012-03-02 15:20:39 +0000618 Value *NewPointer = getNewValue(Pointer, BBMap, GlobalMaps[0]);
Tobias Grosser80998e72012-03-02 11:27:28 +0000619 Value *VectorPtr = Builder.CreateBitCast(NewPointer, VectorPtrType,
620 "vector_ptr");
621 LoadInst *VecLoad = Builder.CreateLoad(VectorPtr,
622 Load->getName() + "_p_vec_full");
623 if (!Aligned)
624 VecLoad->setAlignment(8);
625
626 return VecLoad;
627}
628
629Value *VectorBlockGenerator::generateStrideZeroLoad(const LoadInst *Load,
630 ValueMapT &BBMap) {
631 const Value *Pointer = Load->getPointerOperand();
632 Type *VectorPtrType = getVectorPtrTy(Pointer, 1);
Tobias Grosser55d52082012-03-02 15:20:39 +0000633 Value *NewPointer = getNewValue(Pointer, BBMap, GlobalMaps[0]);
Tobias Grosser80998e72012-03-02 11:27:28 +0000634 Value *VectorPtr = Builder.CreateBitCast(NewPointer, VectorPtrType,
635 Load->getName() + "_p_vec_p");
636 LoadInst *ScalarLoad= Builder.CreateLoad(VectorPtr,
637 Load->getName() + "_p_splat_one");
638
639 if (!Aligned)
640 ScalarLoad->setAlignment(8);
641
642 Constant *SplatVector =
643 Constant::getNullValue(VectorType::get(Builder.getInt32Ty(),
644 getVectorWidth()));
645
646 Value *VectorLoad = Builder.CreateShuffleVector(ScalarLoad, ScalarLoad,
647 SplatVector,
648 Load->getName()
649 + "_p_splat");
650 return VectorLoad;
651}
652
653Value *VectorBlockGenerator::generateUnknownStrideLoad(const LoadInst *Load,
654 VectorValueMapT &ScalarMaps) {
655 int VectorWidth = getVectorWidth();
656 const Value *Pointer = Load->getPointerOperand();
657 VectorType *VectorType = VectorType::get(
658 dyn_cast<PointerType>(Pointer->getType())->getElementType(), VectorWidth);
659
660 Value *Vector = UndefValue::get(VectorType);
661
662 for (int i = 0; i < VectorWidth; i++) {
Tobias Grosser55d52082012-03-02 15:20:39 +0000663 Value *NewPointer = getNewValue(Pointer, ScalarMaps[i], GlobalMaps[i]);
Tobias Grosser80998e72012-03-02 11:27:28 +0000664 Value *ScalarLoad = Builder.CreateLoad(NewPointer,
665 Load->getName() + "_p_scalar_");
666 Vector = Builder.CreateInsertElement(Vector, ScalarLoad,
667 Builder.getInt32(i),
668 Load->getName() + "_p_vec_");
669 }
670
671 return Vector;
672}
673
674void VectorBlockGenerator::generateLoad(const LoadInst *Load,
675 ValueMapT &VectorMap,
676 VectorValueMapT &ScalarMaps) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000677 Value *NewLoad;
678
679 MemoryAccess &Access = Statement.getAccessFor(Load);
680
Tobias Grosser08a82382012-03-02 15:20:24 +0000681 if (Access.isStrideZero(isl_set_copy(Domain)))
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000682 NewLoad = generateStrideZeroLoad(Load, ScalarMaps[0]);
Tobias Grosser08a82382012-03-02 15:20:24 +0000683 else if (Access.isStrideOne(isl_set_copy(Domain)))
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000684 NewLoad = generateStrideOneLoad(Load, ScalarMaps[0]);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000685 else
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000686 NewLoad = generateUnknownStrideLoad(Load, ScalarMaps);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000687
688 VectorMap[Load] = NewLoad;
689}
690
Tobias Grosser80998e72012-03-02 11:27:28 +0000691void VectorBlockGenerator::copyUnaryInst(const UnaryInstruction *Inst,
Tobias Grosserdf382372012-03-02 15:20:35 +0000692 ValueMapT &VectorMap,
693 VectorValueMapT &ScalarMaps) {
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000694 int VectorWidth = getVectorWidth();
Tobias Grosser55d52082012-03-02 15:20:39 +0000695 Value *NewOperand = getVectorValue(Inst->getOperand(0), VectorMap,
696 ScalarMaps);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000697
698 assert(isa<CastInst>(Inst) && "Can not generate vector code for instruction");
699
700 const CastInst *Cast = dyn_cast<CastInst>(Inst);
701 VectorType *DestType = VectorType::get(Inst->getType(), VectorWidth);
702 VectorMap[Inst] = Builder.CreateCast(Cast->getOpcode(), NewOperand, DestType);
703}
704
Tobias Grosser80998e72012-03-02 11:27:28 +0000705void VectorBlockGenerator::copyBinaryInst(const BinaryOperator *Inst,
Tobias Grosserdf382372012-03-02 15:20:35 +0000706 ValueMapT &VectorMap,
707 VectorValueMapT &ScalarMaps) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000708 Value *OpZero = Inst->getOperand(0);
709 Value *OpOne = Inst->getOperand(1);
710
711 Value *NewOpZero, *NewOpOne;
Tobias Grosser55d52082012-03-02 15:20:39 +0000712 NewOpZero = getVectorValue(OpZero, VectorMap, ScalarMaps);
713 NewOpOne = getVectorValue(OpOne, VectorMap, ScalarMaps);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000714
715 Value *NewInst = Builder.CreateBinOp(Inst->getOpcode(), NewOpZero,
716 NewOpOne,
717 Inst->getName() + "p_vec");
718 VectorMap[Inst] = NewInst;
719}
720
Tobias Grosserdf382372012-03-02 15:20:35 +0000721void VectorBlockGenerator::copyStore(const StoreInst *Store,
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000722 ValueMapT &VectorMap,
Tobias Grosser8927a442012-03-02 11:27:05 +0000723 VectorValueMapT &ScalarMaps) {
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000724 int VectorWidth = getVectorWidth();
725
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000726 MemoryAccess &Access = Statement.getAccessFor(Store);
727
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000728 const Value *Pointer = Store->getPointerOperand();
Tobias Grosser55d52082012-03-02 15:20:39 +0000729 Value *Vector = getVectorValue(Store->getValueOperand(), VectorMap,
Tobias Grosserdf382372012-03-02 15:20:35 +0000730 ScalarMaps);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000731
Tobias Grosser08a82382012-03-02 15:20:24 +0000732 if (Access.isStrideOne(isl_set_copy(Domain))) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000733 Type *VectorPtrType = getVectorPtrTy(Pointer, VectorWidth);
Tobias Grosser55d52082012-03-02 15:20:39 +0000734 Value *NewPointer = getNewValue(Pointer, ScalarMaps[0], GlobalMaps[0]);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000735
736 Value *VectorPtr = Builder.CreateBitCast(NewPointer, VectorPtrType,
737 "vector_ptr");
738 StoreInst *Store = Builder.CreateStore(Vector, VectorPtr);
739
740 if (!Aligned)
741 Store->setAlignment(8);
742 } else {
743 for (unsigned i = 0; i < ScalarMaps.size(); i++) {
744 Value *Scalar = Builder.CreateExtractElement(Vector,
745 Builder.getInt32(i));
Tobias Grosser55d52082012-03-02 15:20:39 +0000746 Value *NewPointer = getNewValue(Pointer, ScalarMaps[i], GlobalMaps[i]);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000747 Builder.CreateStore(Scalar, NewPointer);
748 }
749 }
750}
751
Tobias Grosser80998e72012-03-02 11:27:28 +0000752bool VectorBlockGenerator::hasVectorOperands(const Instruction *Inst,
753 ValueMapT &VectorMap) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000754 for (Instruction::const_op_iterator OI = Inst->op_begin(),
755 OE = Inst->op_end(); OI != OE; ++OI)
756 if (VectorMap.count(*OI))
757 return true;
758 return false;
759}
760
Tobias Grosser80998e72012-03-02 11:27:28 +0000761int VectorBlockGenerator::getVectorWidth() {
Tobias Grosserdf382372012-03-02 15:20:35 +0000762 return GlobalMaps.size();
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000763}
764
Tobias Grosser80998e72012-03-02 11:27:28 +0000765void VectorBlockGenerator::copyInstruction(const Instruction *Inst,
Tobias Grosser32152cb2012-03-02 11:27:18 +0000766 ValueMapT &VectorMap,
767 VectorValueMapT &ScalarMaps) {
Tobias Grosser80998e72012-03-02 11:27:28 +0000768 // Terminator instructions control the control flow. They are explicitly
769 // expressed in the clast and do not need to be copied.
770 if (Inst->isTerminator())
771 return;
772
Tobias Grosser32152cb2012-03-02 11:27:18 +0000773 if (const LoadInst *Load = dyn_cast<LoadInst>(Inst)) {
Tobias Grosser80998e72012-03-02 11:27:28 +0000774 generateLoad(Load, VectorMap, ScalarMaps);
Tobias Grosser32152cb2012-03-02 11:27:18 +0000775 return;
776 }
777
778 if (hasVectorOperands(Inst, VectorMap)) {
779 if (const StoreInst *Store = dyn_cast<StoreInst>(Inst)) {
Tobias Grosserdf382372012-03-02 15:20:35 +0000780 copyStore(Store, VectorMap, ScalarMaps);
Tobias Grosser32152cb2012-03-02 11:27:18 +0000781 return;
782 }
783
784 if (const UnaryInstruction *Unary = dyn_cast<UnaryInstruction>(Inst)) {
Tobias Grosserdf382372012-03-02 15:20:35 +0000785 copyUnaryInst(Unary, VectorMap, ScalarMaps);
Tobias Grosser32152cb2012-03-02 11:27:18 +0000786 return;
787 }
788
789 if (const BinaryOperator *Binary = dyn_cast<BinaryOperator>(Inst)) {
Tobias Grosserdf382372012-03-02 15:20:35 +0000790 copyBinaryInst(Binary, VectorMap, ScalarMaps);
Tobias Grosser32152cb2012-03-02 11:27:18 +0000791 return;
792 }
793
794 llvm_unreachable("Cannot issue vector code for this instruction");
795 }
796
797 for (int VectorLane = 0; VectorLane < getVectorWidth(); VectorLane++)
Tobias Grosserdf382372012-03-02 15:20:35 +0000798 copyInstScalar(Inst, ScalarMaps[VectorLane], GlobalMaps[VectorLane]);
Tobias Grosser32152cb2012-03-02 11:27:18 +0000799}
800
Tobias Grosser80998e72012-03-02 11:27:28 +0000801void VectorBlockGenerator::copyBB() {
Tobias Grosser14bcbd52012-03-02 11:26:52 +0000802 BasicBlock *BB = Statement.getBasicBlock();
Tobias Grosser0ac92142012-02-14 14:02:27 +0000803 BasicBlock *CopyBB = SplitBlock(Builder.GetInsertBlock(),
804 Builder.GetInsertPoint(), P);
Tobias Grosserb61e6312012-02-15 09:58:46 +0000805 CopyBB->setName("polly.stmt." + BB->getName());
Tobias Grosser0ac92142012-02-14 14:02:27 +0000806 Builder.SetInsertPoint(CopyBB->begin());
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000807
808 // Create two maps that store the mapping from the original instructions of
809 // the old basic block to their copies in the new basic block. Those maps
810 // are basic block local.
811 //
812 // As vector code generation is supported there is one map for scalar values
813 // and one for vector values.
814 //
815 // In case we just do scalar code generation, the vectorMap is not used and
816 // the scalarMap has just one dimension, which contains the mapping.
817 //
818 // In case vector code generation is done, an instruction may either appear
819 // in the vector map once (as it is calculating >vectorwidth< values at a
820 // time. Or (if the values are calculated using scalar operations), it
821 // appears once in every dimension of the scalarMap.
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000822 VectorValueMapT ScalarBlockMap(getVectorWidth());
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000823 ValueMapT VectorBlockMap;
824
825 for (BasicBlock::const_iterator II = BB->begin(), IE = BB->end();
826 II != IE; ++II)
Tobias Grosserfc1153f2012-03-02 11:27:15 +0000827 copyInstruction(II, VectorBlockMap, ScalarBlockMap);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000828}
829
Tobias Grosser75805372011-04-29 06:27:02 +0000830/// Class to generate LLVM-IR that calculates the value of a clast_expr.
831class ClastExpCodeGen {
832 IRBuilder<> &Builder;
Tobias Grosser5e8ffa82012-03-23 12:20:36 +0000833 const CharMapT &IVS;
Tobias Grosser75805372011-04-29 06:27:02 +0000834
Tobias Grosserbb137e32012-01-24 16:42:28 +0000835 Value *codegen(const clast_name *e, Type *Ty);
836 Value *codegen(const clast_term *e, Type *Ty);
837 Value *codegen(const clast_binary *e, Type *Ty);
838 Value *codegen(const clast_reduction *r, Type *Ty);
Tobias Grosser75805372011-04-29 06:27:02 +0000839public:
840
841 // A generator for clast expressions.
842 //
843 // @param B The IRBuilder that defines where the code to calculate the
844 // clast expressions should be inserted.
845 // @param IVMAP A Map that translates strings describing the induction
846 // variables to the Values* that represent these variables
847 // on the LLVM side.
Tobias Grosser5e8ffa82012-03-23 12:20:36 +0000848 ClastExpCodeGen(IRBuilder<> &B, CharMapT &IVMap);
Tobias Grosser75805372011-04-29 06:27:02 +0000849
850 // Generates code to calculate a given clast expression.
851 //
852 // @param e The expression to calculate.
853 // @return The Value that holds the result.
Tobias Grosserbb137e32012-01-24 16:42:28 +0000854 Value *codegen(const clast_expr *e, Type *Ty);
Tobias Grosserbb137e32012-01-24 16:42:28 +0000855};
856
857Value *ClastExpCodeGen::codegen(const clast_name *e, Type *Ty) {
Tobias Grosser5e8ffa82012-03-23 12:20:36 +0000858 CharMapT::const_iterator I = IVS.find(e->name);
Tobias Grosserbb137e32012-01-24 16:42:28 +0000859
Tobias Grosser5e8ffa82012-03-23 12:20:36 +0000860 assert(I != IVS.end() && "Clast name not found");
Tobias Grosserbb137e32012-01-24 16:42:28 +0000861
862 return Builder.CreateSExtOrBitCast(I->second, Ty);
863}
864
865Value *ClastExpCodeGen::codegen(const clast_term *e, Type *Ty) {
866 APInt a = APInt_from_MPZ(e->val);
867
868 Value *ConstOne = ConstantInt::get(Builder.getContext(), a);
869 ConstOne = Builder.CreateSExtOrBitCast(ConstOne, Ty);
870
871 if (!e->var)
872 return ConstOne;
873
874 Value *var = codegen(e->var, Ty);
875 return Builder.CreateMul(ConstOne, var);
876}
877
878Value *ClastExpCodeGen::codegen(const clast_binary *e, Type *Ty) {
879 Value *LHS = codegen(e->LHS, Ty);
880
881 APInt RHS_AP = APInt_from_MPZ(e->RHS);
882
883 Value *RHS = ConstantInt::get(Builder.getContext(), RHS_AP);
884 RHS = Builder.CreateSExtOrBitCast(RHS, Ty);
885
886 switch (e->type) {
887 case clast_bin_mod:
888 return Builder.CreateSRem(LHS, RHS);
889 case clast_bin_fdiv:
890 {
Tobias Grosser9a44b972012-02-16 14:13:19 +0000891 // floord(n,d) ((n < 0) ? (n - d + 1) : n) / d
Tobias Grosser906eafe2012-02-16 09:56:10 +0000892 Value *One = ConstantInt::get(Ty, 1);
893 Value *Zero = ConstantInt::get(Ty, 0);
Tobias Grosser9a44b972012-02-16 14:13:19 +0000894 Value *Sum1 = Builder.CreateSub(LHS, RHS);
895 Value *Sum2 = Builder.CreateAdd(Sum1, One);
896 Value *isNegative = Builder.CreateICmpSLT(LHS, Zero);
897 Value *Dividend = Builder.CreateSelect(isNegative, Sum2, LHS);
898 return Builder.CreateSDiv(Dividend, RHS);
Tobias Grosserbb137e32012-01-24 16:42:28 +0000899 }
900 case clast_bin_cdiv:
901 {
Tobias Grosser9a44b972012-02-16 14:13:19 +0000902 // ceild(n,d) ((n < 0) ? n : (n + d - 1)) / d
903 Value *One = ConstantInt::get(Ty, 1);
Tobias Grosser906eafe2012-02-16 09:56:10 +0000904 Value *Zero = ConstantInt::get(Ty, 0);
Tobias Grosser9a44b972012-02-16 14:13:19 +0000905 Value *Sum1 = Builder.CreateAdd(LHS, RHS);
906 Value *Sum2 = Builder.CreateSub(Sum1, One);
907 Value *isNegative = Builder.CreateICmpSLT(LHS, Zero);
908 Value *Dividend = Builder.CreateSelect(isNegative, LHS, Sum2);
909 return Builder.CreateSDiv(Dividend, RHS);
Tobias Grosserbb137e32012-01-24 16:42:28 +0000910 }
911 case clast_bin_div:
912 return Builder.CreateSDiv(LHS, RHS);
913 };
914
915 llvm_unreachable("Unknown clast binary expression type");
916}
917
918Value *ClastExpCodeGen::codegen(const clast_reduction *r, Type *Ty) {
919 assert(( r->type == clast_red_min
920 || r->type == clast_red_max
921 || r->type == clast_red_sum)
922 && "Clast reduction type not supported");
923 Value *old = codegen(r->elts[0], Ty);
924
925 for (int i=1; i < r->n; ++i) {
926 Value *exprValue = codegen(r->elts[i], Ty);
927
928 switch (r->type) {
929 case clast_red_min:
930 {
931 Value *cmp = Builder.CreateICmpSLT(old, exprValue);
932 old = Builder.CreateSelect(cmp, old, exprValue);
933 break;
934 }
935 case clast_red_max:
936 {
937 Value *cmp = Builder.CreateICmpSGT(old, exprValue);
938 old = Builder.CreateSelect(cmp, old, exprValue);
939 break;
940 }
941 case clast_red_sum:
942 old = Builder.CreateAdd(old, exprValue);
943 break;
Tobias Grosserbb137e32012-01-24 16:42:28 +0000944 }
Tobias Grosser75805372011-04-29 06:27:02 +0000945 }
946
Tobias Grosserbb137e32012-01-24 16:42:28 +0000947 return old;
948}
949
Tobias Grosser5e8ffa82012-03-23 12:20:36 +0000950ClastExpCodeGen::ClastExpCodeGen(IRBuilder<> &B, CharMapT &IVMap)
Tobias Grosserbb137e32012-01-24 16:42:28 +0000951 : Builder(B), IVS(IVMap) {}
952
953Value *ClastExpCodeGen::codegen(const clast_expr *e, Type *Ty) {
954 switch(e->type) {
955 case clast_expr_name:
956 return codegen((const clast_name *)e, Ty);
957 case clast_expr_term:
958 return codegen((const clast_term *)e, Ty);
959 case clast_expr_bin:
960 return codegen((const clast_binary *)e, Ty);
961 case clast_expr_red:
962 return codegen((const clast_reduction *)e, Ty);
963 }
964
965 llvm_unreachable("Unknown clast expression!");
966}
967
Tobias Grosser75805372011-04-29 06:27:02 +0000968class ClastStmtCodeGen {
Tobias Grosserf74a4cd2012-03-23 10:35:18 +0000969public:
970 const std::vector<std::string> &getParallelLoops();
971
972private:
Tobias Grosser75805372011-04-29 06:27:02 +0000973 // The Scop we code generate.
974 Scop *S;
Tobias Grosser0ac92142012-02-14 14:02:27 +0000975 Pass *P;
Tobias Grosser75805372011-04-29 06:27:02 +0000976
977 // The Builder specifies the current location to code generate at.
978 IRBuilder<> &Builder;
979
980 // Map the Values from the old code to their counterparts in the new code.
981 ValueMapT ValueMap;
982
983 // clastVars maps from the textual representation of a clast variable to its
984 // current *Value. clast variables are scheduling variables, original
985 // induction variables or parameters. They are used either in loop bounds or
986 // to define the statement instance that is executed.
987 //
988 // for (s = 0; s < n + 3; ++i)
989 // for (t = s; t < m; ++j)
990 // Stmt(i = s + 3 * m, j = t);
991 //
992 // {s,t,i,j,n,m} is the set of clast variables in this clast.
Tobias Grosser5e8ffa82012-03-23 12:20:36 +0000993 CharMapT ClastVars;
Tobias Grosser75805372011-04-29 06:27:02 +0000994
995 // Codegenerator for clast expressions.
996 ClastExpCodeGen ExpGen;
997
998 // Do we currently generate parallel code?
999 bool parallelCodeGeneration;
1000
1001 std::vector<std::string> parallelLoops;
1002
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001003 void codegen(const clast_assignment *a);
Tobias Grosser75805372011-04-29 06:27:02 +00001004
1005 void codegen(const clast_assignment *a, ScopStmt *Statement,
1006 unsigned Dimension, int vectorDim,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001007 std::vector<ValueMapT> *VectorVMap = 0);
Tobias Grosser75805372011-04-29 06:27:02 +00001008
1009 void codegenSubstitutions(const clast_stmt *Assignment,
1010 ScopStmt *Statement, int vectorDim = 0,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001011 std::vector<ValueMapT> *VectorVMap = 0);
Tobias Grosser75805372011-04-29 06:27:02 +00001012
1013 void codegen(const clast_user_stmt *u, std::vector<Value*> *IVS = NULL,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001014 const char *iterator = NULL, isl_set *scatteringDomain = 0);
Tobias Grosser75805372011-04-29 06:27:02 +00001015
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001016 void codegen(const clast_block *b);
Tobias Grosser75805372011-04-29 06:27:02 +00001017
1018 /// @brief Create a classical sequential loop.
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001019 void codegenForSequential(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +00001020
1021 /// @brief Create OpenMP structure values.
1022 ///
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001023 /// Create a list of values that has to be stored into the OpenMP subfuncition
Tobias Grosser75805372011-04-29 06:27:02 +00001024 /// structure.
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001025 SetVector<Value*> getOMPValues();
Tobias Grosser75805372011-04-29 06:27:02 +00001026
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001027 /// @brief Update the internal structures according to a Value Map.
1028 ///
1029 /// @param VMap A map from old to new values.
1030 /// @param Reverse If true, we assume the update should be reversed.
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001031 void updateWithValueMap(OMPGenerator::ValueToValueMapTy &VMap,
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001032 bool Reverse);
Tobias Grosser75805372011-04-29 06:27:02 +00001033
1034 /// @brief Create an OpenMP parallel for loop.
1035 ///
1036 /// This loop reflects a loop as if it would have been created by an OpenMP
1037 /// statement.
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001038 void codegenForOpenMP(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +00001039
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001040 bool isInnermostLoop(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +00001041
1042 /// @brief Get the number of loop iterations for this loop.
1043 /// @param f The clast for loop to check.
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001044 int getNumberOfIterations(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +00001045
1046 /// @brief Create vector instructions for this loop.
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001047 void codegenForVector(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +00001048
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001049 void codegen(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +00001050
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001051 Value *codegen(const clast_equation *eq);
Tobias Grosser75805372011-04-29 06:27:02 +00001052
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001053 void codegen(const clast_guard *g);
Tobias Grosser75805372011-04-29 06:27:02 +00001054
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001055 void codegen(const clast_stmt *stmt);
Tobias Grosser75805372011-04-29 06:27:02 +00001056
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001057 void addParameters(const CloogNames *names);
Tobias Grosser75805372011-04-29 06:27:02 +00001058
Tobias Grossere9ffea22012-03-15 09:34:48 +00001059 IntegerType *getIntPtrTy();
1060
Tobias Grosser75805372011-04-29 06:27:02 +00001061 public:
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001062 void codegen(const clast_root *r);
Tobias Grosser75805372011-04-29 06:27:02 +00001063
Tobias Grosserd596b372012-03-15 09:34:52 +00001064 ClastStmtCodeGen(Scop *scop, IRBuilder<> &B, Pass *P);
Tobias Grosser75805372011-04-29 06:27:02 +00001065};
1066}
1067
Tobias Grossere9ffea22012-03-15 09:34:48 +00001068IntegerType *ClastStmtCodeGen::getIntPtrTy() {
1069 return P->getAnalysis<TargetData>().getIntPtrType(Builder.getContext());
1070}
1071
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001072const std::vector<std::string> &ClastStmtCodeGen::getParallelLoops() {
1073 return parallelLoops;
1074}
1075
1076void ClastStmtCodeGen::codegen(const clast_assignment *a) {
Tobias Grossere9ffea22012-03-15 09:34:48 +00001077 Value *V= ExpGen.codegen(a->RHS, getIntPtrTy());
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001078 ClastVars[a->LHS] = V;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001079}
1080
Tobias Grosserf00bd962012-04-02 12:26:13 +00001081void ClastStmtCodeGen::codegen(const clast_assignment *A, ScopStmt *Stmt,
1082 unsigned Dim, int VectorDim,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001083 std::vector<ValueMapT> *VectorVMap) {
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001084 const PHINode *PN;
Tobias Grosserf00bd962012-04-02 12:26:13 +00001085 Value *RHS;
1086
1087 assert(!A->LHS && "Statement assignments do not have left hand side");
1088
Tobias Grosserf00bd962012-04-02 12:26:13 +00001089 PN = Stmt->getInductionVariableForDimension(Dim);
Tobias Grosser0905a232012-04-03 12:24:32 +00001090 RHS = ExpGen.codegen(A->RHS, Builder.getInt64Ty());
1091 RHS = Builder.CreateTruncOrBitCast(RHS, PN->getType());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001092
1093 if (VectorVMap)
Tobias Grosserf00bd962012-04-02 12:26:13 +00001094 (*VectorVMap)[VectorDim][PN] = RHS;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001095
Tobias Grosserf00bd962012-04-02 12:26:13 +00001096 ValueMap[PN] = RHS;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001097}
1098
1099void ClastStmtCodeGen::codegenSubstitutions(const clast_stmt *Assignment,
1100 ScopStmt *Statement, int vectorDim,
1101 std::vector<ValueMapT> *VectorVMap) {
1102 int Dimension = 0;
1103
1104 while (Assignment) {
1105 assert(CLAST_STMT_IS_A(Assignment, stmt_ass)
1106 && "Substitions are expected to be assignments");
1107 codegen((const clast_assignment *)Assignment, Statement, Dimension,
1108 vectorDim, VectorVMap);
1109 Assignment = Assignment->next;
1110 Dimension++;
1111 }
1112}
1113
1114void ClastStmtCodeGen::codegen(const clast_user_stmt *u,
1115 std::vector<Value*> *IVS , const char *iterator,
Tobias Grosser14bcbd52012-03-02 11:26:52 +00001116 isl_set *Domain) {
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001117 ScopStmt *Statement = (ScopStmt *)u->statement->usr;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001118
1119 if (u->substitutions)
1120 codegenSubstitutions(u->substitutions, Statement);
1121
Tobias Grosser80998e72012-03-02 11:27:28 +00001122 int VectorDimensions = IVS ? IVS->size() : 1;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001123
Tobias Grosser80998e72012-03-02 11:27:28 +00001124 if (VectorDimensions == 1) {
Tobias Grosser55d52082012-03-02 15:20:39 +00001125 BlockGenerator::generate(Builder, *Statement, ValueMap, P);
Tobias Grosser80998e72012-03-02 11:27:28 +00001126 return;
1127 }
1128
1129 VectorValueMapT VectorMap(VectorDimensions);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001130
1131 if (IVS) {
1132 assert (u->substitutions && "Substitutions expected!");
1133 int i = 0;
1134 for (std::vector<Value*>::iterator II = IVS->begin(), IE = IVS->end();
1135 II != IE; ++II) {
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001136 ClastVars[iterator] = *II;
Tobias Grosser14bcbd52012-03-02 11:26:52 +00001137 codegenSubstitutions(u->substitutions, Statement, i, &VectorMap);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001138 i++;
1139 }
1140 }
1141
Tobias Grosser55d52082012-03-02 15:20:39 +00001142 VectorBlockGenerator::generate(Builder, *Statement, VectorMap, Domain, P);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001143}
1144
1145void ClastStmtCodeGen::codegen(const clast_block *b) {
1146 if (b->body)
1147 codegen(b->body);
1148}
1149
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001150void ClastStmtCodeGen::codegenForSequential(const clast_for *f) {
1151 Value *LowerBound, *UpperBound, *IV, *Stride;
Tobias Grosser0ac92142012-02-14 14:02:27 +00001152 BasicBlock *AfterBB;
Tobias Grossere9ffea22012-03-15 09:34:48 +00001153 Type *IntPtrTy = getIntPtrTy();
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001154
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001155 LowerBound = ExpGen.codegen(f->LB, IntPtrTy);
1156 UpperBound = ExpGen.codegen(f->UB, IntPtrTy);
1157 Stride = Builder.getInt(APInt_from_MPZ(f->stride));
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001158
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001159 IV = createLoop(LowerBound, UpperBound, Stride, &Builder, P, &AfterBB);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001160
1161 // Add loop iv to symbols.
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001162 ClastVars[f->iterator] = IV;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001163
1164 if (f->body)
1165 codegen(f->body);
1166
1167 // Loop is finished, so remove its iv from the live symbols.
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001168 ClastVars.erase(f->iterator);
Tobias Grosser0ac92142012-02-14 14:02:27 +00001169 Builder.SetInsertPoint(AfterBB->begin());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001170}
1171
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001172SetVector<Value*> ClastStmtCodeGen::getOMPValues() {
1173 SetVector<Value*> Values;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001174
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001175 // The clast variables
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001176 for (CharMapT::iterator I = ClastVars.begin(), E = ClastVars.end();
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001177 I != E; I++)
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001178 Values.insert(I->second);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001179
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001180 // The memory reference base addresses
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001181 for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI) {
1182 ScopStmt *Stmt = *SI;
1183 for (SmallVector<MemoryAccess*, 8>::iterator I = Stmt->memacc_begin(),
1184 E = Stmt->memacc_end(); I != E; ++I) {
1185 Value *BaseAddr = const_cast<Value*>((*I)->getBaseAddr());
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001186 Values.insert((BaseAddr));
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001187 }
1188 }
1189
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001190 return Values;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001191}
1192
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001193void ClastStmtCodeGen::updateWithValueMap(OMPGenerator::ValueToValueMapTy &VMap,
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001194 bool Reverse) {
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001195 std::set<Value*> Inserted;
1196
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001197 if (Reverse) {
1198 OMPGenerator::ValueToValueMapTy ReverseMap;
1199
1200 for (std::map<Value*, Value*>::iterator I = VMap.begin(), E = VMap.end();
1201 I != E; ++I)
1202 ReverseMap.insert(std::make_pair(I->second, I->first));
1203
1204 for (CharMapT::iterator I = ClastVars.begin(), E = ClastVars.end();
1205 I != E; I++) {
1206 ClastVars[I->first] = ReverseMap[I->second];
1207 Inserted.insert(I->second);
1208 }
1209
1210 /// FIXME: At the moment we do not reverse the update of the ValueMap.
1211 /// This is incomplet, but the failure should be obvious, such that
1212 /// we can fix this later.
1213 return;
1214 }
1215
1216 for (CharMapT::iterator I = ClastVars.begin(), E = ClastVars.end();
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001217 I != E; I++) {
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001218 ClastVars[I->first] = VMap[I->second];
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001219 Inserted.insert(I->second);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001220 }
1221
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001222 for (std::map<Value*, Value*>::iterator I = VMap.begin(), E = VMap.end();
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001223 I != E; ++I) {
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001224 if (Inserted.count(I->first))
1225 continue;
1226
1227 ValueMap[I->first] = I->second;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001228 }
1229}
1230
Tobias Grosser900893d2012-03-29 13:10:26 +00001231static void clearDomtree(Function *F, DominatorTree &DT) {
1232 DomTreeNode *N = DT.getNode(&F->getEntryBlock());
1233 std::vector<BasicBlock*> Nodes;
1234 for (po_iterator<DomTreeNode*> I = po_begin(N), E = po_end(N); I != E; ++I)
1235 Nodes.push_back(I->getBlock());
1236
1237 for (std::vector<BasicBlock*>::iterator I = Nodes.begin(), E = Nodes.end();
1238 I != E; ++I)
1239 DT.eraseNode(*I);
1240}
1241
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001242void ClastStmtCodeGen::codegenForOpenMP(const clast_for *For) {
Tobias Grosserebf30082012-03-23 12:20:32 +00001243 Value *Stride, *LB, *UB, *IV;
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001244 BasicBlock::iterator LoopBody;
1245 IntegerType *IntPtrTy = getIntPtrTy();
1246 SetVector<Value*> Values;
1247 OMPGenerator::ValueToValueMapTy VMap;
1248 OMPGenerator OMPGen(Builder, P);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001249
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001250 Stride = Builder.getInt(APInt_from_MPZ(For->stride));
1251 Stride = Builder.CreateSExtOrBitCast(Stride, IntPtrTy);
Tobias Grosserebf30082012-03-23 12:20:32 +00001252 LB = ExpGen.codegen(For->LB, IntPtrTy);
1253 UB = ExpGen.codegen(For->UB, IntPtrTy);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001254
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001255 Values = getOMPValues();
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001256
Tobias Grosserebf30082012-03-23 12:20:32 +00001257 IV = OMPGen.createParallelLoop(LB, UB, Stride, Values, VMap, &LoopBody);
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001258 BasicBlock::iterator AfterLoop = Builder.GetInsertPoint();
1259 Builder.SetInsertPoint(LoopBody);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001260
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001261 updateWithValueMap(VMap, /* reverse */ false);
1262 ClastVars[For->iterator] = IV;
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001263
1264 if (For->body)
1265 codegen(For->body);
1266
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001267 ClastVars.erase(For->iterator);
1268 updateWithValueMap(VMap, /* reverse */ true);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001269
Tobias Grosser900893d2012-03-29 13:10:26 +00001270 clearDomtree((*LoopBody).getParent()->getParent(),
1271 P->getAnalysis<DominatorTree>());
1272
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001273 Builder.SetInsertPoint(AfterLoop);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001274}
1275
1276bool ClastStmtCodeGen::isInnermostLoop(const clast_for *f) {
1277 const clast_stmt *stmt = f->body;
1278
1279 while (stmt) {
1280 if (!CLAST_STMT_IS_A(stmt, stmt_user))
1281 return false;
1282
1283 stmt = stmt->next;
1284 }
1285
1286 return true;
1287}
1288
1289int ClastStmtCodeGen::getNumberOfIterations(const clast_for *f) {
1290 isl_set *loopDomain = isl_set_copy(isl_set_from_cloog_domain(f->domain));
1291 isl_set *tmp = isl_set_copy(loopDomain);
1292
1293 // Calculate a map similar to the identity map, but with the last input
1294 // and output dimension not related.
1295 // [i0, i1, i2, i3] -> [i0, i1, i2, o0]
1296 isl_space *Space = isl_set_get_space(loopDomain);
1297 Space = isl_space_drop_outputs(Space,
1298 isl_set_dim(loopDomain, isl_dim_set) - 2, 1);
1299 Space = isl_space_map_from_set(Space);
1300 isl_map *identity = isl_map_identity(Space);
1301 identity = isl_map_add_dims(identity, isl_dim_in, 1);
1302 identity = isl_map_add_dims(identity, isl_dim_out, 1);
1303
1304 isl_map *map = isl_map_from_domain_and_range(tmp, loopDomain);
1305 map = isl_map_intersect(map, identity);
1306
1307 isl_map *lexmax = isl_map_lexmax(isl_map_copy(map));
1308 isl_map *lexmin = isl_map_lexmin(map);
1309 isl_map *sub = isl_map_sum(lexmax, isl_map_neg(lexmin));
1310
1311 isl_set *elements = isl_map_range(sub);
1312
1313 if (!isl_set_is_singleton(elements)) {
1314 isl_set_free(elements);
1315 return -1;
1316 }
1317
1318 isl_point *p = isl_set_sample_point(elements);
1319
1320 isl_int v;
1321 isl_int_init(v);
1322 isl_point_get_coordinate(p, isl_dim_set, isl_set_n_dim(loopDomain) - 1, &v);
1323 int numberIterations = isl_int_get_si(v);
1324 isl_int_clear(v);
1325 isl_point_free(p);
1326
1327 return (numberIterations) / isl_int_get_si(f->stride) + 1;
1328}
1329
Tobias Grosser2da263e2012-03-15 09:34:55 +00001330void ClastStmtCodeGen::codegenForVector(const clast_for *F) {
1331 DEBUG(dbgs() << "Vectorizing loop '" << F->iterator << "'\n";);
1332 int VectorWidth = getNumberOfIterations(F);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001333
Tobias Grosser2da263e2012-03-15 09:34:55 +00001334 Value *LB = ExpGen.codegen(F->LB, getIntPtrTy());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001335
Tobias Grosser2da263e2012-03-15 09:34:55 +00001336 APInt Stride = APInt_from_MPZ(F->stride);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001337 IntegerType *LoopIVType = dyn_cast<IntegerType>(LB->getType());
1338 Stride = Stride.zext(LoopIVType->getBitWidth());
1339 Value *StrideValue = ConstantInt::get(LoopIVType, Stride);
1340
Tobias Grosser2da263e2012-03-15 09:34:55 +00001341 std::vector<Value*> IVS(VectorWidth);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001342 IVS[0] = LB;
1343
Tobias Grosser2da263e2012-03-15 09:34:55 +00001344 for (int i = 1; i < VectorWidth; i++)
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001345 IVS[i] = Builder.CreateAdd(IVS[i-1], StrideValue, "p_vector_iv");
1346
Tobias Grosser00d898d2012-03-15 09:34:58 +00001347 isl_set *Domain = isl_set_from_cloog_domain(F->domain);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001348
1349 // Add loop iv to symbols.
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001350 ClastVars[F->iterator] = LB;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001351
Tobias Grosser2da263e2012-03-15 09:34:55 +00001352 const clast_stmt *Stmt = F->body;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001353
Tobias Grosser2da263e2012-03-15 09:34:55 +00001354 while (Stmt) {
Tobias Grosser00d898d2012-03-15 09:34:58 +00001355 codegen((const clast_user_stmt *)Stmt, &IVS, F->iterator,
1356 isl_set_copy(Domain));
Tobias Grosser2da263e2012-03-15 09:34:55 +00001357 Stmt = Stmt->next;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001358 }
1359
1360 // Loop is finished, so remove its iv from the live symbols.
Tobias Grosser00d898d2012-03-15 09:34:58 +00001361 isl_set_free(Domain);
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001362 ClastVars.erase(F->iterator);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001363}
1364
1365void ClastStmtCodeGen::codegen(const clast_for *f) {
Tobias Grosserd596b372012-03-15 09:34:52 +00001366 if ((Vector || OpenMP) && P->getAnalysis<Dependences>().isParallelFor(f)) {
Tobias Grosserce3f5372012-03-02 11:26:42 +00001367 if (Vector && isInnermostLoop(f) && (-1 != getNumberOfIterations(f))
1368 && (getNumberOfIterations(f) <= 16)) {
1369 codegenForVector(f);
1370 return;
1371 }
1372
1373 if (OpenMP && !parallelCodeGeneration) {
1374 parallelCodeGeneration = true;
1375 parallelLoops.push_back(f->iterator);
1376 codegenForOpenMP(f);
1377 parallelCodeGeneration = false;
1378 return;
1379 }
1380 }
1381
1382 codegenForSequential(f);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001383}
1384
1385Value *ClastStmtCodeGen::codegen(const clast_equation *eq) {
Tobias Grossere9ffea22012-03-15 09:34:48 +00001386 Value *LHS = ExpGen.codegen(eq->LHS, getIntPtrTy());
1387 Value *RHS = ExpGen.codegen(eq->RHS, getIntPtrTy());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001388 CmpInst::Predicate P;
1389
1390 if (eq->sign == 0)
1391 P = ICmpInst::ICMP_EQ;
1392 else if (eq->sign > 0)
1393 P = ICmpInst::ICMP_SGE;
1394 else
1395 P = ICmpInst::ICMP_SLE;
1396
1397 return Builder.CreateICmp(P, LHS, RHS);
1398}
1399
1400void ClastStmtCodeGen::codegen(const clast_guard *g) {
1401 Function *F = Builder.GetInsertBlock()->getParent();
1402 LLVMContext &Context = F->getContext();
Tobias Grosser0ac92142012-02-14 14:02:27 +00001403
1404 BasicBlock *CondBB = SplitBlock(Builder.GetInsertBlock(),
1405 Builder.GetInsertPoint(), P);
1406 CondBB->setName("polly.cond");
1407 BasicBlock *MergeBB = SplitBlock(CondBB, CondBB->begin(), P);
1408 MergeBB->setName("polly.merge");
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001409 BasicBlock *ThenBB = BasicBlock::Create(Context, "polly.then", F);
Tobias Grosser0ac92142012-02-14 14:02:27 +00001410
Tobias Grosserd596b372012-03-15 09:34:52 +00001411 DominatorTree &DT = P->getAnalysis<DominatorTree>();
1412 DT.addNewBlock(ThenBB, CondBB);
1413 DT.changeImmediateDominator(MergeBB, CondBB);
Tobias Grosser0ac92142012-02-14 14:02:27 +00001414
1415 CondBB->getTerminator()->eraseFromParent();
1416
1417 Builder.SetInsertPoint(CondBB);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001418
1419 Value *Predicate = codegen(&(g->eq[0]));
1420
1421 for (int i = 1; i < g->n; ++i) {
1422 Value *TmpPredicate = codegen(&(g->eq[i]));
1423 Predicate = Builder.CreateAnd(Predicate, TmpPredicate);
1424 }
1425
1426 Builder.CreateCondBr(Predicate, ThenBB, MergeBB);
1427 Builder.SetInsertPoint(ThenBB);
Tobias Grosser0ac92142012-02-14 14:02:27 +00001428 Builder.CreateBr(MergeBB);
1429 Builder.SetInsertPoint(ThenBB->begin());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001430
1431 codegen(g->then);
Tobias Grosser62a3c962012-02-16 09:56:21 +00001432
1433 Builder.SetInsertPoint(MergeBB->begin());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001434}
1435
1436void ClastStmtCodeGen::codegen(const clast_stmt *stmt) {
1437 if (CLAST_STMT_IS_A(stmt, stmt_root))
1438 assert(false && "No second root statement expected");
1439 else if (CLAST_STMT_IS_A(stmt, stmt_ass))
1440 codegen((const clast_assignment *)stmt);
1441 else if (CLAST_STMT_IS_A(stmt, stmt_user))
1442 codegen((const clast_user_stmt *)stmt);
1443 else if (CLAST_STMT_IS_A(stmt, stmt_block))
1444 codegen((const clast_block *)stmt);
1445 else if (CLAST_STMT_IS_A(stmt, stmt_for))
1446 codegen((const clast_for *)stmt);
1447 else if (CLAST_STMT_IS_A(stmt, stmt_guard))
1448 codegen((const clast_guard *)stmt);
1449
1450 if (stmt->next)
1451 codegen(stmt->next);
1452}
1453
1454void ClastStmtCodeGen::addParameters(const CloogNames *names) {
Tobias Grosserd596b372012-03-15 09:34:52 +00001455 SCEVExpander Rewriter(P->getAnalysis<ScalarEvolution>(), "polly");
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001456
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001457 int i = 0;
1458 for (Scop::param_iterator PI = S->param_begin(), PE = S->param_end();
1459 PI != PE; ++PI) {
1460 assert(i < names->nb_parameters && "Not enough parameter names");
1461
1462 const SCEV *Param = *PI;
1463 Type *Ty = Param->getType();
1464
1465 Instruction *insertLocation = --(Builder.GetInsertBlock()->end());
1466 Value *V = Rewriter.expandCodeFor(Param, Ty, insertLocation);
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001467 ClastVars[names->parameters[i]] = V;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001468
1469 ++i;
1470 }
1471}
1472
1473void ClastStmtCodeGen::codegen(const clast_root *r) {
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001474 addParameters(r->names);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001475
1476 parallelCodeGeneration = false;
1477
1478 const clast_stmt *stmt = (const clast_stmt*) r;
1479 if (stmt->next)
1480 codegen(stmt->next);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001481}
1482
Tobias Grosserd596b372012-03-15 09:34:52 +00001483ClastStmtCodeGen::ClastStmtCodeGen(Scop *scop, IRBuilder<> &B, Pass *P) :
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001484 S(scop), P(P), Builder(B), ExpGen(Builder, ClastVars) {}
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001485
Tobias Grosser75805372011-04-29 06:27:02 +00001486namespace {
1487class CodeGeneration : public ScopPass {
1488 Region *region;
1489 Scop *S;
1490 DominatorTree *DT;
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001491 RegionInfo *RI;
Tobias Grosser75805372011-04-29 06:27:02 +00001492
1493 std::vector<std::string> parallelLoops;
1494
1495 public:
1496 static char ID;
1497
1498 CodeGeneration() : ScopPass(ID) {}
1499
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001500 // Split the entry edge of the region and generate a new basic block on this
1501 // edge. This function also updates ScopInfo and RegionInfo.
1502 //
1503 // @param region The region where the entry edge will be splitted.
1504 BasicBlock *splitEdgeAdvanced(Region *region) {
1505 BasicBlock *newBlock;
1506 BasicBlock *splitBlock;
1507
1508 newBlock = SplitEdge(region->getEnteringBlock(), region->getEntry(), this);
1509
1510 if (DT->dominates(region->getEntry(), newBlock)) {
Tobias Grossercb47dfe2012-02-15 09:58:50 +00001511 BasicBlock *OldBlock = region->getEntry();
1512 std::string OldName = OldBlock->getName();
1513
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001514 // Update ScopInfo.
1515 for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI)
Tobias Grosserf12cea42012-02-15 09:58:53 +00001516 if ((*SI)->getBasicBlock() == OldBlock) {
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001517 (*SI)->setBasicBlock(newBlock);
1518 break;
1519 }
1520
1521 // Update RegionInfo.
Tobias Grossercb47dfe2012-02-15 09:58:50 +00001522 splitBlock = OldBlock;
1523 OldBlock->setName("polly.split");
1524 newBlock->setName(OldName);
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001525 region->replaceEntry(newBlock);
Tobias Grosser7a16c892011-05-14 19:01:55 +00001526 RI->setRegionFor(newBlock, region);
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001527 } else {
1528 RI->setRegionFor(newBlock, region->getParent());
1529 splitBlock = newBlock;
1530 }
1531
1532 return splitBlock;
1533 }
1534
1535 // Create a split block that branches either to the old code or to a new basic
1536 // block where the new code can be inserted.
1537 //
Tobias Grosserbd608a82012-02-12 12:09:41 +00001538 // @param Builder A builder that will be set to point to a basic block, where
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001539 // the new code can be generated.
1540 // @return The split basic block.
Tobias Grosserbd608a82012-02-12 12:09:41 +00001541 BasicBlock *addSplitAndStartBlock(IRBuilder<> *Builder) {
1542 BasicBlock *StartBlock, *SplitBlock;
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001543
Tobias Grosserbd608a82012-02-12 12:09:41 +00001544 SplitBlock = splitEdgeAdvanced(region);
1545 SplitBlock->setName("polly.split_new_and_old");
1546 Function *F = SplitBlock->getParent();
1547 StartBlock = BasicBlock::Create(F->getContext(), "polly.start", F);
1548 SplitBlock->getTerminator()->eraseFromParent();
1549 Builder->SetInsertPoint(SplitBlock);
1550 Builder->CreateCondBr(Builder->getTrue(), StartBlock, region->getEntry());
1551 DT->addNewBlock(StartBlock, SplitBlock);
1552 Builder->SetInsertPoint(StartBlock);
1553 return SplitBlock;
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001554 }
1555
1556 // Merge the control flow of the newly generated code with the existing code.
1557 //
Tobias Grosserbd608a82012-02-12 12:09:41 +00001558 // @param SplitBlock The basic block where the control flow was split between
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001559 // old and new version of the Scop.
Tobias Grosserbd608a82012-02-12 12:09:41 +00001560 // @param Builder An IRBuilder that points to the last instruction of the
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001561 // newly generated code.
Tobias Grosserbd608a82012-02-12 12:09:41 +00001562 void mergeControlFlow(BasicBlock *SplitBlock, IRBuilder<> *Builder) {
1563 BasicBlock *MergeBlock;
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001564 Region *R = region;
1565
1566 if (R->getExit()->getSinglePredecessor())
1567 // No splitEdge required. A block with a single predecessor cannot have
1568 // PHI nodes that would complicate life.
Tobias Grosserbd608a82012-02-12 12:09:41 +00001569 MergeBlock = R->getExit();
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001570 else {
Tobias Grosserbd608a82012-02-12 12:09:41 +00001571 MergeBlock = SplitEdge(R->getExitingBlock(), R->getExit(), this);
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001572 // SplitEdge will never split R->getExit(), as R->getExit() has more than
1573 // one predecessor. Hence, mergeBlock is always a newly generated block.
Tobias Grosserbd608a82012-02-12 12:09:41 +00001574 R->replaceExit(MergeBlock);
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001575 }
1576
Tobias Grosserbd608a82012-02-12 12:09:41 +00001577 Builder->CreateBr(MergeBlock);
Tobias Grosser8518bbe2012-02-12 12:09:46 +00001578 MergeBlock->setName("polly.merge_new_and_old");
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001579
Tobias Grosserbd608a82012-02-12 12:09:41 +00001580 if (DT->dominates(SplitBlock, MergeBlock))
1581 DT->changeImmediateDominator(MergeBlock, SplitBlock);
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001582 }
1583
Tobias Grosser75805372011-04-29 06:27:02 +00001584 bool runOnScop(Scop &scop) {
1585 S = &scop;
1586 region = &S->getRegion();
Tobias Grosser75805372011-04-29 06:27:02 +00001587 DT = &getAnalysis<DominatorTree>();
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001588 RI = &getAnalysis<RegionInfo>();
Tobias Grosser75805372011-04-29 06:27:02 +00001589
1590 parallelLoops.clear();
1591
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001592 assert(region->isSimple() && "Only simple regions are supported");
Tobias Grosser76d7c522011-05-14 19:01:37 +00001593
Tobias Grosser5772e652012-02-01 14:23:33 +00001594 // In the CFG the optimized code of the SCoP is generated next to the
1595 // original code. Both the new and the original version of the code remain
1596 // in the CFG. A branch statement decides which version is executed.
1597 // For now, we always execute the new version (the old one is dead code
1598 // eliminated by the cleanup passes). In the future we may decide to execute
1599 // the new version only if certain run time checks succeed. This will be
1600 // useful to support constructs for which we cannot prove all assumptions at
1601 // compile time.
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001602 //
1603 // Before transformation:
1604 //
1605 // bb0
1606 // |
1607 // orig_scop
1608 // |
1609 // bb1
1610 //
1611 // After transformation:
1612 // bb0
1613 // |
1614 // polly.splitBlock
Tobias Grosser2bd3af12011-08-01 22:39:00 +00001615 // / \.
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001616 // | startBlock
1617 // | |
1618 // orig_scop new_scop
1619 // \ /
1620 // \ /
1621 // bb1 (joinBlock)
1622 IRBuilder<> builder(region->getEntry());
Tobias Grosser75805372011-04-29 06:27:02 +00001623
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001624 // The builder will be set to startBlock.
1625 BasicBlock *splitBlock = addSplitAndStartBlock(&builder);
Tobias Grosser0ac92142012-02-14 14:02:27 +00001626 BasicBlock *StartBlock = builder.GetInsertBlock();
Tobias Grosser75805372011-04-29 06:27:02 +00001627
Tobias Grosser0ac92142012-02-14 14:02:27 +00001628 mergeControlFlow(splitBlock, &builder);
1629 builder.SetInsertPoint(StartBlock->begin());
1630
Tobias Grosserd596b372012-03-15 09:34:52 +00001631 ClastStmtCodeGen CodeGen(S, builder, this);
Tobias Grosser3fdecae2011-05-14 19:02:39 +00001632 CloogInfo &C = getAnalysis<CloogInfo>();
1633 CodeGen.codegen(C.getClast());
Tobias Grosser75805372011-04-29 06:27:02 +00001634
Tobias Grosser75805372011-04-29 06:27:02 +00001635 parallelLoops.insert(parallelLoops.begin(),
1636 CodeGen.getParallelLoops().begin(),
1637 CodeGen.getParallelLoops().end());
1638
Tobias Grosserabb6dcd2011-05-14 19:02:34 +00001639 return true;
Tobias Grosser75805372011-04-29 06:27:02 +00001640 }
1641
1642 virtual void printScop(raw_ostream &OS) const {
1643 for (std::vector<std::string>::const_iterator PI = parallelLoops.begin(),
1644 PE = parallelLoops.end(); PI != PE; ++PI)
1645 OS << "Parallel loop with iterator '" << *PI << "' generated\n";
1646 }
1647
1648 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
1649 AU.addRequired<CloogInfo>();
1650 AU.addRequired<Dependences>();
1651 AU.addRequired<DominatorTree>();
Tobias Grosser75805372011-04-29 06:27:02 +00001652 AU.addRequired<RegionInfo>();
Tobias Grosser73600b82011-10-08 00:30:40 +00001653 AU.addRequired<ScalarEvolution>();
Tobias Grosser75805372011-04-29 06:27:02 +00001654 AU.addRequired<ScopDetection>();
1655 AU.addRequired<ScopInfo>();
1656 AU.addRequired<TargetData>();
1657
1658 AU.addPreserved<CloogInfo>();
1659 AU.addPreserved<Dependences>();
Tobias Grosser5d6eb862011-05-14 19:02:45 +00001660
Tobias Grosser4e3f9a42011-05-23 15:23:36 +00001661 // FIXME: We do not create LoopInfo for the newly generated loops.
Tobias Grosser75805372011-04-29 06:27:02 +00001662 AU.addPreserved<LoopInfo>();
1663 AU.addPreserved<DominatorTree>();
Tobias Grosser75805372011-04-29 06:27:02 +00001664 AU.addPreserved<ScopDetection>();
1665 AU.addPreserved<ScalarEvolution>();
Tobias Grosser5d6eb862011-05-14 19:02:45 +00001666
Tobias Grosser4e3f9a42011-05-23 15:23:36 +00001667 // FIXME: We do not yet add regions for the newly generated code to the
1668 // region tree.
Tobias Grosser75805372011-04-29 06:27:02 +00001669 AU.addPreserved<RegionInfo>();
1670 AU.addPreserved<TempScopInfo>();
1671 AU.addPreserved<ScopInfo>();
1672 AU.addPreservedID(IndependentBlocksID);
1673 }
1674};
1675}
1676
1677char CodeGeneration::ID = 1;
1678
Tobias Grosser73600b82011-10-08 00:30:40 +00001679INITIALIZE_PASS_BEGIN(CodeGeneration, "polly-codegen",
Tobias Grosser3c2efba2012-03-06 07:38:57 +00001680 "Polly - Create LLVM-IR from SCoPs", false, false)
Tobias Grosser73600b82011-10-08 00:30:40 +00001681INITIALIZE_PASS_DEPENDENCY(CloogInfo)
1682INITIALIZE_PASS_DEPENDENCY(Dependences)
1683INITIALIZE_PASS_DEPENDENCY(DominatorTree)
1684INITIALIZE_PASS_DEPENDENCY(RegionInfo)
1685INITIALIZE_PASS_DEPENDENCY(ScalarEvolution)
1686INITIALIZE_PASS_DEPENDENCY(ScopDetection)
1687INITIALIZE_PASS_DEPENDENCY(TargetData)
1688INITIALIZE_PASS_END(CodeGeneration, "polly-codegen",
Tobias Grosser3c2efba2012-03-06 07:38:57 +00001689 "Polly - Create LLVM-IR from SCoPs", false, false)
Tobias Grosser75805372011-04-29 06:27:02 +00001690
Tobias Grosser7ffe4e82011-11-17 12:56:10 +00001691Pass *polly::createCodeGenerationPass() {
Tobias Grosser75805372011-04-29 06:27:02 +00001692 return new CodeGeneration();
1693}