blob: 69f27c007585f5fd31ec11a4382f468d0a7759e2 [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,
243 Value *BaseAddress, const Value *OldOperand,
Tobias Grosserd6adda32012-03-23 08:21:22 +0000244 ValueMapT &BBMap, 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) {
286 const Instruction *Inst = dyn_cast<Instruction>(Old);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000287
Tobias Grosser55d52082012-03-02 15:20:39 +0000288 if (!Inst)
289 return const_cast<Value*>(Old);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000290
Tobias Grosser8367e0c2012-03-02 15:20:31 +0000291 // OldOperand was redefined outside of this BasicBlock.
Tobias Grosser55d52082012-03-02 15:20:39 +0000292 if (GlobalMap.count(Old)) {
293 Value *New = GlobalMap[Old];
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000294
Tobias Grosser55d52082012-03-02 15:20:39 +0000295 if (Old->getType()->getScalarSizeInBits()
296 < New->getType()->getScalarSizeInBits())
297 New = Builder.CreateTruncOrBitCast(New, Old->getType());
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000298
Tobias Grosser55d52082012-03-02 15:20:39 +0000299 return New;
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000300 }
301
Tobias Grosser8367e0c2012-03-02 15:20:31 +0000302 // OldOperand was recalculated within this BasicBlock.
Tobias Grosser55d52082012-03-02 15:20:39 +0000303 if (BBMap.count(Old)) {
304 return BBMap[Old];
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000305 }
306
Tobias Grosser8367e0c2012-03-02 15:20:31 +0000307 // OldOperand is SCoP invariant.
Tobias Grosser55d52082012-03-02 15:20:39 +0000308 if (!Statement.getParent()->getRegion().contains(Inst->getParent()))
309 return const_cast<Value*>(Old);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000310
Tobias Grosser8367e0c2012-03-02 15:20:31 +0000311 // We could not find any valid new operand.
312 return NULL;
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000313}
314
Tobias Grosserdf382372012-03-02 15:20:35 +0000315void BlockGenerator::copyInstScalar(const Instruction *Inst, ValueMapT &BBMap,
316 ValueMapT &GlobalMap) {
Tobias Grosser80998e72012-03-02 11:27:28 +0000317 Instruction *NewInst = Inst->clone();
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000318
Tobias Grosser80998e72012-03-02 11:27:28 +0000319 // Replace old operands with the new ones.
320 for (Instruction::const_op_iterator OI = Inst->op_begin(),
321 OE = Inst->op_end(); OI != OE; ++OI) {
322 Value *OldOperand = *OI;
Tobias Grosser55d52082012-03-02 15:20:39 +0000323 Value *NewOperand = getNewValue(OldOperand, BBMap, GlobalMap);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000324
Tobias Grosser80998e72012-03-02 11:27:28 +0000325 if (!NewOperand) {
326 assert(!isa<StoreInst>(NewInst)
327 && "Store instructions are always needed!");
328 delete NewInst;
329 return;
330 }
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000331
Tobias Grosser80998e72012-03-02 11:27:28 +0000332 NewInst->replaceUsesOfWith(OldOperand, NewOperand);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000333 }
334
Tobias Grosser80998e72012-03-02 11:27:28 +0000335 Builder.Insert(NewInst);
336 BBMap[Inst] = NewInst;
337
338 if (!NewInst->getType()->isVoidTy())
339 NewInst->setName("p_" + Inst->getName());
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000340}
341
Tobias Grosserd6adda32012-03-23 08:21:22 +0000342std::vector<Value*> BlockGenerator::getMemoryAccessIndex(
343 __isl_keep isl_map *AccessRelation, Value *BaseAddress,
344 ValueMapT &BBMap, ValueMapT &GlobalMap) {
345
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000346 assert((isl_map_dim(AccessRelation, isl_dim_out) == 1)
347 && "Only single dimensional access functions supported");
348
Tobias Grosserd6adda32012-03-23 08:21:22 +0000349 std::vector<Value *> IVS;
350 for (unsigned i = 0; i < Statement.getNumIterators(); ++i) {
351 const Value *OriginalIV = Statement.getInductionVariableForDimension(i);
352 Value *NewIV = getNewValue(OriginalIV, BBMap, GlobalMap);
353 IVS.push_back(NewIV);
354 }
355
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000356 isl_pw_aff *PwAff = isl_map_dim_max(isl_map_copy(AccessRelation), 0);
Tobias Grosserd6adda32012-03-23 08:21:22 +0000357 IslGenerator IslGen(Builder, IVS);
Tobias Grosser642c4112012-03-02 11:27:25 +0000358 Value *OffsetValue = IslGen.generateIslPwAff(PwAff);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000359
Tobias Grosserd6adda32012-03-23 08:21:22 +0000360 Type *Ty = Builder.getInt64Ty();
361 OffsetValue = Builder.CreateIntCast(OffsetValue, Ty, true);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000362
363 std::vector<Value*> IndexArray;
Tobias Grosserd6adda32012-03-23 08:21:22 +0000364 Value *NullValue = Constant::getNullValue(Ty);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000365 IndexArray.push_back(NullValue);
366 IndexArray.push_back(OffsetValue);
367 return IndexArray;
368}
369
370Value *BlockGenerator::getNewAccessOperand(
371 __isl_keep isl_map *NewAccessRelation, Value *BaseAddress, const Value
Tobias Grosserd6adda32012-03-23 08:21:22 +0000372 *OldOperand, ValueMapT &BBMap, ValueMapT &GlobalMap) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000373 std::vector<Value*> IndexArray = getMemoryAccessIndex(NewAccessRelation,
Tobias Grosserd6adda32012-03-23 08:21:22 +0000374 BaseAddress,
375 BBMap, GlobalMap);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000376 Value *NewOperand = Builder.CreateGEP(BaseAddress, IndexArray,
377 "p_newarrayidx_");
378 return NewOperand;
379}
380
381Value *BlockGenerator::generateLocationAccessed(const Instruction *Inst,
382 const Value *Pointer,
Tobias Grosserdf382372012-03-02 15:20:35 +0000383 ValueMapT &BBMap,
384 ValueMapT &GlobalMap) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000385 MemoryAccess &Access = Statement.getAccessFor(Inst);
386 isl_map *CurrentAccessRelation = Access.getAccessRelation();
387 isl_map *NewAccessRelation = Access.getNewAccessRelation();
388
389 assert(isl_map_has_equal_space(CurrentAccessRelation, NewAccessRelation)
390 && "Current and new access function use different spaces");
391
392 Value *NewPointer;
393
394 if (!NewAccessRelation) {
Tobias Grosser55d52082012-03-02 15:20:39 +0000395 NewPointer = getNewValue(Pointer, BBMap, GlobalMap);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000396 } else {
397 Value *BaseAddress = const_cast<Value*>(Access.getBaseAddr());
398 NewPointer = getNewAccessOperand(NewAccessRelation, BaseAddress, Pointer,
Tobias Grosserd6adda32012-03-23 08:21:22 +0000399 BBMap, GlobalMap);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000400 }
401
402 isl_map_free(CurrentAccessRelation);
403 isl_map_free(NewAccessRelation);
404 return NewPointer;
405}
406
407Value *BlockGenerator::generateScalarLoad(const LoadInst *Load,
Tobias Grosserdf382372012-03-02 15:20:35 +0000408 ValueMapT &BBMap,
409 ValueMapT &GlobalMap) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000410 const Value *Pointer = Load->getPointerOperand();
411 const Instruction *Inst = dyn_cast<Instruction>(Load);
Tobias Grosserdf382372012-03-02 15:20:35 +0000412 Value *NewPointer = generateLocationAccessed(Inst, Pointer, BBMap, GlobalMap);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000413 Value *ScalarLoad = Builder.CreateLoad(NewPointer,
414 Load->getName() + "_p_scalar_");
415 return ScalarLoad;
416}
417
Tobias Grosserd6adda32012-03-23 08:21:22 +0000418Value *BlockGenerator::generateScalarStore(const StoreInst *Store,
419 ValueMapT &BBMap,
420 ValueMapT &GlobalMap) {
421 const Value *Pointer = Store->getPointerOperand();
422 Value *NewPointer = generateLocationAccessed(Store, Pointer, BBMap,
423 GlobalMap);
424 Value *ValueOperand = getNewValue(Store->getValueOperand(), BBMap, GlobalMap);
425
426 return Builder.CreateStore(ValueOperand, NewPointer);
427}
428
Tobias Grosser80998e72012-03-02 11:27:28 +0000429void BlockGenerator::copyInstruction(const Instruction *Inst,
Tobias Grosserdf382372012-03-02 15:20:35 +0000430 ValueMapT &BBMap, ValueMapT &GlobalMap) {
Tobias Grosser80998e72012-03-02 11:27:28 +0000431 // Terminator instructions control the control flow. They are explicitly
432 // expressed in the clast and do not need to be copied.
433 if (Inst->isTerminator())
434 return;
435
436 if (const LoadInst *Load = dyn_cast<LoadInst>(Inst)) {
Tobias Grosserdf382372012-03-02 15:20:35 +0000437 BBMap[Load] = generateScalarLoad(Load, BBMap, GlobalMap);
Tobias Grosser80998e72012-03-02 11:27:28 +0000438 return;
439 }
440
Tobias Grosserd6adda32012-03-23 08:21:22 +0000441 if (const StoreInst *Store = dyn_cast<StoreInst>(Inst)) {
442 BBMap[Store] = generateScalarStore(Store, BBMap, GlobalMap);
443 return;
444 }
445
Tobias Grosserdf382372012-03-02 15:20:35 +0000446 copyInstScalar(Inst, BBMap, GlobalMap);
Tobias Grosser80998e72012-03-02 11:27:28 +0000447}
448
449
Tobias Grosser55d52082012-03-02 15:20:39 +0000450void BlockGenerator::copyBB(ValueMapT &GlobalMap) {
Tobias Grosser80998e72012-03-02 11:27:28 +0000451 BasicBlock *BB = Statement.getBasicBlock();
452 BasicBlock *CopyBB = SplitBlock(Builder.GetInsertBlock(),
453 Builder.GetInsertPoint(), P);
454 CopyBB->setName("polly.stmt." + BB->getName());
455 Builder.SetInsertPoint(CopyBB->begin());
456
Tobias Grosserdf382372012-03-02 15:20:35 +0000457 ValueMapT BBMap;
Tobias Grosser80998e72012-03-02 11:27:28 +0000458
459 for (BasicBlock::const_iterator II = BB->begin(), IE = BB->end(); II != IE;
460 ++II)
Tobias Grosserdf382372012-03-02 15:20:35 +0000461 copyInstruction(II, BBMap, GlobalMap);
Tobias Grosser80998e72012-03-02 11:27:28 +0000462}
463
Tobias Grosser55d52082012-03-02 15:20:39 +0000464/// @brief Generate a new vector basic block for a polyhedral statement.
465///
466/// The only public function exposed is generate().
Tobias Grosser80998e72012-03-02 11:27:28 +0000467class VectorBlockGenerator : BlockGenerator {
468public:
Tobias Grosser55d52082012-03-02 15:20:39 +0000469 /// @brief Generate a new vector basic block for a ScoPStmt.
470 ///
471 /// This code generation is similar to the normal, scalar code generation,
472 /// except that each instruction is code generated for several vector lanes
473 /// at a time. If possible instructions are issued as actual vector
474 /// instructions, but e.g. for address calculation instructions we currently
475 /// generate scalar instructions for each vector lane.
476 ///
477 /// @param Builder The LLVM-IR Builder used to generate the statement. The
478 /// code is generated at the location, the builder points
479 /// to.
480 /// @param Stmt The statement to code generate.
481 /// @param GlobalMaps A vector of maps that define for certain Values
482 /// referenced from the original code new Values they should
483 /// be replaced with. Each map in the vector of maps is
484 /// used for one vector lane. The number of elements in the
485 /// vector defines the width of the generated vector
486 /// instructions.
487 /// @param P A reference to the pass this function is called from.
488 /// The pass is needed to update other analysis.
489 static void generate(IRBuilder<> &B, ScopStmt &Stmt,
490 VectorValueMapT &GlobalMaps, __isl_keep isl_set *Domain,
491 Pass *P) {
492 VectorBlockGenerator Generator(B, GlobalMaps, Stmt, Domain, P);
Tobias Grosser80998e72012-03-02 11:27:28 +0000493 Generator.copyBB();
494 }
495
496private:
Tobias Grosser55d52082012-03-02 15:20:39 +0000497 // This is a vector of global value maps. The first map is used for the first
498 // vector lane, ...
499 // Each map, contains information about Instructions in the old ScoP, which
500 // are recalculated in the new SCoP. When copying the basic block, we replace
501 // all referenes to the old instructions with their recalculated values.
Tobias Grosserdf382372012-03-02 15:20:35 +0000502 VectorValueMapT &GlobalMaps;
Tobias Grosser80998e72012-03-02 11:27:28 +0000503
Tobias Grosser08a82382012-03-02 15:20:24 +0000504 isl_set *Domain;
505
Tobias Grosser55d52082012-03-02 15:20:39 +0000506 VectorBlockGenerator(IRBuilder<> &B, VectorValueMapT &GlobalMaps,
507 ScopStmt &Stmt, __isl_keep isl_set *Domain, Pass *P);
Tobias Grosser80998e72012-03-02 11:27:28 +0000508
509 int getVectorWidth();
510
Tobias Grosser55d52082012-03-02 15:20:39 +0000511 Value *getVectorValue(const Value *Old, ValueMapT &VectorMap,
512 VectorValueMapT &ScalarMaps);
Tobias Grosser80998e72012-03-02 11:27:28 +0000513
514 Type *getVectorPtrTy(const Value *V, int Width);
515
516 /// @brief Load a vector from a set of adjacent scalars
517 ///
518 /// In case a set of scalars is known to be next to each other in memory,
519 /// create a vector load that loads those scalars
520 ///
521 /// %vector_ptr= bitcast double* %p to <4 x double>*
522 /// %vec_full = load <4 x double>* %vector_ptr
523 ///
524 Value *generateStrideOneLoad(const LoadInst *Load, ValueMapT &BBMap);
525
526 /// @brief Load a vector initialized from a single scalar in memory
527 ///
528 /// In case all elements of a vector are initialized to the same
529 /// scalar value, this value is loaded and shuffeled into all elements
530 /// of the vector.
531 ///
532 /// %splat_one = load <1 x double>* %p
533 /// %splat = shufflevector <1 x double> %splat_one, <1 x
534 /// double> %splat_one, <4 x i32> zeroinitializer
535 ///
536 Value *generateStrideZeroLoad(const LoadInst *Load, ValueMapT &BBMap);
537
538 /// @Load a vector from scalars distributed in memory
539 ///
540 /// In case some scalars a distributed randomly in memory. Create a vector
541 /// by loading each scalar and by inserting one after the other into the
542 /// vector.
543 ///
544 /// %scalar_1= load double* %p_1
545 /// %vec_1 = insertelement <2 x double> undef, double %scalar_1, i32 0
546 /// %scalar 2 = load double* %p_2
547 /// %vec_2 = insertelement <2 x double> %vec_1, double %scalar_1, i32 1
548 ///
549 Value *generateUnknownStrideLoad(const LoadInst *Load,
550 VectorValueMapT &ScalarMaps);
551
Tobias Grosser80998e72012-03-02 11:27:28 +0000552 void generateLoad(const LoadInst *Load, ValueMapT &VectorMap,
553 VectorValueMapT &ScalarMaps);
554
Tobias Grosserdf382372012-03-02 15:20:35 +0000555 void copyUnaryInst(const UnaryInstruction *Inst, ValueMapT &VectorMap,
556 VectorValueMapT &ScalarMaps);
Tobias Grosser80998e72012-03-02 11:27:28 +0000557
Tobias Grosserdf382372012-03-02 15:20:35 +0000558 void copyBinaryInst(const BinaryOperator *Inst, ValueMapT &VectorMap,
559 VectorValueMapT &ScalarMaps);
Tobias Grosser80998e72012-03-02 11:27:28 +0000560
Tobias Grosserdf382372012-03-02 15:20:35 +0000561 void copyStore(const StoreInst *Store, ValueMapT &VectorMap,
Tobias Grosser260e86d2012-03-02 15:20:28 +0000562 VectorValueMapT &ScalarMaps);
Tobias Grosser80998e72012-03-02 11:27:28 +0000563
564 bool hasVectorOperands(const Instruction *Inst, ValueMapT &VectorMap);
565
566 void copyInstruction(const Instruction *Inst, ValueMapT &VectorMap,
567 VectorValueMapT &ScalarMaps);
568
Tobias Grosser80998e72012-03-02 11:27:28 +0000569 void copyBB();
570};
571
Tobias Grosser55d52082012-03-02 15:20:39 +0000572VectorBlockGenerator::VectorBlockGenerator(IRBuilder<> &B,
573 VectorValueMapT &GlobalMaps, ScopStmt &Stmt, __isl_keep isl_set *Domain,
574 Pass *P) : BlockGenerator(B, Stmt, P), GlobalMaps(GlobalMaps),
575 Domain(Domain) {
Tobias Grosserdf382372012-03-02 15:20:35 +0000576 assert(GlobalMaps.size() > 1 && "Only one vector lane found");
Tobias Grosser08a82382012-03-02 15:20:24 +0000577 assert(Domain && "No statement domain provided");
Tobias Grosser80998e72012-03-02 11:27:28 +0000578 }
579
Tobias Grosser55d52082012-03-02 15:20:39 +0000580Value *VectorBlockGenerator::getVectorValue(const Value *Old,
581 ValueMapT &VectorMap,
582 VectorValueMapT &ScalarMaps) {
583 if (VectorMap.count(Old))
584 return VectorMap[Old];
Tobias Grosser80998e72012-03-02 11:27:28 +0000585
Tobias Grosserdf382372012-03-02 15:20:35 +0000586 int Width = getVectorWidth();
Tobias Grosser80998e72012-03-02 11:27:28 +0000587
Tobias Grosser55d52082012-03-02 15:20:39 +0000588 Value *Vector = UndefValue::get(VectorType::get(Old->getType(), Width));
Tobias Grosser80998e72012-03-02 11:27:28 +0000589
Tobias Grosserdf382372012-03-02 15:20:35 +0000590 for (int Lane = 0; Lane < Width; Lane++)
591 Vector = Builder.CreateInsertElement(Vector,
Tobias Grosser55d52082012-03-02 15:20:39 +0000592 getNewValue(Old,
593 ScalarMaps[Lane],
594 GlobalMaps[Lane]),
Tobias Grosserdf382372012-03-02 15:20:35 +0000595 Builder.getInt32(Lane));
Tobias Grosser80998e72012-03-02 11:27:28 +0000596
Tobias Grosser55d52082012-03-02 15:20:39 +0000597 VectorMap[Old] = Vector;
Tobias Grosserdf382372012-03-02 15:20:35 +0000598
599 return Vector;
Tobias Grosser80998e72012-03-02 11:27:28 +0000600}
601
602Type *VectorBlockGenerator::getVectorPtrTy(const Value *Val, int Width) {
603 PointerType *PointerTy = dyn_cast<PointerType>(Val->getType());
604 assert(PointerTy && "PointerType expected");
605
606 Type *ScalarType = PointerTy->getElementType();
607 VectorType *VectorType = VectorType::get(ScalarType, Width);
608
609 return PointerType::getUnqual(VectorType);
610}
611
612Value *VectorBlockGenerator::generateStrideOneLoad(const LoadInst *Load,
613 ValueMapT &BBMap) {
614 const Value *Pointer = Load->getPointerOperand();
615 Type *VectorPtrType = getVectorPtrTy(Pointer, getVectorWidth());
Tobias Grosser55d52082012-03-02 15:20:39 +0000616 Value *NewPointer = getNewValue(Pointer, BBMap, GlobalMaps[0]);
Tobias Grosser80998e72012-03-02 11:27:28 +0000617 Value *VectorPtr = Builder.CreateBitCast(NewPointer, VectorPtrType,
618 "vector_ptr");
619 LoadInst *VecLoad = Builder.CreateLoad(VectorPtr,
620 Load->getName() + "_p_vec_full");
621 if (!Aligned)
622 VecLoad->setAlignment(8);
623
624 return VecLoad;
625}
626
627Value *VectorBlockGenerator::generateStrideZeroLoad(const LoadInst *Load,
628 ValueMapT &BBMap) {
629 const Value *Pointer = Load->getPointerOperand();
630 Type *VectorPtrType = getVectorPtrTy(Pointer, 1);
Tobias Grosser55d52082012-03-02 15:20:39 +0000631 Value *NewPointer = getNewValue(Pointer, BBMap, GlobalMaps[0]);
Tobias Grosser80998e72012-03-02 11:27:28 +0000632 Value *VectorPtr = Builder.CreateBitCast(NewPointer, VectorPtrType,
633 Load->getName() + "_p_vec_p");
634 LoadInst *ScalarLoad= Builder.CreateLoad(VectorPtr,
635 Load->getName() + "_p_splat_one");
636
637 if (!Aligned)
638 ScalarLoad->setAlignment(8);
639
640 Constant *SplatVector =
641 Constant::getNullValue(VectorType::get(Builder.getInt32Ty(),
642 getVectorWidth()));
643
644 Value *VectorLoad = Builder.CreateShuffleVector(ScalarLoad, ScalarLoad,
645 SplatVector,
646 Load->getName()
647 + "_p_splat");
648 return VectorLoad;
649}
650
651Value *VectorBlockGenerator::generateUnknownStrideLoad(const LoadInst *Load,
652 VectorValueMapT &ScalarMaps) {
653 int VectorWidth = getVectorWidth();
654 const Value *Pointer = Load->getPointerOperand();
655 VectorType *VectorType = VectorType::get(
656 dyn_cast<PointerType>(Pointer->getType())->getElementType(), VectorWidth);
657
658 Value *Vector = UndefValue::get(VectorType);
659
660 for (int i = 0; i < VectorWidth; i++) {
Tobias Grosser55d52082012-03-02 15:20:39 +0000661 Value *NewPointer = getNewValue(Pointer, ScalarMaps[i], GlobalMaps[i]);
Tobias Grosser80998e72012-03-02 11:27:28 +0000662 Value *ScalarLoad = Builder.CreateLoad(NewPointer,
663 Load->getName() + "_p_scalar_");
664 Vector = Builder.CreateInsertElement(Vector, ScalarLoad,
665 Builder.getInt32(i),
666 Load->getName() + "_p_vec_");
667 }
668
669 return Vector;
670}
671
672void VectorBlockGenerator::generateLoad(const LoadInst *Load,
673 ValueMapT &VectorMap,
674 VectorValueMapT &ScalarMaps) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000675 Value *NewLoad;
676
677 MemoryAccess &Access = Statement.getAccessFor(Load);
678
Tobias Grosser08a82382012-03-02 15:20:24 +0000679 if (Access.isStrideZero(isl_set_copy(Domain)))
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000680 NewLoad = generateStrideZeroLoad(Load, ScalarMaps[0]);
Tobias Grosser08a82382012-03-02 15:20:24 +0000681 else if (Access.isStrideOne(isl_set_copy(Domain)))
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000682 NewLoad = generateStrideOneLoad(Load, ScalarMaps[0]);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000683 else
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000684 NewLoad = generateUnknownStrideLoad(Load, ScalarMaps);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000685
686 VectorMap[Load] = NewLoad;
687}
688
Tobias Grosser80998e72012-03-02 11:27:28 +0000689void VectorBlockGenerator::copyUnaryInst(const UnaryInstruction *Inst,
Tobias Grosserdf382372012-03-02 15:20:35 +0000690 ValueMapT &VectorMap,
691 VectorValueMapT &ScalarMaps) {
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000692 int VectorWidth = getVectorWidth();
Tobias Grosser55d52082012-03-02 15:20:39 +0000693 Value *NewOperand = getVectorValue(Inst->getOperand(0), VectorMap,
694 ScalarMaps);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000695
696 assert(isa<CastInst>(Inst) && "Can not generate vector code for instruction");
697
698 const CastInst *Cast = dyn_cast<CastInst>(Inst);
699 VectorType *DestType = VectorType::get(Inst->getType(), VectorWidth);
700 VectorMap[Inst] = Builder.CreateCast(Cast->getOpcode(), NewOperand, DestType);
701}
702
Tobias Grosser80998e72012-03-02 11:27:28 +0000703void VectorBlockGenerator::copyBinaryInst(const BinaryOperator *Inst,
Tobias Grosserdf382372012-03-02 15:20:35 +0000704 ValueMapT &VectorMap,
705 VectorValueMapT &ScalarMaps) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000706 Value *OpZero = Inst->getOperand(0);
707 Value *OpOne = Inst->getOperand(1);
708
709 Value *NewOpZero, *NewOpOne;
Tobias Grosser55d52082012-03-02 15:20:39 +0000710 NewOpZero = getVectorValue(OpZero, VectorMap, ScalarMaps);
711 NewOpOne = getVectorValue(OpOne, VectorMap, ScalarMaps);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000712
713 Value *NewInst = Builder.CreateBinOp(Inst->getOpcode(), NewOpZero,
714 NewOpOne,
715 Inst->getName() + "p_vec");
716 VectorMap[Inst] = NewInst;
717}
718
Tobias Grosserdf382372012-03-02 15:20:35 +0000719void VectorBlockGenerator::copyStore(const StoreInst *Store,
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000720 ValueMapT &VectorMap,
Tobias Grosser8927a442012-03-02 11:27:05 +0000721 VectorValueMapT &ScalarMaps) {
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000722 int VectorWidth = getVectorWidth();
723
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000724 MemoryAccess &Access = Statement.getAccessFor(Store);
725
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000726 const Value *Pointer = Store->getPointerOperand();
Tobias Grosser55d52082012-03-02 15:20:39 +0000727 Value *Vector = getVectorValue(Store->getValueOperand(), VectorMap,
Tobias Grosserdf382372012-03-02 15:20:35 +0000728 ScalarMaps);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000729
Tobias Grosser08a82382012-03-02 15:20:24 +0000730 if (Access.isStrideOne(isl_set_copy(Domain))) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000731 Type *VectorPtrType = getVectorPtrTy(Pointer, VectorWidth);
Tobias Grosser55d52082012-03-02 15:20:39 +0000732 Value *NewPointer = getNewValue(Pointer, ScalarMaps[0], GlobalMaps[0]);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000733
734 Value *VectorPtr = Builder.CreateBitCast(NewPointer, VectorPtrType,
735 "vector_ptr");
736 StoreInst *Store = Builder.CreateStore(Vector, VectorPtr);
737
738 if (!Aligned)
739 Store->setAlignment(8);
740 } else {
741 for (unsigned i = 0; i < ScalarMaps.size(); i++) {
742 Value *Scalar = Builder.CreateExtractElement(Vector,
743 Builder.getInt32(i));
Tobias Grosser55d52082012-03-02 15:20:39 +0000744 Value *NewPointer = getNewValue(Pointer, ScalarMaps[i], GlobalMaps[i]);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000745 Builder.CreateStore(Scalar, NewPointer);
746 }
747 }
748}
749
Tobias Grosser80998e72012-03-02 11:27:28 +0000750bool VectorBlockGenerator::hasVectorOperands(const Instruction *Inst,
751 ValueMapT &VectorMap) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000752 for (Instruction::const_op_iterator OI = Inst->op_begin(),
753 OE = Inst->op_end(); OI != OE; ++OI)
754 if (VectorMap.count(*OI))
755 return true;
756 return false;
757}
758
Tobias Grosser80998e72012-03-02 11:27:28 +0000759int VectorBlockGenerator::getVectorWidth() {
Tobias Grosserdf382372012-03-02 15:20:35 +0000760 return GlobalMaps.size();
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000761}
762
Tobias Grosser80998e72012-03-02 11:27:28 +0000763void VectorBlockGenerator::copyInstruction(const Instruction *Inst,
Tobias Grosser32152cb2012-03-02 11:27:18 +0000764 ValueMapT &VectorMap,
765 VectorValueMapT &ScalarMaps) {
Tobias Grosser80998e72012-03-02 11:27:28 +0000766 // Terminator instructions control the control flow. They are explicitly
767 // expressed in the clast and do not need to be copied.
768 if (Inst->isTerminator())
769 return;
770
Tobias Grosser32152cb2012-03-02 11:27:18 +0000771 if (const LoadInst *Load = dyn_cast<LoadInst>(Inst)) {
Tobias Grosser80998e72012-03-02 11:27:28 +0000772 generateLoad(Load, VectorMap, ScalarMaps);
Tobias Grosser32152cb2012-03-02 11:27:18 +0000773 return;
774 }
775
776 if (hasVectorOperands(Inst, VectorMap)) {
777 if (const StoreInst *Store = dyn_cast<StoreInst>(Inst)) {
Tobias Grosserdf382372012-03-02 15:20:35 +0000778 copyStore(Store, VectorMap, ScalarMaps);
Tobias Grosser32152cb2012-03-02 11:27:18 +0000779 return;
780 }
781
782 if (const UnaryInstruction *Unary = dyn_cast<UnaryInstruction>(Inst)) {
Tobias Grosserdf382372012-03-02 15:20:35 +0000783 copyUnaryInst(Unary, VectorMap, ScalarMaps);
Tobias Grosser32152cb2012-03-02 11:27:18 +0000784 return;
785 }
786
787 if (const BinaryOperator *Binary = dyn_cast<BinaryOperator>(Inst)) {
Tobias Grosserdf382372012-03-02 15:20:35 +0000788 copyBinaryInst(Binary, VectorMap, ScalarMaps);
Tobias Grosser32152cb2012-03-02 11:27:18 +0000789 return;
790 }
791
792 llvm_unreachable("Cannot issue vector code for this instruction");
793 }
794
795 for (int VectorLane = 0; VectorLane < getVectorWidth(); VectorLane++)
Tobias Grosserdf382372012-03-02 15:20:35 +0000796 copyInstScalar(Inst, ScalarMaps[VectorLane], GlobalMaps[VectorLane]);
Tobias Grosser32152cb2012-03-02 11:27:18 +0000797}
798
Tobias Grosser80998e72012-03-02 11:27:28 +0000799void VectorBlockGenerator::copyBB() {
Tobias Grosser14bcbd52012-03-02 11:26:52 +0000800 BasicBlock *BB = Statement.getBasicBlock();
Tobias Grosser0ac92142012-02-14 14:02:27 +0000801 BasicBlock *CopyBB = SplitBlock(Builder.GetInsertBlock(),
802 Builder.GetInsertPoint(), P);
Tobias Grosserb61e6312012-02-15 09:58:46 +0000803 CopyBB->setName("polly.stmt." + BB->getName());
Tobias Grosser0ac92142012-02-14 14:02:27 +0000804 Builder.SetInsertPoint(CopyBB->begin());
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000805
806 // Create two maps that store the mapping from the original instructions of
807 // the old basic block to their copies in the new basic block. Those maps
808 // are basic block local.
809 //
810 // As vector code generation is supported there is one map for scalar values
811 // and one for vector values.
812 //
813 // In case we just do scalar code generation, the vectorMap is not used and
814 // the scalarMap has just one dimension, which contains the mapping.
815 //
816 // In case vector code generation is done, an instruction may either appear
817 // in the vector map once (as it is calculating >vectorwidth< values at a
818 // time. Or (if the values are calculated using scalar operations), it
819 // appears once in every dimension of the scalarMap.
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000820 VectorValueMapT ScalarBlockMap(getVectorWidth());
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000821 ValueMapT VectorBlockMap;
822
823 for (BasicBlock::const_iterator II = BB->begin(), IE = BB->end();
824 II != IE; ++II)
Tobias Grosserfc1153f2012-03-02 11:27:15 +0000825 copyInstruction(II, VectorBlockMap, ScalarBlockMap);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000826}
827
Tobias Grosser75805372011-04-29 06:27:02 +0000828/// Class to generate LLVM-IR that calculates the value of a clast_expr.
829class ClastExpCodeGen {
830 IRBuilder<> &Builder;
Tobias Grosser5e8ffa82012-03-23 12:20:36 +0000831 const CharMapT &IVS;
Tobias Grosser75805372011-04-29 06:27:02 +0000832
Tobias Grosserbb137e32012-01-24 16:42:28 +0000833 Value *codegen(const clast_name *e, Type *Ty);
834 Value *codegen(const clast_term *e, Type *Ty);
835 Value *codegen(const clast_binary *e, Type *Ty);
836 Value *codegen(const clast_reduction *r, Type *Ty);
Tobias Grosser75805372011-04-29 06:27:02 +0000837public:
838
839 // A generator for clast expressions.
840 //
841 // @param B The IRBuilder that defines where the code to calculate the
842 // clast expressions should be inserted.
843 // @param IVMAP A Map that translates strings describing the induction
844 // variables to the Values* that represent these variables
845 // on the LLVM side.
Tobias Grosser5e8ffa82012-03-23 12:20:36 +0000846 ClastExpCodeGen(IRBuilder<> &B, CharMapT &IVMap);
Tobias Grosser75805372011-04-29 06:27:02 +0000847
848 // Generates code to calculate a given clast expression.
849 //
850 // @param e The expression to calculate.
851 // @return The Value that holds the result.
Tobias Grosserbb137e32012-01-24 16:42:28 +0000852 Value *codegen(const clast_expr *e, Type *Ty);
Tobias Grosserbb137e32012-01-24 16:42:28 +0000853};
854
855Value *ClastExpCodeGen::codegen(const clast_name *e, Type *Ty) {
Tobias Grosser5e8ffa82012-03-23 12:20:36 +0000856 CharMapT::const_iterator I = IVS.find(e->name);
Tobias Grosserbb137e32012-01-24 16:42:28 +0000857
Tobias Grosser5e8ffa82012-03-23 12:20:36 +0000858 assert(I != IVS.end() && "Clast name not found");
Tobias Grosserbb137e32012-01-24 16:42:28 +0000859
860 return Builder.CreateSExtOrBitCast(I->second, Ty);
861}
862
863Value *ClastExpCodeGen::codegen(const clast_term *e, Type *Ty) {
864 APInt a = APInt_from_MPZ(e->val);
865
866 Value *ConstOne = ConstantInt::get(Builder.getContext(), a);
867 ConstOne = Builder.CreateSExtOrBitCast(ConstOne, Ty);
868
869 if (!e->var)
870 return ConstOne;
871
872 Value *var = codegen(e->var, Ty);
873 return Builder.CreateMul(ConstOne, var);
874}
875
876Value *ClastExpCodeGen::codegen(const clast_binary *e, Type *Ty) {
877 Value *LHS = codegen(e->LHS, Ty);
878
879 APInt RHS_AP = APInt_from_MPZ(e->RHS);
880
881 Value *RHS = ConstantInt::get(Builder.getContext(), RHS_AP);
882 RHS = Builder.CreateSExtOrBitCast(RHS, Ty);
883
884 switch (e->type) {
885 case clast_bin_mod:
886 return Builder.CreateSRem(LHS, RHS);
887 case clast_bin_fdiv:
888 {
Tobias Grosser9a44b972012-02-16 14:13:19 +0000889 // floord(n,d) ((n < 0) ? (n - d + 1) : n) / d
Tobias Grosser906eafe2012-02-16 09:56:10 +0000890 Value *One = ConstantInt::get(Ty, 1);
891 Value *Zero = ConstantInt::get(Ty, 0);
Tobias Grosser9a44b972012-02-16 14:13:19 +0000892 Value *Sum1 = Builder.CreateSub(LHS, RHS);
893 Value *Sum2 = Builder.CreateAdd(Sum1, One);
894 Value *isNegative = Builder.CreateICmpSLT(LHS, Zero);
895 Value *Dividend = Builder.CreateSelect(isNegative, Sum2, LHS);
896 return Builder.CreateSDiv(Dividend, RHS);
Tobias Grosserbb137e32012-01-24 16:42:28 +0000897 }
898 case clast_bin_cdiv:
899 {
Tobias Grosser9a44b972012-02-16 14:13:19 +0000900 // ceild(n,d) ((n < 0) ? n : (n + d - 1)) / d
901 Value *One = ConstantInt::get(Ty, 1);
Tobias Grosser906eafe2012-02-16 09:56:10 +0000902 Value *Zero = ConstantInt::get(Ty, 0);
Tobias Grosser9a44b972012-02-16 14:13:19 +0000903 Value *Sum1 = Builder.CreateAdd(LHS, RHS);
904 Value *Sum2 = Builder.CreateSub(Sum1, One);
905 Value *isNegative = Builder.CreateICmpSLT(LHS, Zero);
906 Value *Dividend = Builder.CreateSelect(isNegative, LHS, Sum2);
907 return Builder.CreateSDiv(Dividend, RHS);
Tobias Grosserbb137e32012-01-24 16:42:28 +0000908 }
909 case clast_bin_div:
910 return Builder.CreateSDiv(LHS, RHS);
911 };
912
913 llvm_unreachable("Unknown clast binary expression type");
914}
915
916Value *ClastExpCodeGen::codegen(const clast_reduction *r, Type *Ty) {
917 assert(( r->type == clast_red_min
918 || r->type == clast_red_max
919 || r->type == clast_red_sum)
920 && "Clast reduction type not supported");
921 Value *old = codegen(r->elts[0], Ty);
922
923 for (int i=1; i < r->n; ++i) {
924 Value *exprValue = codegen(r->elts[i], Ty);
925
926 switch (r->type) {
927 case clast_red_min:
928 {
929 Value *cmp = Builder.CreateICmpSLT(old, exprValue);
930 old = Builder.CreateSelect(cmp, old, exprValue);
931 break;
932 }
933 case clast_red_max:
934 {
935 Value *cmp = Builder.CreateICmpSGT(old, exprValue);
936 old = Builder.CreateSelect(cmp, old, exprValue);
937 break;
938 }
939 case clast_red_sum:
940 old = Builder.CreateAdd(old, exprValue);
941 break;
Tobias Grosserbb137e32012-01-24 16:42:28 +0000942 }
Tobias Grosser75805372011-04-29 06:27:02 +0000943 }
944
Tobias Grosserbb137e32012-01-24 16:42:28 +0000945 return old;
946}
947
Tobias Grosser5e8ffa82012-03-23 12:20:36 +0000948ClastExpCodeGen::ClastExpCodeGen(IRBuilder<> &B, CharMapT &IVMap)
Tobias Grosserbb137e32012-01-24 16:42:28 +0000949 : Builder(B), IVS(IVMap) {}
950
951Value *ClastExpCodeGen::codegen(const clast_expr *e, Type *Ty) {
952 switch(e->type) {
953 case clast_expr_name:
954 return codegen((const clast_name *)e, Ty);
955 case clast_expr_term:
956 return codegen((const clast_term *)e, Ty);
957 case clast_expr_bin:
958 return codegen((const clast_binary *)e, Ty);
959 case clast_expr_red:
960 return codegen((const clast_reduction *)e, Ty);
961 }
962
963 llvm_unreachable("Unknown clast expression!");
964}
965
Tobias Grosser75805372011-04-29 06:27:02 +0000966class ClastStmtCodeGen {
Tobias Grosserf74a4cd2012-03-23 10:35:18 +0000967public:
968 const std::vector<std::string> &getParallelLoops();
969
970private:
Tobias Grosser75805372011-04-29 06:27:02 +0000971 // The Scop we code generate.
972 Scop *S;
Tobias Grosser0ac92142012-02-14 14:02:27 +0000973 Pass *P;
Tobias Grosser75805372011-04-29 06:27:02 +0000974
975 // The Builder specifies the current location to code generate at.
976 IRBuilder<> &Builder;
977
978 // Map the Values from the old code to their counterparts in the new code.
979 ValueMapT ValueMap;
980
981 // clastVars maps from the textual representation of a clast variable to its
982 // current *Value. clast variables are scheduling variables, original
983 // induction variables or parameters. They are used either in loop bounds or
984 // to define the statement instance that is executed.
985 //
986 // for (s = 0; s < n + 3; ++i)
987 // for (t = s; t < m; ++j)
988 // Stmt(i = s + 3 * m, j = t);
989 //
990 // {s,t,i,j,n,m} is the set of clast variables in this clast.
Tobias Grosser5e8ffa82012-03-23 12:20:36 +0000991 CharMapT ClastVars;
Tobias Grosser75805372011-04-29 06:27:02 +0000992
993 // Codegenerator for clast expressions.
994 ClastExpCodeGen ExpGen;
995
996 // Do we currently generate parallel code?
997 bool parallelCodeGeneration;
998
999 std::vector<std::string> parallelLoops;
1000
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001001 void codegen(const clast_assignment *a);
Tobias Grosser75805372011-04-29 06:27:02 +00001002
1003 void codegen(const clast_assignment *a, ScopStmt *Statement,
1004 unsigned Dimension, int vectorDim,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001005 std::vector<ValueMapT> *VectorVMap = 0);
Tobias Grosser75805372011-04-29 06:27:02 +00001006
1007 void codegenSubstitutions(const clast_stmt *Assignment,
1008 ScopStmt *Statement, int vectorDim = 0,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001009 std::vector<ValueMapT> *VectorVMap = 0);
Tobias Grosser75805372011-04-29 06:27:02 +00001010
1011 void codegen(const clast_user_stmt *u, std::vector<Value*> *IVS = NULL,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001012 const char *iterator = NULL, isl_set *scatteringDomain = 0);
Tobias Grosser75805372011-04-29 06:27:02 +00001013
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001014 void codegen(const clast_block *b);
Tobias Grosser75805372011-04-29 06:27:02 +00001015
1016 /// @brief Create a classical sequential loop.
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001017 void codegenForSequential(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +00001018
1019 /// @brief Create OpenMP structure values.
1020 ///
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001021 /// Create a list of values that has to be stored into the OpenMP subfuncition
Tobias Grosser75805372011-04-29 06:27:02 +00001022 /// structure.
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001023 SetVector<Value*> getOMPValues();
Tobias Grosser75805372011-04-29 06:27:02 +00001024
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001025 /// @brief Update the internal structures according to a Value Map.
1026 ///
1027 /// @param VMap A map from old to new values.
1028 /// @param Reverse If true, we assume the update should be reversed.
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001029 void updateWithValueMap(OMPGenerator::ValueToValueMapTy &VMap,
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001030 bool Reverse);
Tobias Grosser75805372011-04-29 06:27:02 +00001031
1032 /// @brief Create an OpenMP parallel for loop.
1033 ///
1034 /// This loop reflects a loop as if it would have been created by an OpenMP
1035 /// statement.
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001036 void codegenForOpenMP(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +00001037
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001038 bool isInnermostLoop(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +00001039
1040 /// @brief Get the number of loop iterations for this loop.
1041 /// @param f The clast for loop to check.
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001042 int getNumberOfIterations(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +00001043
1044 /// @brief Create vector instructions for this loop.
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001045 void codegenForVector(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +00001046
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001047 void codegen(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +00001048
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001049 Value *codegen(const clast_equation *eq);
Tobias Grosser75805372011-04-29 06:27:02 +00001050
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001051 void codegen(const clast_guard *g);
Tobias Grosser75805372011-04-29 06:27:02 +00001052
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001053 void codegen(const clast_stmt *stmt);
Tobias Grosser75805372011-04-29 06:27:02 +00001054
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001055 void addParameters(const CloogNames *names);
Tobias Grosser75805372011-04-29 06:27:02 +00001056
Tobias Grossere9ffea22012-03-15 09:34:48 +00001057 IntegerType *getIntPtrTy();
1058
Tobias Grosser75805372011-04-29 06:27:02 +00001059 public:
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001060 void codegen(const clast_root *r);
Tobias Grosser75805372011-04-29 06:27:02 +00001061
Tobias Grosserd596b372012-03-15 09:34:52 +00001062 ClastStmtCodeGen(Scop *scop, IRBuilder<> &B, Pass *P);
Tobias Grosser75805372011-04-29 06:27:02 +00001063};
1064}
1065
Tobias Grossere9ffea22012-03-15 09:34:48 +00001066IntegerType *ClastStmtCodeGen::getIntPtrTy() {
1067 return P->getAnalysis<TargetData>().getIntPtrType(Builder.getContext());
1068}
1069
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001070const std::vector<std::string> &ClastStmtCodeGen::getParallelLoops() {
1071 return parallelLoops;
1072}
1073
1074void ClastStmtCodeGen::codegen(const clast_assignment *a) {
Tobias Grossere9ffea22012-03-15 09:34:48 +00001075 Value *V= ExpGen.codegen(a->RHS, getIntPtrTy());
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001076 ClastVars[a->LHS] = V;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001077}
1078
1079void ClastStmtCodeGen::codegen(const clast_assignment *a, ScopStmt *Statement,
1080 unsigned Dimension, int vectorDim,
1081 std::vector<ValueMapT> *VectorVMap) {
Tobias Grossere9ffea22012-03-15 09:34:48 +00001082 Value *RHS = ExpGen.codegen(a->RHS, getIntPtrTy());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001083
1084 assert(!a->LHS && "Statement assignments do not have left hand side");
1085 const PHINode *PN;
1086 PN = Statement->getInductionVariableForDimension(Dimension);
1087 const Value *V = PN;
1088
1089 if (VectorVMap)
1090 (*VectorVMap)[vectorDim][V] = RHS;
1091
1092 ValueMap[V] = RHS;
1093}
1094
1095void ClastStmtCodeGen::codegenSubstitutions(const clast_stmt *Assignment,
1096 ScopStmt *Statement, int vectorDim,
1097 std::vector<ValueMapT> *VectorVMap) {
1098 int Dimension = 0;
1099
1100 while (Assignment) {
1101 assert(CLAST_STMT_IS_A(Assignment, stmt_ass)
1102 && "Substitions are expected to be assignments");
1103 codegen((const clast_assignment *)Assignment, Statement, Dimension,
1104 vectorDim, VectorVMap);
1105 Assignment = Assignment->next;
1106 Dimension++;
1107 }
1108}
1109
1110void ClastStmtCodeGen::codegen(const clast_user_stmt *u,
1111 std::vector<Value*> *IVS , const char *iterator,
Tobias Grosser14bcbd52012-03-02 11:26:52 +00001112 isl_set *Domain) {
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001113 ScopStmt *Statement = (ScopStmt *)u->statement->usr;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001114
1115 if (u->substitutions)
1116 codegenSubstitutions(u->substitutions, Statement);
1117
Tobias Grosser80998e72012-03-02 11:27:28 +00001118 int VectorDimensions = IVS ? IVS->size() : 1;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001119
Tobias Grosser80998e72012-03-02 11:27:28 +00001120 if (VectorDimensions == 1) {
Tobias Grosser55d52082012-03-02 15:20:39 +00001121 BlockGenerator::generate(Builder, *Statement, ValueMap, P);
Tobias Grosser80998e72012-03-02 11:27:28 +00001122 return;
1123 }
1124
1125 VectorValueMapT VectorMap(VectorDimensions);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001126
1127 if (IVS) {
1128 assert (u->substitutions && "Substitutions expected!");
1129 int i = 0;
1130 for (std::vector<Value*>::iterator II = IVS->begin(), IE = IVS->end();
1131 II != IE; ++II) {
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001132 ClastVars[iterator] = *II;
Tobias Grosser14bcbd52012-03-02 11:26:52 +00001133 codegenSubstitutions(u->substitutions, Statement, i, &VectorMap);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001134 i++;
1135 }
1136 }
1137
Tobias Grosser55d52082012-03-02 15:20:39 +00001138 VectorBlockGenerator::generate(Builder, *Statement, VectorMap, Domain, P);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001139}
1140
1141void ClastStmtCodeGen::codegen(const clast_block *b) {
1142 if (b->body)
1143 codegen(b->body);
1144}
1145
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001146void ClastStmtCodeGen::codegenForSequential(const clast_for *f) {
1147 Value *LowerBound, *UpperBound, *IV, *Stride;
Tobias Grosser0ac92142012-02-14 14:02:27 +00001148 BasicBlock *AfterBB;
Tobias Grossere9ffea22012-03-15 09:34:48 +00001149 Type *IntPtrTy = getIntPtrTy();
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001150
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001151 LowerBound = ExpGen.codegen(f->LB, IntPtrTy);
1152 UpperBound = ExpGen.codegen(f->UB, IntPtrTy);
1153 Stride = Builder.getInt(APInt_from_MPZ(f->stride));
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001154
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001155 IV = createLoop(LowerBound, UpperBound, Stride, &Builder, P, &AfterBB);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001156
1157 // Add loop iv to symbols.
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001158 ClastVars[f->iterator] = IV;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001159
1160 if (f->body)
1161 codegen(f->body);
1162
1163 // Loop is finished, so remove its iv from the live symbols.
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001164 ClastVars.erase(f->iterator);
Tobias Grosser0ac92142012-02-14 14:02:27 +00001165 Builder.SetInsertPoint(AfterBB->begin());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001166}
1167
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001168SetVector<Value*> ClastStmtCodeGen::getOMPValues() {
1169 SetVector<Value*> Values;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001170
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001171 // The clast variables
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001172 for (CharMapT::iterator I = ClastVars.begin(), E = ClastVars.end();
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001173 I != E; I++)
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001174 Values.insert(I->second);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001175
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001176 // The memory reference base addresses
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001177 for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI) {
1178 ScopStmt *Stmt = *SI;
1179 for (SmallVector<MemoryAccess*, 8>::iterator I = Stmt->memacc_begin(),
1180 E = Stmt->memacc_end(); I != E; ++I) {
1181 Value *BaseAddr = const_cast<Value*>((*I)->getBaseAddr());
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001182 Values.insert((BaseAddr));
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001183 }
1184 }
1185
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001186 return Values;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001187}
1188
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001189void ClastStmtCodeGen::updateWithValueMap(OMPGenerator::ValueToValueMapTy &VMap,
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001190 bool Reverse) {
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001191 std::set<Value*> Inserted;
1192
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001193 if (Reverse) {
1194 OMPGenerator::ValueToValueMapTy ReverseMap;
1195
1196 for (std::map<Value*, Value*>::iterator I = VMap.begin(), E = VMap.end();
1197 I != E; ++I)
1198 ReverseMap.insert(std::make_pair(I->second, I->first));
1199
1200 for (CharMapT::iterator I = ClastVars.begin(), E = ClastVars.end();
1201 I != E; I++) {
1202 ClastVars[I->first] = ReverseMap[I->second];
1203 Inserted.insert(I->second);
1204 }
1205
1206 /// FIXME: At the moment we do not reverse the update of the ValueMap.
1207 /// This is incomplet, but the failure should be obvious, such that
1208 /// we can fix this later.
1209 return;
1210 }
1211
1212 for (CharMapT::iterator I = ClastVars.begin(), E = ClastVars.end();
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001213 I != E; I++) {
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001214 ClastVars[I->first] = VMap[I->second];
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001215 Inserted.insert(I->second);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001216 }
1217
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001218 for (std::map<Value*, Value*>::iterator I = VMap.begin(), E = VMap.end();
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001219 I != E; ++I) {
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001220 if (Inserted.count(I->first))
1221 continue;
1222
1223 ValueMap[I->first] = I->second;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001224 }
1225}
1226
Tobias Grosser900893d2012-03-29 13:10:26 +00001227static void clearDomtree(Function *F, DominatorTree &DT) {
1228 DomTreeNode *N = DT.getNode(&F->getEntryBlock());
1229 std::vector<BasicBlock*> Nodes;
1230 for (po_iterator<DomTreeNode*> I = po_begin(N), E = po_end(N); I != E; ++I)
1231 Nodes.push_back(I->getBlock());
1232
1233 for (std::vector<BasicBlock*>::iterator I = Nodes.begin(), E = Nodes.end();
1234 I != E; ++I)
1235 DT.eraseNode(*I);
1236}
1237
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001238void ClastStmtCodeGen::codegenForOpenMP(const clast_for *For) {
Tobias Grosserebf30082012-03-23 12:20:32 +00001239 Value *Stride, *LB, *UB, *IV;
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001240 BasicBlock::iterator LoopBody;
1241 IntegerType *IntPtrTy = getIntPtrTy();
1242 SetVector<Value*> Values;
1243 OMPGenerator::ValueToValueMapTy VMap;
1244 OMPGenerator OMPGen(Builder, P);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001245
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001246 Stride = Builder.getInt(APInt_from_MPZ(For->stride));
1247 Stride = Builder.CreateSExtOrBitCast(Stride, IntPtrTy);
Tobias Grosserebf30082012-03-23 12:20:32 +00001248 LB = ExpGen.codegen(For->LB, IntPtrTy);
1249 UB = ExpGen.codegen(For->UB, IntPtrTy);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001250
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001251 Values = getOMPValues();
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001252
Tobias Grosserebf30082012-03-23 12:20:32 +00001253 IV = OMPGen.createParallelLoop(LB, UB, Stride, Values, VMap, &LoopBody);
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001254 BasicBlock::iterator AfterLoop = Builder.GetInsertPoint();
1255 Builder.SetInsertPoint(LoopBody);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001256
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001257 updateWithValueMap(VMap, /* reverse */ false);
1258 ClastVars[For->iterator] = IV;
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001259
1260 if (For->body)
1261 codegen(For->body);
1262
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001263 ClastVars.erase(For->iterator);
1264 updateWithValueMap(VMap, /* reverse */ true);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001265
Tobias Grosser900893d2012-03-29 13:10:26 +00001266 clearDomtree((*LoopBody).getParent()->getParent(),
1267 P->getAnalysis<DominatorTree>());
1268
Tobias Grosserf74a4cd2012-03-23 10:35:18 +00001269 Builder.SetInsertPoint(AfterLoop);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001270}
1271
1272bool ClastStmtCodeGen::isInnermostLoop(const clast_for *f) {
1273 const clast_stmt *stmt = f->body;
1274
1275 while (stmt) {
1276 if (!CLAST_STMT_IS_A(stmt, stmt_user))
1277 return false;
1278
1279 stmt = stmt->next;
1280 }
1281
1282 return true;
1283}
1284
1285int ClastStmtCodeGen::getNumberOfIterations(const clast_for *f) {
1286 isl_set *loopDomain = isl_set_copy(isl_set_from_cloog_domain(f->domain));
1287 isl_set *tmp = isl_set_copy(loopDomain);
1288
1289 // Calculate a map similar to the identity map, but with the last input
1290 // and output dimension not related.
1291 // [i0, i1, i2, i3] -> [i0, i1, i2, o0]
1292 isl_space *Space = isl_set_get_space(loopDomain);
1293 Space = isl_space_drop_outputs(Space,
1294 isl_set_dim(loopDomain, isl_dim_set) - 2, 1);
1295 Space = isl_space_map_from_set(Space);
1296 isl_map *identity = isl_map_identity(Space);
1297 identity = isl_map_add_dims(identity, isl_dim_in, 1);
1298 identity = isl_map_add_dims(identity, isl_dim_out, 1);
1299
1300 isl_map *map = isl_map_from_domain_and_range(tmp, loopDomain);
1301 map = isl_map_intersect(map, identity);
1302
1303 isl_map *lexmax = isl_map_lexmax(isl_map_copy(map));
1304 isl_map *lexmin = isl_map_lexmin(map);
1305 isl_map *sub = isl_map_sum(lexmax, isl_map_neg(lexmin));
1306
1307 isl_set *elements = isl_map_range(sub);
1308
1309 if (!isl_set_is_singleton(elements)) {
1310 isl_set_free(elements);
1311 return -1;
1312 }
1313
1314 isl_point *p = isl_set_sample_point(elements);
1315
1316 isl_int v;
1317 isl_int_init(v);
1318 isl_point_get_coordinate(p, isl_dim_set, isl_set_n_dim(loopDomain) - 1, &v);
1319 int numberIterations = isl_int_get_si(v);
1320 isl_int_clear(v);
1321 isl_point_free(p);
1322
1323 return (numberIterations) / isl_int_get_si(f->stride) + 1;
1324}
1325
Tobias Grosser2da263e2012-03-15 09:34:55 +00001326void ClastStmtCodeGen::codegenForVector(const clast_for *F) {
1327 DEBUG(dbgs() << "Vectorizing loop '" << F->iterator << "'\n";);
1328 int VectorWidth = getNumberOfIterations(F);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001329
Tobias Grosser2da263e2012-03-15 09:34:55 +00001330 Value *LB = ExpGen.codegen(F->LB, getIntPtrTy());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001331
Tobias Grosser2da263e2012-03-15 09:34:55 +00001332 APInt Stride = APInt_from_MPZ(F->stride);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001333 IntegerType *LoopIVType = dyn_cast<IntegerType>(LB->getType());
1334 Stride = Stride.zext(LoopIVType->getBitWidth());
1335 Value *StrideValue = ConstantInt::get(LoopIVType, Stride);
1336
Tobias Grosser2da263e2012-03-15 09:34:55 +00001337 std::vector<Value*> IVS(VectorWidth);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001338 IVS[0] = LB;
1339
Tobias Grosser2da263e2012-03-15 09:34:55 +00001340 for (int i = 1; i < VectorWidth; i++)
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001341 IVS[i] = Builder.CreateAdd(IVS[i-1], StrideValue, "p_vector_iv");
1342
Tobias Grosser00d898d2012-03-15 09:34:58 +00001343 isl_set *Domain = isl_set_from_cloog_domain(F->domain);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001344
1345 // Add loop iv to symbols.
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001346 ClastVars[F->iterator] = LB;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001347
Tobias Grosser2da263e2012-03-15 09:34:55 +00001348 const clast_stmt *Stmt = F->body;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001349
Tobias Grosser2da263e2012-03-15 09:34:55 +00001350 while (Stmt) {
Tobias Grosser00d898d2012-03-15 09:34:58 +00001351 codegen((const clast_user_stmt *)Stmt, &IVS, F->iterator,
1352 isl_set_copy(Domain));
Tobias Grosser2da263e2012-03-15 09:34:55 +00001353 Stmt = Stmt->next;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001354 }
1355
1356 // Loop is finished, so remove its iv from the live symbols.
Tobias Grosser00d898d2012-03-15 09:34:58 +00001357 isl_set_free(Domain);
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001358 ClastVars.erase(F->iterator);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001359}
1360
1361void ClastStmtCodeGen::codegen(const clast_for *f) {
Tobias Grosserd596b372012-03-15 09:34:52 +00001362 if ((Vector || OpenMP) && P->getAnalysis<Dependences>().isParallelFor(f)) {
Tobias Grosserce3f5372012-03-02 11:26:42 +00001363 if (Vector && isInnermostLoop(f) && (-1 != getNumberOfIterations(f))
1364 && (getNumberOfIterations(f) <= 16)) {
1365 codegenForVector(f);
1366 return;
1367 }
1368
1369 if (OpenMP && !parallelCodeGeneration) {
1370 parallelCodeGeneration = true;
1371 parallelLoops.push_back(f->iterator);
1372 codegenForOpenMP(f);
1373 parallelCodeGeneration = false;
1374 return;
1375 }
1376 }
1377
1378 codegenForSequential(f);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001379}
1380
1381Value *ClastStmtCodeGen::codegen(const clast_equation *eq) {
Tobias Grossere9ffea22012-03-15 09:34:48 +00001382 Value *LHS = ExpGen.codegen(eq->LHS, getIntPtrTy());
1383 Value *RHS = ExpGen.codegen(eq->RHS, getIntPtrTy());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001384 CmpInst::Predicate P;
1385
1386 if (eq->sign == 0)
1387 P = ICmpInst::ICMP_EQ;
1388 else if (eq->sign > 0)
1389 P = ICmpInst::ICMP_SGE;
1390 else
1391 P = ICmpInst::ICMP_SLE;
1392
1393 return Builder.CreateICmp(P, LHS, RHS);
1394}
1395
1396void ClastStmtCodeGen::codegen(const clast_guard *g) {
1397 Function *F = Builder.GetInsertBlock()->getParent();
1398 LLVMContext &Context = F->getContext();
Tobias Grosser0ac92142012-02-14 14:02:27 +00001399
1400 BasicBlock *CondBB = SplitBlock(Builder.GetInsertBlock(),
1401 Builder.GetInsertPoint(), P);
1402 CondBB->setName("polly.cond");
1403 BasicBlock *MergeBB = SplitBlock(CondBB, CondBB->begin(), P);
1404 MergeBB->setName("polly.merge");
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001405 BasicBlock *ThenBB = BasicBlock::Create(Context, "polly.then", F);
Tobias Grosser0ac92142012-02-14 14:02:27 +00001406
Tobias Grosserd596b372012-03-15 09:34:52 +00001407 DominatorTree &DT = P->getAnalysis<DominatorTree>();
1408 DT.addNewBlock(ThenBB, CondBB);
1409 DT.changeImmediateDominator(MergeBB, CondBB);
Tobias Grosser0ac92142012-02-14 14:02:27 +00001410
1411 CondBB->getTerminator()->eraseFromParent();
1412
1413 Builder.SetInsertPoint(CondBB);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001414
1415 Value *Predicate = codegen(&(g->eq[0]));
1416
1417 for (int i = 1; i < g->n; ++i) {
1418 Value *TmpPredicate = codegen(&(g->eq[i]));
1419 Predicate = Builder.CreateAnd(Predicate, TmpPredicate);
1420 }
1421
1422 Builder.CreateCondBr(Predicate, ThenBB, MergeBB);
1423 Builder.SetInsertPoint(ThenBB);
Tobias Grosser0ac92142012-02-14 14:02:27 +00001424 Builder.CreateBr(MergeBB);
1425 Builder.SetInsertPoint(ThenBB->begin());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001426
1427 codegen(g->then);
Tobias Grosser62a3c962012-02-16 09:56:21 +00001428
1429 Builder.SetInsertPoint(MergeBB->begin());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001430}
1431
1432void ClastStmtCodeGen::codegen(const clast_stmt *stmt) {
1433 if (CLAST_STMT_IS_A(stmt, stmt_root))
1434 assert(false && "No second root statement expected");
1435 else if (CLAST_STMT_IS_A(stmt, stmt_ass))
1436 codegen((const clast_assignment *)stmt);
1437 else if (CLAST_STMT_IS_A(stmt, stmt_user))
1438 codegen((const clast_user_stmt *)stmt);
1439 else if (CLAST_STMT_IS_A(stmt, stmt_block))
1440 codegen((const clast_block *)stmt);
1441 else if (CLAST_STMT_IS_A(stmt, stmt_for))
1442 codegen((const clast_for *)stmt);
1443 else if (CLAST_STMT_IS_A(stmt, stmt_guard))
1444 codegen((const clast_guard *)stmt);
1445
1446 if (stmt->next)
1447 codegen(stmt->next);
1448}
1449
1450void ClastStmtCodeGen::addParameters(const CloogNames *names) {
Tobias Grosserd596b372012-03-15 09:34:52 +00001451 SCEVExpander Rewriter(P->getAnalysis<ScalarEvolution>(), "polly");
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001452
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001453 int i = 0;
1454 for (Scop::param_iterator PI = S->param_begin(), PE = S->param_end();
1455 PI != PE; ++PI) {
1456 assert(i < names->nb_parameters && "Not enough parameter names");
1457
1458 const SCEV *Param = *PI;
1459 Type *Ty = Param->getType();
1460
1461 Instruction *insertLocation = --(Builder.GetInsertBlock()->end());
1462 Value *V = Rewriter.expandCodeFor(Param, Ty, insertLocation);
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001463 ClastVars[names->parameters[i]] = V;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001464
1465 ++i;
1466 }
1467}
1468
1469void ClastStmtCodeGen::codegen(const clast_root *r) {
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001470 addParameters(r->names);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001471
1472 parallelCodeGeneration = false;
1473
1474 const clast_stmt *stmt = (const clast_stmt*) r;
1475 if (stmt->next)
1476 codegen(stmt->next);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001477}
1478
Tobias Grosserd596b372012-03-15 09:34:52 +00001479ClastStmtCodeGen::ClastStmtCodeGen(Scop *scop, IRBuilder<> &B, Pass *P) :
Tobias Grosser5e8ffa82012-03-23 12:20:36 +00001480 S(scop), P(P), Builder(B), ExpGen(Builder, ClastVars) {}
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001481
Tobias Grosser75805372011-04-29 06:27:02 +00001482namespace {
1483class CodeGeneration : public ScopPass {
1484 Region *region;
1485 Scop *S;
1486 DominatorTree *DT;
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001487 RegionInfo *RI;
Tobias Grosser75805372011-04-29 06:27:02 +00001488
1489 std::vector<std::string> parallelLoops;
1490
1491 public:
1492 static char ID;
1493
1494 CodeGeneration() : ScopPass(ID) {}
1495
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001496 // Split the entry edge of the region and generate a new basic block on this
1497 // edge. This function also updates ScopInfo and RegionInfo.
1498 //
1499 // @param region The region where the entry edge will be splitted.
1500 BasicBlock *splitEdgeAdvanced(Region *region) {
1501 BasicBlock *newBlock;
1502 BasicBlock *splitBlock;
1503
1504 newBlock = SplitEdge(region->getEnteringBlock(), region->getEntry(), this);
1505
1506 if (DT->dominates(region->getEntry(), newBlock)) {
Tobias Grossercb47dfe2012-02-15 09:58:50 +00001507 BasicBlock *OldBlock = region->getEntry();
1508 std::string OldName = OldBlock->getName();
1509
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001510 // Update ScopInfo.
1511 for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI)
Tobias Grosserf12cea42012-02-15 09:58:53 +00001512 if ((*SI)->getBasicBlock() == OldBlock) {
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001513 (*SI)->setBasicBlock(newBlock);
1514 break;
1515 }
1516
1517 // Update RegionInfo.
Tobias Grossercb47dfe2012-02-15 09:58:50 +00001518 splitBlock = OldBlock;
1519 OldBlock->setName("polly.split");
1520 newBlock->setName(OldName);
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001521 region->replaceEntry(newBlock);
Tobias Grosser7a16c892011-05-14 19:01:55 +00001522 RI->setRegionFor(newBlock, region);
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001523 } else {
1524 RI->setRegionFor(newBlock, region->getParent());
1525 splitBlock = newBlock;
1526 }
1527
1528 return splitBlock;
1529 }
1530
1531 // Create a split block that branches either to the old code or to a new basic
1532 // block where the new code can be inserted.
1533 //
Tobias Grosserbd608a82012-02-12 12:09:41 +00001534 // @param Builder A builder that will be set to point to a basic block, where
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001535 // the new code can be generated.
1536 // @return The split basic block.
Tobias Grosserbd608a82012-02-12 12:09:41 +00001537 BasicBlock *addSplitAndStartBlock(IRBuilder<> *Builder) {
1538 BasicBlock *StartBlock, *SplitBlock;
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001539
Tobias Grosserbd608a82012-02-12 12:09:41 +00001540 SplitBlock = splitEdgeAdvanced(region);
1541 SplitBlock->setName("polly.split_new_and_old");
1542 Function *F = SplitBlock->getParent();
1543 StartBlock = BasicBlock::Create(F->getContext(), "polly.start", F);
1544 SplitBlock->getTerminator()->eraseFromParent();
1545 Builder->SetInsertPoint(SplitBlock);
1546 Builder->CreateCondBr(Builder->getTrue(), StartBlock, region->getEntry());
1547 DT->addNewBlock(StartBlock, SplitBlock);
1548 Builder->SetInsertPoint(StartBlock);
1549 return SplitBlock;
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001550 }
1551
1552 // Merge the control flow of the newly generated code with the existing code.
1553 //
Tobias Grosserbd608a82012-02-12 12:09:41 +00001554 // @param SplitBlock The basic block where the control flow was split between
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001555 // old and new version of the Scop.
Tobias Grosserbd608a82012-02-12 12:09:41 +00001556 // @param Builder An IRBuilder that points to the last instruction of the
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001557 // newly generated code.
Tobias Grosserbd608a82012-02-12 12:09:41 +00001558 void mergeControlFlow(BasicBlock *SplitBlock, IRBuilder<> *Builder) {
1559 BasicBlock *MergeBlock;
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001560 Region *R = region;
1561
1562 if (R->getExit()->getSinglePredecessor())
1563 // No splitEdge required. A block with a single predecessor cannot have
1564 // PHI nodes that would complicate life.
Tobias Grosserbd608a82012-02-12 12:09:41 +00001565 MergeBlock = R->getExit();
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001566 else {
Tobias Grosserbd608a82012-02-12 12:09:41 +00001567 MergeBlock = SplitEdge(R->getExitingBlock(), R->getExit(), this);
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001568 // SplitEdge will never split R->getExit(), as R->getExit() has more than
1569 // one predecessor. Hence, mergeBlock is always a newly generated block.
Tobias Grosserbd608a82012-02-12 12:09:41 +00001570 R->replaceExit(MergeBlock);
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001571 }
1572
Tobias Grosserbd608a82012-02-12 12:09:41 +00001573 Builder->CreateBr(MergeBlock);
Tobias Grosser8518bbe2012-02-12 12:09:46 +00001574 MergeBlock->setName("polly.merge_new_and_old");
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001575
Tobias Grosserbd608a82012-02-12 12:09:41 +00001576 if (DT->dominates(SplitBlock, MergeBlock))
1577 DT->changeImmediateDominator(MergeBlock, SplitBlock);
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001578 }
1579
Tobias Grosser75805372011-04-29 06:27:02 +00001580 bool runOnScop(Scop &scop) {
1581 S = &scop;
1582 region = &S->getRegion();
Tobias Grosser75805372011-04-29 06:27:02 +00001583 DT = &getAnalysis<DominatorTree>();
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001584 RI = &getAnalysis<RegionInfo>();
Tobias Grosser75805372011-04-29 06:27:02 +00001585
1586 parallelLoops.clear();
1587
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001588 assert(region->isSimple() && "Only simple regions are supported");
Tobias Grosser76d7c522011-05-14 19:01:37 +00001589
Tobias Grosser5772e652012-02-01 14:23:33 +00001590 // In the CFG the optimized code of the SCoP is generated next to the
1591 // original code. Both the new and the original version of the code remain
1592 // in the CFG. A branch statement decides which version is executed.
1593 // For now, we always execute the new version (the old one is dead code
1594 // eliminated by the cleanup passes). In the future we may decide to execute
1595 // the new version only if certain run time checks succeed. This will be
1596 // useful to support constructs for which we cannot prove all assumptions at
1597 // compile time.
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001598 //
1599 // Before transformation:
1600 //
1601 // bb0
1602 // |
1603 // orig_scop
1604 // |
1605 // bb1
1606 //
1607 // After transformation:
1608 // bb0
1609 // |
1610 // polly.splitBlock
Tobias Grosser2bd3af12011-08-01 22:39:00 +00001611 // / \.
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001612 // | startBlock
1613 // | |
1614 // orig_scop new_scop
1615 // \ /
1616 // \ /
1617 // bb1 (joinBlock)
1618 IRBuilder<> builder(region->getEntry());
Tobias Grosser75805372011-04-29 06:27:02 +00001619
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001620 // The builder will be set to startBlock.
1621 BasicBlock *splitBlock = addSplitAndStartBlock(&builder);
Tobias Grosser0ac92142012-02-14 14:02:27 +00001622 BasicBlock *StartBlock = builder.GetInsertBlock();
Tobias Grosser75805372011-04-29 06:27:02 +00001623
Tobias Grosser0ac92142012-02-14 14:02:27 +00001624 mergeControlFlow(splitBlock, &builder);
1625 builder.SetInsertPoint(StartBlock->begin());
1626
Tobias Grosserd596b372012-03-15 09:34:52 +00001627 ClastStmtCodeGen CodeGen(S, builder, this);
Tobias Grosser3fdecae2011-05-14 19:02:39 +00001628 CloogInfo &C = getAnalysis<CloogInfo>();
1629 CodeGen.codegen(C.getClast());
Tobias Grosser75805372011-04-29 06:27:02 +00001630
Tobias Grosser75805372011-04-29 06:27:02 +00001631 parallelLoops.insert(parallelLoops.begin(),
1632 CodeGen.getParallelLoops().begin(),
1633 CodeGen.getParallelLoops().end());
1634
Tobias Grosserabb6dcd2011-05-14 19:02:34 +00001635 return true;
Tobias Grosser75805372011-04-29 06:27:02 +00001636 }
1637
1638 virtual void printScop(raw_ostream &OS) const {
1639 for (std::vector<std::string>::const_iterator PI = parallelLoops.begin(),
1640 PE = parallelLoops.end(); PI != PE; ++PI)
1641 OS << "Parallel loop with iterator '" << *PI << "' generated\n";
1642 }
1643
1644 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
1645 AU.addRequired<CloogInfo>();
1646 AU.addRequired<Dependences>();
1647 AU.addRequired<DominatorTree>();
Tobias Grosser75805372011-04-29 06:27:02 +00001648 AU.addRequired<RegionInfo>();
Tobias Grosser73600b82011-10-08 00:30:40 +00001649 AU.addRequired<ScalarEvolution>();
Tobias Grosser75805372011-04-29 06:27:02 +00001650 AU.addRequired<ScopDetection>();
1651 AU.addRequired<ScopInfo>();
1652 AU.addRequired<TargetData>();
1653
1654 AU.addPreserved<CloogInfo>();
1655 AU.addPreserved<Dependences>();
Tobias Grosser5d6eb862011-05-14 19:02:45 +00001656
Tobias Grosser4e3f9a42011-05-23 15:23:36 +00001657 // FIXME: We do not create LoopInfo for the newly generated loops.
Tobias Grosser75805372011-04-29 06:27:02 +00001658 AU.addPreserved<LoopInfo>();
1659 AU.addPreserved<DominatorTree>();
Tobias Grosser75805372011-04-29 06:27:02 +00001660 AU.addPreserved<ScopDetection>();
1661 AU.addPreserved<ScalarEvolution>();
Tobias Grosser5d6eb862011-05-14 19:02:45 +00001662
Tobias Grosser4e3f9a42011-05-23 15:23:36 +00001663 // FIXME: We do not yet add regions for the newly generated code to the
1664 // region tree.
Tobias Grosser75805372011-04-29 06:27:02 +00001665 AU.addPreserved<RegionInfo>();
1666 AU.addPreserved<TempScopInfo>();
1667 AU.addPreserved<ScopInfo>();
1668 AU.addPreservedID(IndependentBlocksID);
1669 }
1670};
1671}
1672
1673char CodeGeneration::ID = 1;
1674
Tobias Grosser73600b82011-10-08 00:30:40 +00001675INITIALIZE_PASS_BEGIN(CodeGeneration, "polly-codegen",
Tobias Grosser3c2efba2012-03-06 07:38:57 +00001676 "Polly - Create LLVM-IR from SCoPs", false, false)
Tobias Grosser73600b82011-10-08 00:30:40 +00001677INITIALIZE_PASS_DEPENDENCY(CloogInfo)
1678INITIALIZE_PASS_DEPENDENCY(Dependences)
1679INITIALIZE_PASS_DEPENDENCY(DominatorTree)
1680INITIALIZE_PASS_DEPENDENCY(RegionInfo)
1681INITIALIZE_PASS_DEPENDENCY(ScalarEvolution)
1682INITIALIZE_PASS_DEPENDENCY(ScopDetection)
1683INITIALIZE_PASS_DEPENDENCY(TargetData)
1684INITIALIZE_PASS_END(CodeGeneration, "polly-codegen",
Tobias Grosser3c2efba2012-03-06 07:38:57 +00001685 "Polly - Create LLVM-IR from SCoPs", false, false)
Tobias Grosser75805372011-04-29 06:27:02 +00001686
Tobias Grosser7ffe4e82011-11-17 12:56:10 +00001687Pass *polly::createCodeGenerationPass() {
Tobias Grosser75805372011-04-29 06:27:02 +00001688 return new CodeGeneration();
1689}