blob: 2bba6e6ad1120ea826a592b2e493d2ee9322c586 [file] [log] [blame]
Tobias Grosser75805372011-04-29 06:27:02 +00001//===------ CodeGeneration.cpp - Code generate the Scops. -----------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// The CodeGeneration pass takes a Scop created by ScopInfo and translates it
11// back to LLVM-IR using Cloog.
12//
13// The Scop describes the high level memory behaviour of a control flow region.
14// Transformation passes can update the schedule (execution order) of statements
15// in the Scop. Cloog is used to generate an abstract syntax tree (clast) that
16// reflects the updated execution order. This clast is used to create new
17// LLVM-IR that is computational equivalent to the original control flow region,
18// but executes its code in the new execution order defined by the changed
19// scattering.
20//
21//===----------------------------------------------------------------------===//
22
23#define DEBUG_TYPE "polly-codegen"
24
Tobias Grosser75805372011-04-29 06:27:02 +000025#include "polly/Cloog.h"
Tobias Grosser67707b72011-10-23 20:59:40 +000026#include "polly/CodeGeneration.h"
Tobias Grosser75805372011-04-29 06:27:02 +000027#include "polly/Dependences.h"
Tobias Grosserbda1f8f2012-02-01 14:23:29 +000028#include "polly/LinkAllPasses.h"
Tobias Grosser75805372011-04-29 06:27:02 +000029#include "polly/ScopInfo.h"
30#include "polly/TempScopInfo.h"
Tobias Grosserbda1f8f2012-02-01 14:23:29 +000031#include "polly/Support/GICHelper.h"
32
33#include "llvm/Module.h"
34#include "llvm/ADT/SetVector.h"
35#include "llvm/Analysis/LoopInfo.h"
36#include "llvm/Analysis/ScalarEvolutionExpander.h"
Tobias Grosser75805372011-04-29 06:27:02 +000037#include "llvm/Support/CommandLine.h"
38#include "llvm/Support/Debug.h"
39#include "llvm/Support/IRBuilder.h"
Tobias Grosser75805372011-04-29 06:27:02 +000040#include "llvm/Target/TargetData.h"
Tobias Grosserbda1f8f2012-02-01 14:23:29 +000041#include "llvm/Transforms/Utils/BasicBlockUtils.h"
Tobias Grosser75805372011-04-29 06:27:02 +000042
43#define CLOOG_INT_GMP 1
44#include "cloog/cloog.h"
45#include "cloog/isl/cloog.h"
46
Raghesh Aloora71989c2011-12-28 02:48:26 +000047#include "isl/aff.h"
48
Tobias Grosser75805372011-04-29 06:27:02 +000049#include <vector>
50#include <utility>
51
52using namespace polly;
53using namespace llvm;
54
55struct isl_set;
56
57namespace polly {
58
Tobias Grosser67707b72011-10-23 20:59:40 +000059bool EnablePollyVector;
60
61static cl::opt<bool, true>
Tobias Grosser75805372011-04-29 06:27:02 +000062Vector("enable-polly-vector",
63 cl::desc("Enable polly vector code generation"), cl::Hidden,
Tobias Grosser0acfcdb2012-03-16 17:17:16 +000064 cl::location(EnablePollyVector), cl::init(false), cl::ZeroOrMore);
Tobias Grosser75805372011-04-29 06:27:02 +000065
66static cl::opt<bool>
67OpenMP("enable-polly-openmp",
68 cl::desc("Generate OpenMP parallel code"), cl::Hidden,
69 cl::value_desc("OpenMP code generation enabled if true"),
Tobias Grosser0acfcdb2012-03-16 17:17:16 +000070 cl::init(false), cl::ZeroOrMore);
Tobias Grosser75805372011-04-29 06:27:02 +000071
72static cl::opt<bool>
73AtLeastOnce("enable-polly-atLeastOnce",
74 cl::desc("Give polly the hint, that every loop is executed at least"
75 "once"), cl::Hidden,
76 cl::value_desc("OpenMP code generation enabled if true"),
Tobias Grosser0acfcdb2012-03-16 17:17:16 +000077 cl::init(false), cl::ZeroOrMore);
Tobias Grosser75805372011-04-29 06:27:02 +000078
79static cl::opt<bool>
80Aligned("enable-polly-aligned",
81 cl::desc("Assumed aligned memory accesses."), cl::Hidden,
82 cl::value_desc("OpenMP code generation enabled if true"),
Tobias Grosser0acfcdb2012-03-16 17:17:16 +000083 cl::init(false), cl::ZeroOrMore);
Tobias Grosser75805372011-04-29 06:27:02 +000084
Tobias Grosser75805372011-04-29 06:27:02 +000085typedef DenseMap<const Value*, Value*> ValueMapT;
86typedef DenseMap<const char*, Value*> CharMapT;
87typedef std::vector<ValueMapT> VectorValueMapT;
88
89// Create a new loop.
90//
91// @param Builder The builder used to create the loop. It also defines the
92// place where to create the loop.
93// @param UB The upper bound of the loop iv.
94// @param Stride The number by which the loop iv is incremented after every
95// iteration.
Tobias Grosser0ac92142012-02-14 14:02:27 +000096static Value *createLoop(IRBuilder<> *Builder, Value *LB, Value *UB,
Tobias Grosserd596b372012-03-15 09:34:52 +000097 APInt Stride, Pass *P, BasicBlock **AfterBlock) {
98 DominatorTree &DT = P->getAnalysis<DominatorTree>();
Tobias Grosser75805372011-04-29 06:27:02 +000099 Function *F = Builder->GetInsertBlock()->getParent();
100 LLVMContext &Context = F->getContext();
101
102 BasicBlock *PreheaderBB = Builder->GetInsertBlock();
103 BasicBlock *HeaderBB = BasicBlock::Create(Context, "polly.loop_header", F);
104 BasicBlock *BodyBB = BasicBlock::Create(Context, "polly.loop_body", F);
Tobias Grosser0ac92142012-02-14 14:02:27 +0000105 BasicBlock *AfterBB = SplitBlock(PreheaderBB, Builder->GetInsertPoint()++, P);
106 AfterBB->setName("polly.loop_after");
Tobias Grosser75805372011-04-29 06:27:02 +0000107
Tobias Grosser0ac92142012-02-14 14:02:27 +0000108 PreheaderBB->getTerminator()->setSuccessor(0, HeaderBB);
Tobias Grosserd596b372012-03-15 09:34:52 +0000109 DT.addNewBlock(HeaderBB, PreheaderBB);
Tobias Grosser75805372011-04-29 06:27:02 +0000110
Tobias Grosser75805372011-04-29 06:27:02 +0000111 Builder->SetInsertPoint(HeaderBB);
112
113 // Use the type of upper and lower bound.
114 assert(LB->getType() == UB->getType()
115 && "Different types for upper and lower bound.");
116
Tobias Grosser55927aa2011-07-18 09:53:32 +0000117 IntegerType *LoopIVType = dyn_cast<IntegerType>(UB->getType());
Tobias Grosser75805372011-04-29 06:27:02 +0000118 assert(LoopIVType && "UB is not integer?");
119
120 // IV
Tobias Grosser0ac92142012-02-14 14:02:27 +0000121 PHINode *IV = Builder->CreatePHI(LoopIVType, 2, "polly.loopiv");
Tobias Grosser75805372011-04-29 06:27:02 +0000122 IV->addIncoming(LB, PreheaderBB);
123
124 // IV increment.
125 Value *StrideValue = ConstantInt::get(LoopIVType,
126 Stride.zext(LoopIVType->getBitWidth()));
Tobias Grosser0ac92142012-02-14 14:02:27 +0000127 Value *IncrementedIV = Builder->CreateAdd(IV, StrideValue,
128 "polly.next_loopiv");
Tobias Grosser75805372011-04-29 06:27:02 +0000129
130 // Exit condition.
Tobias Grosser0ac92142012-02-14 14:02:27 +0000131 Value *CMP;
Tobias Grosser75805372011-04-29 06:27:02 +0000132 if (AtLeastOnce) { // At least on iteration.
133 UB = Builder->CreateAdd(UB, Builder->getInt64(1));
Tobias Grosser0ac92142012-02-14 14:02:27 +0000134 CMP = Builder->CreateICmpNE(IV, UB);
Tobias Grosser75805372011-04-29 06:27:02 +0000135 } else { // Maybe not executed at all.
Tobias Grosser0ac92142012-02-14 14:02:27 +0000136 CMP = Builder->CreateICmpSLE(IV, UB);
Tobias Grosser75805372011-04-29 06:27:02 +0000137 }
Tobias Grosser0ac92142012-02-14 14:02:27 +0000138
139 Builder->CreateCondBr(CMP, BodyBB, AfterBB);
Tobias Grosserd596b372012-03-15 09:34:52 +0000140 DT.addNewBlock(BodyBB, HeaderBB);
Tobias Grosser75805372011-04-29 06:27:02 +0000141
142 Builder->SetInsertPoint(BodyBB);
Tobias Grosser0ac92142012-02-14 14:02:27 +0000143 Builder->CreateBr(HeaderBB);
144 IV->addIncoming(IncrementedIV, BodyBB);
Tobias Grosserd596b372012-03-15 09:34:52 +0000145 DT.changeImmediateDominator(AfterBB, HeaderBB);
Tobias Grosser0ac92142012-02-14 14:02:27 +0000146
147 Builder->SetInsertPoint(BodyBB->begin());
148 *AfterBlock = AfterBB;
149
150 return IV;
Tobias Grosser75805372011-04-29 06:27:02 +0000151}
152
Tobias Grosser642c4112012-03-02 11:27:25 +0000153class IslGenerator;
154
155class IslGenerator {
156public:
Tobias Grosserd6adda32012-03-23 08:21:22 +0000157 IslGenerator(IRBuilder<> &Builder, std::vector<Value *> &IVS) :
158 Builder(Builder), IVS(IVS) {}
Tobias Grosser642c4112012-03-02 11:27:25 +0000159 Value *generateIslInt(__isl_take isl_int Int);
160 Value *generateIslAff(__isl_take isl_aff *Aff);
161 Value *generateIslPwAff(__isl_take isl_pw_aff *PwAff);
162
163private:
164 typedef struct {
165 Value *Result;
166 class IslGenerator *Generator;
167 } IslGenInfo;
168
169 IRBuilder<> &Builder;
Tobias Grosserd6adda32012-03-23 08:21:22 +0000170 std::vector<Value *> &IVS;
Tobias Grosser642c4112012-03-02 11:27:25 +0000171 static int mergeIslAffValues(__isl_take isl_set *Set,
172 __isl_take isl_aff *Aff, void *User);
173};
174
175Value *IslGenerator::generateIslInt(isl_int Int) {
176 mpz_t IntMPZ;
177 mpz_init(IntMPZ);
178 isl_int_get_gmp(Int, IntMPZ);
179 Value *IntValue = Builder.getInt(APInt_from_MPZ(IntMPZ));
180 mpz_clear(IntMPZ);
181 return IntValue;
182}
183
184Value *IslGenerator::generateIslAff(__isl_take isl_aff *Aff) {
Tobias Grosserd6adda32012-03-23 08:21:22 +0000185 Value *Result;
Tobias Grosser642c4112012-03-02 11:27:25 +0000186 Value *ConstValue;
187 isl_int ConstIsl;
188
189 isl_int_init(ConstIsl);
190 isl_aff_get_constant(Aff, &ConstIsl);
191 ConstValue = generateIslInt(ConstIsl);
Tobias Grosserd6adda32012-03-23 08:21:22 +0000192 Type *Ty = Builder.getInt64Ty();
Tobias Grosser642c4112012-03-02 11:27:25 +0000193
Tobias Grosserd6adda32012-03-23 08:21:22 +0000194 // FIXME: We should give the constant and coefficients the right type. Here
195 // we force it into i64.
196 Result = Builder.CreateSExtOrBitCast(ConstValue, Ty);
197
198 unsigned int NbInputDims = isl_aff_dim(Aff, isl_dim_in);
199
200 assert((IVS.size() == NbInputDims) && "The Dimension of Induction Variables"
201 "must match the dimension of the affine space.");
202
203 isl_int CoefficientIsl;
204 isl_int_init(CoefficientIsl);
205
206 for (unsigned int i = 0; i < NbInputDims; ++i) {
207 Value *CoefficientValue;
208 isl_aff_get_coefficient(Aff, isl_dim_in, i, &CoefficientIsl);
209
210 if (isl_int_is_zero(CoefficientIsl))
211 continue;
212
213 CoefficientValue = generateIslInt(CoefficientIsl);
214 CoefficientValue = Builder.CreateIntCast(CoefficientValue, Ty, true);
215 Value *IV = Builder.CreateIntCast(IVS[i], Ty, true);
216 Value *PAdd = Builder.CreateMul(CoefficientValue, IV, "p_mul_coeff");
217 Result = Builder.CreateAdd(Result, PAdd, "p_sum_coeff");
218 }
219
220 isl_int_clear(CoefficientIsl);
Tobias Grosser642c4112012-03-02 11:27:25 +0000221 isl_int_clear(ConstIsl);
222 isl_aff_free(Aff);
223
Tobias Grosserd6adda32012-03-23 08:21:22 +0000224 return Result;
Tobias Grosser642c4112012-03-02 11:27:25 +0000225}
226
227int IslGenerator::mergeIslAffValues(__isl_take isl_set *Set,
228 __isl_take isl_aff *Aff, void *User) {
229 IslGenInfo *GenInfo = (IslGenInfo *)User;
230
231 assert((GenInfo->Result == NULL) && "Result is already set."
232 "Currently only single isl_aff is supported");
233 assert(isl_set_plain_is_universe(Set)
234 && "Code generation failed because the set is not universe");
235
236 GenInfo->Result = GenInfo->Generator->generateIslAff(Aff);
237
238 isl_set_free(Set);
239 return 0;
240}
241
242Value *IslGenerator::generateIslPwAff(__isl_take isl_pw_aff *PwAff) {
243 IslGenInfo User;
244 User.Result = NULL;
245 User.Generator = this;
246 isl_pw_aff_foreach_piece(PwAff, mergeIslAffValues, &User);
247 assert(User.Result && "Code generation for isl_pw_aff failed");
248
249 isl_pw_aff_free(PwAff);
250 return User.Result;
251}
252
Tobias Grosser55d52082012-03-02 15:20:39 +0000253/// @brief Generate a new basic block for a polyhedral statement.
254///
255/// The only public function exposed is generate().
Tobias Grosser75805372011-04-29 06:27:02 +0000256class BlockGenerator {
Tobias Grosserc941ede2012-03-02 11:26:49 +0000257public:
Tobias Grosser55d52082012-03-02 15:20:39 +0000258 /// @brief Generate a new BasicBlock for a ScopStmt.
259 ///
260 /// @param Builder The LLVM-IR Builder used to generate the statement. The
261 /// code is generated at the location, the Builder points to.
262 /// @param Stmt The statement to code generate.
263 /// @param GlobalMap A map that defines for certain Values referenced from the
264 /// original code new Values they should be replaced with.
265 /// @param P A reference to the pass this function is called from.
266 /// The pass is needed to update other analysis.
267 static void generate(IRBuilder<> &Builder, ScopStmt &Stmt,
268 ValueMapT &GlobalMap, Pass *P) {
269 BlockGenerator Generator(Builder, Stmt, P);
270 Generator.copyBB(GlobalMap);
Tobias Grosserc941ede2012-03-02 11:26:49 +0000271 }
272
Tobias Grosser80998e72012-03-02 11:27:28 +0000273protected:
Tobias Grosser75805372011-04-29 06:27:02 +0000274 IRBuilder<> &Builder;
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000275 ScopStmt &Statement;
Tobias Grosser8412cda2012-03-02 11:26:55 +0000276 Pass *P;
Tobias Grosser75805372011-04-29 06:27:02 +0000277
Tobias Grosser55d52082012-03-02 15:20:39 +0000278 BlockGenerator(IRBuilder<> &B, ScopStmt &Stmt, Pass *P);
Tobias Grosser75805372011-04-29 06:27:02 +0000279
Tobias Grosser55d52082012-03-02 15:20:39 +0000280 /// @brief Get the new version of a Value.
281 ///
282 /// @param Old The old Value.
Tobias Grosser3c2efba2012-03-06 07:38:57 +0000283 /// @param BBMap A mapping from old values to their new values
Tobias Grosser55d52082012-03-02 15:20:39 +0000284 /// (for values recalculated within this basic block).
285 /// @param GlobalMap A mapping from old values to their new values
286 /// (for values recalculated in the new ScoP, but not
287 /// within this basic block).
288 ///
289 /// @returns o The old value, if it is still valid.
290 /// o The new value, if available.
291 /// o NULL, if no value is found.
292 Value *getNewValue(const Value *Old, ValueMapT &BBMap, ValueMapT &GlobalMap);
Tobias Grosser75805372011-04-29 06:27:02 +0000293
Tobias Grosserdf382372012-03-02 15:20:35 +0000294 void copyInstScalar(const Instruction *Inst, ValueMapT &BBMap,
295 ValueMapT &GlobalMap);
Tobias Grosser75805372011-04-29 06:27:02 +0000296
Raghesh Aloor129e8672011-08-15 02:33:39 +0000297 /// @brief Get the memory access offset to be added to the base address
Tobias Grosser80998e72012-03-02 11:27:28 +0000298 std::vector<Value*> getMemoryAccessIndex(__isl_keep isl_map *AccessRelation,
Tobias Grosserd6adda32012-03-23 08:21:22 +0000299 Value *BaseAddress, ValueMapT &BBMap,
300 ValueMapT &GlobalMap);
Raghesh Aloor129e8672011-08-15 02:33:39 +0000301
Raghesh Aloor62b13122011-08-03 17:02:50 +0000302 /// @brief Get the new operand address according to the changed access in
303 /// JSCOP file.
Raghesh Aloor46eceba2011-12-09 14:27:17 +0000304 Value *getNewAccessOperand(__isl_keep isl_map *NewAccessRelation,
305 Value *BaseAddress, const Value *OldOperand,
Tobias Grosserd6adda32012-03-23 08:21:22 +0000306 ValueMapT &BBMap, ValueMapT &GlobalMap);
Raghesh Aloor62b13122011-08-03 17:02:50 +0000307
308 /// @brief Generate the operand address
309 Value *generateLocationAccessed(const Instruction *Inst,
Tobias Grosserdf382372012-03-02 15:20:35 +0000310 const Value *Pointer, ValueMapT &BBMap,
311 ValueMapT &GlobalMap);
Raghesh Aloor129e8672011-08-15 02:33:39 +0000312
Tobias Grosserdf382372012-03-02 15:20:35 +0000313 Value *generateScalarLoad(const LoadInst *load, ValueMapT &BBMap,
314 ValueMapT &GlobalMap);
Tobias Grosser75805372011-04-29 06:27:02 +0000315
Tobias Grosserd6adda32012-03-23 08:21:22 +0000316 Value *generateScalarStore(const StoreInst *store, ValueMapT &BBMap,
317 ValueMapT &GlobalMap);
318
Tobias Grosser55d52082012-03-02 15:20:39 +0000319 /// @brief Copy a single Instruction.
320 ///
321 /// This copies a single Instruction and updates references to old values
322 /// with references to new values, as defined by GlobalMap and BBMap.
323 ///
Tobias Grosser3c2efba2012-03-06 07:38:57 +0000324 /// @param BBMap A mapping from old values to their new values
Tobias Grosser55d52082012-03-02 15:20:39 +0000325 /// (for values recalculated within this basic block).
326 /// @param GlobalMap A mapping from old values to their new values
327 /// (for values recalculated in the new ScoP, but not
328 /// within this basic block).
329 void copyInstruction(const Instruction *Inst, ValueMapT &BBMap,
Tobias Grosserdf382372012-03-02 15:20:35 +0000330 ValueMapT &GlobalMap);
Tobias Grosser75805372011-04-29 06:27:02 +0000331
Tobias Grosser55d52082012-03-02 15:20:39 +0000332 /// @brief Copy the basic block.
333 ///
334 /// This copies the entire basic block and updates references to old values
335 /// with references to new values, as defined by GlobalMap.
336 ///
337 /// @param GlobalMap A mapping from old values to their new values
338 /// (for values recalculated in the new ScoP, but not
339 /// within this basic block).
340 void copyBB(ValueMapT &GlobalMap);
Tobias Grosser75805372011-04-29 06:27:02 +0000341};
342
Tobias Grosser55d52082012-03-02 15:20:39 +0000343BlockGenerator::BlockGenerator(IRBuilder<> &B, ScopStmt &Stmt, Pass *P):
344 Builder(B), Statement(Stmt), P(P) {}
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000345
Tobias Grosser55d52082012-03-02 15:20:39 +0000346Value *BlockGenerator::getNewValue(const Value *Old, ValueMapT &BBMap,
347 ValueMapT &GlobalMap) {
348 const Instruction *Inst = dyn_cast<Instruction>(Old);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000349
Tobias Grosser55d52082012-03-02 15:20:39 +0000350 if (!Inst)
351 return const_cast<Value*>(Old);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000352
Tobias Grosser8367e0c2012-03-02 15:20:31 +0000353 // OldOperand was redefined outside of this BasicBlock.
Tobias Grosser55d52082012-03-02 15:20:39 +0000354 if (GlobalMap.count(Old)) {
355 Value *New = GlobalMap[Old];
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000356
Tobias Grosser55d52082012-03-02 15:20:39 +0000357 if (Old->getType()->getScalarSizeInBits()
358 < New->getType()->getScalarSizeInBits())
359 New = Builder.CreateTruncOrBitCast(New, Old->getType());
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000360
Tobias Grosser55d52082012-03-02 15:20:39 +0000361 return New;
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000362 }
363
Tobias Grosser8367e0c2012-03-02 15:20:31 +0000364 // OldOperand was recalculated within this BasicBlock.
Tobias Grosser55d52082012-03-02 15:20:39 +0000365 if (BBMap.count(Old)) {
366 return BBMap[Old];
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000367 }
368
Tobias Grosser8367e0c2012-03-02 15:20:31 +0000369 // OldOperand is SCoP invariant.
Tobias Grosser55d52082012-03-02 15:20:39 +0000370 if (!Statement.getParent()->getRegion().contains(Inst->getParent()))
371 return const_cast<Value*>(Old);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000372
Tobias Grosser8367e0c2012-03-02 15:20:31 +0000373 // We could not find any valid new operand.
374 return NULL;
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000375}
376
Tobias Grosserdf382372012-03-02 15:20:35 +0000377void BlockGenerator::copyInstScalar(const Instruction *Inst, ValueMapT &BBMap,
378 ValueMapT &GlobalMap) {
Tobias Grosser80998e72012-03-02 11:27:28 +0000379 Instruction *NewInst = Inst->clone();
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000380
Tobias Grosser80998e72012-03-02 11:27:28 +0000381 // Replace old operands with the new ones.
382 for (Instruction::const_op_iterator OI = Inst->op_begin(),
383 OE = Inst->op_end(); OI != OE; ++OI) {
384 Value *OldOperand = *OI;
Tobias Grosser55d52082012-03-02 15:20:39 +0000385 Value *NewOperand = getNewValue(OldOperand, BBMap, GlobalMap);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000386
Tobias Grosser80998e72012-03-02 11:27:28 +0000387 if (!NewOperand) {
388 assert(!isa<StoreInst>(NewInst)
389 && "Store instructions are always needed!");
390 delete NewInst;
391 return;
392 }
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000393
Tobias Grosser80998e72012-03-02 11:27:28 +0000394 NewInst->replaceUsesOfWith(OldOperand, NewOperand);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000395 }
396
Tobias Grosser80998e72012-03-02 11:27:28 +0000397 Builder.Insert(NewInst);
398 BBMap[Inst] = NewInst;
399
400 if (!NewInst->getType()->isVoidTy())
401 NewInst->setName("p_" + Inst->getName());
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000402}
403
Tobias Grosserd6adda32012-03-23 08:21:22 +0000404std::vector<Value*> BlockGenerator::getMemoryAccessIndex(
405 __isl_keep isl_map *AccessRelation, Value *BaseAddress,
406 ValueMapT &BBMap, ValueMapT &GlobalMap) {
407
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000408 assert((isl_map_dim(AccessRelation, isl_dim_out) == 1)
409 && "Only single dimensional access functions supported");
410
Tobias Grosserd6adda32012-03-23 08:21:22 +0000411 std::vector<Value *> IVS;
412 for (unsigned i = 0; i < Statement.getNumIterators(); ++i) {
413 const Value *OriginalIV = Statement.getInductionVariableForDimension(i);
414 Value *NewIV = getNewValue(OriginalIV, BBMap, GlobalMap);
415 IVS.push_back(NewIV);
416 }
417
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000418 isl_pw_aff *PwAff = isl_map_dim_max(isl_map_copy(AccessRelation), 0);
Tobias Grosserd6adda32012-03-23 08:21:22 +0000419 IslGenerator IslGen(Builder, IVS);
Tobias Grosser642c4112012-03-02 11:27:25 +0000420 Value *OffsetValue = IslGen.generateIslPwAff(PwAff);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000421
Tobias Grosserd6adda32012-03-23 08:21:22 +0000422 Type *Ty = Builder.getInt64Ty();
423 OffsetValue = Builder.CreateIntCast(OffsetValue, Ty, true);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000424
425 std::vector<Value*> IndexArray;
Tobias Grosserd6adda32012-03-23 08:21:22 +0000426 Value *NullValue = Constant::getNullValue(Ty);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000427 IndexArray.push_back(NullValue);
428 IndexArray.push_back(OffsetValue);
429 return IndexArray;
430}
431
432Value *BlockGenerator::getNewAccessOperand(
433 __isl_keep isl_map *NewAccessRelation, Value *BaseAddress, const Value
Tobias Grosserd6adda32012-03-23 08:21:22 +0000434 *OldOperand, ValueMapT &BBMap, ValueMapT &GlobalMap) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000435 std::vector<Value*> IndexArray = getMemoryAccessIndex(NewAccessRelation,
Tobias Grosserd6adda32012-03-23 08:21:22 +0000436 BaseAddress,
437 BBMap, GlobalMap);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000438 Value *NewOperand = Builder.CreateGEP(BaseAddress, IndexArray,
439 "p_newarrayidx_");
440 return NewOperand;
441}
442
443Value *BlockGenerator::generateLocationAccessed(const Instruction *Inst,
444 const Value *Pointer,
Tobias Grosserdf382372012-03-02 15:20:35 +0000445 ValueMapT &BBMap,
446 ValueMapT &GlobalMap) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000447 MemoryAccess &Access = Statement.getAccessFor(Inst);
448 isl_map *CurrentAccessRelation = Access.getAccessRelation();
449 isl_map *NewAccessRelation = Access.getNewAccessRelation();
450
451 assert(isl_map_has_equal_space(CurrentAccessRelation, NewAccessRelation)
452 && "Current and new access function use different spaces");
453
454 Value *NewPointer;
455
456 if (!NewAccessRelation) {
Tobias Grosser55d52082012-03-02 15:20:39 +0000457 NewPointer = getNewValue(Pointer, BBMap, GlobalMap);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000458 } else {
459 Value *BaseAddress = const_cast<Value*>(Access.getBaseAddr());
460 NewPointer = getNewAccessOperand(NewAccessRelation, BaseAddress, Pointer,
Tobias Grosserd6adda32012-03-23 08:21:22 +0000461 BBMap, GlobalMap);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000462 }
463
464 isl_map_free(CurrentAccessRelation);
465 isl_map_free(NewAccessRelation);
466 return NewPointer;
467}
468
469Value *BlockGenerator::generateScalarLoad(const LoadInst *Load,
Tobias Grosserdf382372012-03-02 15:20:35 +0000470 ValueMapT &BBMap,
471 ValueMapT &GlobalMap) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000472 const Value *Pointer = Load->getPointerOperand();
473 const Instruction *Inst = dyn_cast<Instruction>(Load);
Tobias Grosserdf382372012-03-02 15:20:35 +0000474 Value *NewPointer = generateLocationAccessed(Inst, Pointer, BBMap, GlobalMap);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000475 Value *ScalarLoad = Builder.CreateLoad(NewPointer,
476 Load->getName() + "_p_scalar_");
477 return ScalarLoad;
478}
479
Tobias Grosserd6adda32012-03-23 08:21:22 +0000480Value *BlockGenerator::generateScalarStore(const StoreInst *Store,
481 ValueMapT &BBMap,
482 ValueMapT &GlobalMap) {
483 const Value *Pointer = Store->getPointerOperand();
484 Value *NewPointer = generateLocationAccessed(Store, Pointer, BBMap,
485 GlobalMap);
486 Value *ValueOperand = getNewValue(Store->getValueOperand(), BBMap, GlobalMap);
487
488 return Builder.CreateStore(ValueOperand, NewPointer);
489}
490
Tobias Grosser80998e72012-03-02 11:27:28 +0000491void BlockGenerator::copyInstruction(const Instruction *Inst,
Tobias Grosserdf382372012-03-02 15:20:35 +0000492 ValueMapT &BBMap, ValueMapT &GlobalMap) {
Tobias Grosser80998e72012-03-02 11:27:28 +0000493 // Terminator instructions control the control flow. They are explicitly
494 // expressed in the clast and do not need to be copied.
495 if (Inst->isTerminator())
496 return;
497
498 if (const LoadInst *Load = dyn_cast<LoadInst>(Inst)) {
Tobias Grosserdf382372012-03-02 15:20:35 +0000499 BBMap[Load] = generateScalarLoad(Load, BBMap, GlobalMap);
Tobias Grosser80998e72012-03-02 11:27:28 +0000500 return;
501 }
502
Tobias Grosserd6adda32012-03-23 08:21:22 +0000503 if (const StoreInst *Store = dyn_cast<StoreInst>(Inst)) {
504 BBMap[Store] = generateScalarStore(Store, BBMap, GlobalMap);
505 return;
506 }
507
Tobias Grosserdf382372012-03-02 15:20:35 +0000508 copyInstScalar(Inst, BBMap, GlobalMap);
Tobias Grosser80998e72012-03-02 11:27:28 +0000509}
510
511
Tobias Grosser55d52082012-03-02 15:20:39 +0000512void BlockGenerator::copyBB(ValueMapT &GlobalMap) {
Tobias Grosser80998e72012-03-02 11:27:28 +0000513 BasicBlock *BB = Statement.getBasicBlock();
514 BasicBlock *CopyBB = SplitBlock(Builder.GetInsertBlock(),
515 Builder.GetInsertPoint(), P);
516 CopyBB->setName("polly.stmt." + BB->getName());
517 Builder.SetInsertPoint(CopyBB->begin());
518
Tobias Grosserdf382372012-03-02 15:20:35 +0000519 ValueMapT BBMap;
Tobias Grosser80998e72012-03-02 11:27:28 +0000520
521 for (BasicBlock::const_iterator II = BB->begin(), IE = BB->end(); II != IE;
522 ++II)
Tobias Grosserdf382372012-03-02 15:20:35 +0000523 copyInstruction(II, BBMap, GlobalMap);
Tobias Grosser80998e72012-03-02 11:27:28 +0000524}
525
Tobias Grosser55d52082012-03-02 15:20:39 +0000526/// @brief Generate a new vector basic block for a polyhedral statement.
527///
528/// The only public function exposed is generate().
Tobias Grosser80998e72012-03-02 11:27:28 +0000529class VectorBlockGenerator : BlockGenerator {
530public:
Tobias Grosser55d52082012-03-02 15:20:39 +0000531 /// @brief Generate a new vector basic block for a ScoPStmt.
532 ///
533 /// This code generation is similar to the normal, scalar code generation,
534 /// except that each instruction is code generated for several vector lanes
535 /// at a time. If possible instructions are issued as actual vector
536 /// instructions, but e.g. for address calculation instructions we currently
537 /// generate scalar instructions for each vector lane.
538 ///
539 /// @param Builder The LLVM-IR Builder used to generate the statement. The
540 /// code is generated at the location, the builder points
541 /// to.
542 /// @param Stmt The statement to code generate.
543 /// @param GlobalMaps A vector of maps that define for certain Values
544 /// referenced from the original code new Values they should
545 /// be replaced with. Each map in the vector of maps is
546 /// used for one vector lane. The number of elements in the
547 /// vector defines the width of the generated vector
548 /// instructions.
549 /// @param P A reference to the pass this function is called from.
550 /// The pass is needed to update other analysis.
551 static void generate(IRBuilder<> &B, ScopStmt &Stmt,
552 VectorValueMapT &GlobalMaps, __isl_keep isl_set *Domain,
553 Pass *P) {
554 VectorBlockGenerator Generator(B, GlobalMaps, Stmt, Domain, P);
Tobias Grosser80998e72012-03-02 11:27:28 +0000555 Generator.copyBB();
556 }
557
558private:
Tobias Grosser55d52082012-03-02 15:20:39 +0000559 // This is a vector of global value maps. The first map is used for the first
560 // vector lane, ...
561 // Each map, contains information about Instructions in the old ScoP, which
562 // are recalculated in the new SCoP. When copying the basic block, we replace
563 // all referenes to the old instructions with their recalculated values.
Tobias Grosserdf382372012-03-02 15:20:35 +0000564 VectorValueMapT &GlobalMaps;
Tobias Grosser80998e72012-03-02 11:27:28 +0000565
Tobias Grosser08a82382012-03-02 15:20:24 +0000566 isl_set *Domain;
567
Tobias Grosser55d52082012-03-02 15:20:39 +0000568 VectorBlockGenerator(IRBuilder<> &B, VectorValueMapT &GlobalMaps,
569 ScopStmt &Stmt, __isl_keep isl_set *Domain, Pass *P);
Tobias Grosser80998e72012-03-02 11:27:28 +0000570
571 int getVectorWidth();
572
Tobias Grosser55d52082012-03-02 15:20:39 +0000573 Value *getVectorValue(const Value *Old, ValueMapT &VectorMap,
574 VectorValueMapT &ScalarMaps);
Tobias Grosser80998e72012-03-02 11:27:28 +0000575
576 Type *getVectorPtrTy(const Value *V, int Width);
577
578 /// @brief Load a vector from a set of adjacent scalars
579 ///
580 /// In case a set of scalars is known to be next to each other in memory,
581 /// create a vector load that loads those scalars
582 ///
583 /// %vector_ptr= bitcast double* %p to <4 x double>*
584 /// %vec_full = load <4 x double>* %vector_ptr
585 ///
586 Value *generateStrideOneLoad(const LoadInst *Load, ValueMapT &BBMap);
587
588 /// @brief Load a vector initialized from a single scalar in memory
589 ///
590 /// In case all elements of a vector are initialized to the same
591 /// scalar value, this value is loaded and shuffeled into all elements
592 /// of the vector.
593 ///
594 /// %splat_one = load <1 x double>* %p
595 /// %splat = shufflevector <1 x double> %splat_one, <1 x
596 /// double> %splat_one, <4 x i32> zeroinitializer
597 ///
598 Value *generateStrideZeroLoad(const LoadInst *Load, ValueMapT &BBMap);
599
600 /// @Load a vector from scalars distributed in memory
601 ///
602 /// In case some scalars a distributed randomly in memory. Create a vector
603 /// by loading each scalar and by inserting one after the other into the
604 /// vector.
605 ///
606 /// %scalar_1= load double* %p_1
607 /// %vec_1 = insertelement <2 x double> undef, double %scalar_1, i32 0
608 /// %scalar 2 = load double* %p_2
609 /// %vec_2 = insertelement <2 x double> %vec_1, double %scalar_1, i32 1
610 ///
611 Value *generateUnknownStrideLoad(const LoadInst *Load,
612 VectorValueMapT &ScalarMaps);
613
Tobias Grosser80998e72012-03-02 11:27:28 +0000614 void generateLoad(const LoadInst *Load, ValueMapT &VectorMap,
615 VectorValueMapT &ScalarMaps);
616
Tobias Grosserdf382372012-03-02 15:20:35 +0000617 void copyUnaryInst(const UnaryInstruction *Inst, ValueMapT &VectorMap,
618 VectorValueMapT &ScalarMaps);
Tobias Grosser80998e72012-03-02 11:27:28 +0000619
Tobias Grosserdf382372012-03-02 15:20:35 +0000620 void copyBinaryInst(const BinaryOperator *Inst, ValueMapT &VectorMap,
621 VectorValueMapT &ScalarMaps);
Tobias Grosser80998e72012-03-02 11:27:28 +0000622
Tobias Grosserdf382372012-03-02 15:20:35 +0000623 void copyStore(const StoreInst *Store, ValueMapT &VectorMap,
Tobias Grosser260e86d2012-03-02 15:20:28 +0000624 VectorValueMapT &ScalarMaps);
Tobias Grosser80998e72012-03-02 11:27:28 +0000625
626 bool hasVectorOperands(const Instruction *Inst, ValueMapT &VectorMap);
627
628 void copyInstruction(const Instruction *Inst, ValueMapT &VectorMap,
629 VectorValueMapT &ScalarMaps);
630
Tobias Grosser80998e72012-03-02 11:27:28 +0000631 void copyBB();
632};
633
Tobias Grosser55d52082012-03-02 15:20:39 +0000634VectorBlockGenerator::VectorBlockGenerator(IRBuilder<> &B,
635 VectorValueMapT &GlobalMaps, ScopStmt &Stmt, __isl_keep isl_set *Domain,
636 Pass *P) : BlockGenerator(B, Stmt, P), GlobalMaps(GlobalMaps),
637 Domain(Domain) {
Tobias Grosserdf382372012-03-02 15:20:35 +0000638 assert(GlobalMaps.size() > 1 && "Only one vector lane found");
Tobias Grosser08a82382012-03-02 15:20:24 +0000639 assert(Domain && "No statement domain provided");
Tobias Grosser80998e72012-03-02 11:27:28 +0000640 }
641
Tobias Grosser55d52082012-03-02 15:20:39 +0000642Value *VectorBlockGenerator::getVectorValue(const Value *Old,
643 ValueMapT &VectorMap,
644 VectorValueMapT &ScalarMaps) {
645 if (VectorMap.count(Old))
646 return VectorMap[Old];
Tobias Grosser80998e72012-03-02 11:27:28 +0000647
Tobias Grosserdf382372012-03-02 15:20:35 +0000648 int Width = getVectorWidth();
Tobias Grosser80998e72012-03-02 11:27:28 +0000649
Tobias Grosser55d52082012-03-02 15:20:39 +0000650 Value *Vector = UndefValue::get(VectorType::get(Old->getType(), Width));
Tobias Grosser80998e72012-03-02 11:27:28 +0000651
Tobias Grosserdf382372012-03-02 15:20:35 +0000652 for (int Lane = 0; Lane < Width; Lane++)
653 Vector = Builder.CreateInsertElement(Vector,
Tobias Grosser55d52082012-03-02 15:20:39 +0000654 getNewValue(Old,
655 ScalarMaps[Lane],
656 GlobalMaps[Lane]),
Tobias Grosserdf382372012-03-02 15:20:35 +0000657 Builder.getInt32(Lane));
Tobias Grosser80998e72012-03-02 11:27:28 +0000658
Tobias Grosser55d52082012-03-02 15:20:39 +0000659 VectorMap[Old] = Vector;
Tobias Grosserdf382372012-03-02 15:20:35 +0000660
661 return Vector;
Tobias Grosser80998e72012-03-02 11:27:28 +0000662}
663
664Type *VectorBlockGenerator::getVectorPtrTy(const Value *Val, int Width) {
665 PointerType *PointerTy = dyn_cast<PointerType>(Val->getType());
666 assert(PointerTy && "PointerType expected");
667
668 Type *ScalarType = PointerTy->getElementType();
669 VectorType *VectorType = VectorType::get(ScalarType, Width);
670
671 return PointerType::getUnqual(VectorType);
672}
673
674Value *VectorBlockGenerator::generateStrideOneLoad(const LoadInst *Load,
675 ValueMapT &BBMap) {
676 const Value *Pointer = Load->getPointerOperand();
677 Type *VectorPtrType = getVectorPtrTy(Pointer, getVectorWidth());
Tobias Grosser55d52082012-03-02 15:20:39 +0000678 Value *NewPointer = getNewValue(Pointer, BBMap, GlobalMaps[0]);
Tobias Grosser80998e72012-03-02 11:27:28 +0000679 Value *VectorPtr = Builder.CreateBitCast(NewPointer, VectorPtrType,
680 "vector_ptr");
681 LoadInst *VecLoad = Builder.CreateLoad(VectorPtr,
682 Load->getName() + "_p_vec_full");
683 if (!Aligned)
684 VecLoad->setAlignment(8);
685
686 return VecLoad;
687}
688
689Value *VectorBlockGenerator::generateStrideZeroLoad(const LoadInst *Load,
690 ValueMapT &BBMap) {
691 const Value *Pointer = Load->getPointerOperand();
692 Type *VectorPtrType = getVectorPtrTy(Pointer, 1);
Tobias Grosser55d52082012-03-02 15:20:39 +0000693 Value *NewPointer = getNewValue(Pointer, BBMap, GlobalMaps[0]);
Tobias Grosser80998e72012-03-02 11:27:28 +0000694 Value *VectorPtr = Builder.CreateBitCast(NewPointer, VectorPtrType,
695 Load->getName() + "_p_vec_p");
696 LoadInst *ScalarLoad= Builder.CreateLoad(VectorPtr,
697 Load->getName() + "_p_splat_one");
698
699 if (!Aligned)
700 ScalarLoad->setAlignment(8);
701
702 Constant *SplatVector =
703 Constant::getNullValue(VectorType::get(Builder.getInt32Ty(),
704 getVectorWidth()));
705
706 Value *VectorLoad = Builder.CreateShuffleVector(ScalarLoad, ScalarLoad,
707 SplatVector,
708 Load->getName()
709 + "_p_splat");
710 return VectorLoad;
711}
712
713Value *VectorBlockGenerator::generateUnknownStrideLoad(const LoadInst *Load,
714 VectorValueMapT &ScalarMaps) {
715 int VectorWidth = getVectorWidth();
716 const Value *Pointer = Load->getPointerOperand();
717 VectorType *VectorType = VectorType::get(
718 dyn_cast<PointerType>(Pointer->getType())->getElementType(), VectorWidth);
719
720 Value *Vector = UndefValue::get(VectorType);
721
722 for (int i = 0; i < VectorWidth; i++) {
Tobias Grosser55d52082012-03-02 15:20:39 +0000723 Value *NewPointer = getNewValue(Pointer, ScalarMaps[i], GlobalMaps[i]);
Tobias Grosser80998e72012-03-02 11:27:28 +0000724 Value *ScalarLoad = Builder.CreateLoad(NewPointer,
725 Load->getName() + "_p_scalar_");
726 Vector = Builder.CreateInsertElement(Vector, ScalarLoad,
727 Builder.getInt32(i),
728 Load->getName() + "_p_vec_");
729 }
730
731 return Vector;
732}
733
734void VectorBlockGenerator::generateLoad(const LoadInst *Load,
735 ValueMapT &VectorMap,
736 VectorValueMapT &ScalarMaps) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000737 Value *NewLoad;
738
739 MemoryAccess &Access = Statement.getAccessFor(Load);
740
Tobias Grosser08a82382012-03-02 15:20:24 +0000741 if (Access.isStrideZero(isl_set_copy(Domain)))
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000742 NewLoad = generateStrideZeroLoad(Load, ScalarMaps[0]);
Tobias Grosser08a82382012-03-02 15:20:24 +0000743 else if (Access.isStrideOne(isl_set_copy(Domain)))
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000744 NewLoad = generateStrideOneLoad(Load, ScalarMaps[0]);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000745 else
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000746 NewLoad = generateUnknownStrideLoad(Load, ScalarMaps);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000747
748 VectorMap[Load] = NewLoad;
749}
750
Tobias Grosser80998e72012-03-02 11:27:28 +0000751void VectorBlockGenerator::copyUnaryInst(const UnaryInstruction *Inst,
Tobias Grosserdf382372012-03-02 15:20:35 +0000752 ValueMapT &VectorMap,
753 VectorValueMapT &ScalarMaps) {
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000754 int VectorWidth = getVectorWidth();
Tobias Grosser55d52082012-03-02 15:20:39 +0000755 Value *NewOperand = getVectorValue(Inst->getOperand(0), VectorMap,
756 ScalarMaps);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000757
758 assert(isa<CastInst>(Inst) && "Can not generate vector code for instruction");
759
760 const CastInst *Cast = dyn_cast<CastInst>(Inst);
761 VectorType *DestType = VectorType::get(Inst->getType(), VectorWidth);
762 VectorMap[Inst] = Builder.CreateCast(Cast->getOpcode(), NewOperand, DestType);
763}
764
Tobias Grosser80998e72012-03-02 11:27:28 +0000765void VectorBlockGenerator::copyBinaryInst(const BinaryOperator *Inst,
Tobias Grosserdf382372012-03-02 15:20:35 +0000766 ValueMapT &VectorMap,
767 VectorValueMapT &ScalarMaps) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000768 Value *OpZero = Inst->getOperand(0);
769 Value *OpOne = Inst->getOperand(1);
770
771 Value *NewOpZero, *NewOpOne;
Tobias Grosser55d52082012-03-02 15:20:39 +0000772 NewOpZero = getVectorValue(OpZero, VectorMap, ScalarMaps);
773 NewOpOne = getVectorValue(OpOne, VectorMap, ScalarMaps);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000774
775 Value *NewInst = Builder.CreateBinOp(Inst->getOpcode(), NewOpZero,
776 NewOpOne,
777 Inst->getName() + "p_vec");
778 VectorMap[Inst] = NewInst;
779}
780
Tobias Grosserdf382372012-03-02 15:20:35 +0000781void VectorBlockGenerator::copyStore(const StoreInst *Store,
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000782 ValueMapT &VectorMap,
Tobias Grosser8927a442012-03-02 11:27:05 +0000783 VectorValueMapT &ScalarMaps) {
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000784 int VectorWidth = getVectorWidth();
785
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000786 MemoryAccess &Access = Statement.getAccessFor(Store);
787
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000788 const Value *Pointer = Store->getPointerOperand();
Tobias Grosser55d52082012-03-02 15:20:39 +0000789 Value *Vector = getVectorValue(Store->getValueOperand(), VectorMap,
Tobias Grosserdf382372012-03-02 15:20:35 +0000790 ScalarMaps);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000791
Tobias Grosser08a82382012-03-02 15:20:24 +0000792 if (Access.isStrideOne(isl_set_copy(Domain))) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000793 Type *VectorPtrType = getVectorPtrTy(Pointer, VectorWidth);
Tobias Grosser55d52082012-03-02 15:20:39 +0000794 Value *NewPointer = getNewValue(Pointer, ScalarMaps[0], GlobalMaps[0]);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000795
796 Value *VectorPtr = Builder.CreateBitCast(NewPointer, VectorPtrType,
797 "vector_ptr");
798 StoreInst *Store = Builder.CreateStore(Vector, VectorPtr);
799
800 if (!Aligned)
801 Store->setAlignment(8);
802 } else {
803 for (unsigned i = 0; i < ScalarMaps.size(); i++) {
804 Value *Scalar = Builder.CreateExtractElement(Vector,
805 Builder.getInt32(i));
Tobias Grosser55d52082012-03-02 15:20:39 +0000806 Value *NewPointer = getNewValue(Pointer, ScalarMaps[i], GlobalMaps[i]);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000807 Builder.CreateStore(Scalar, NewPointer);
808 }
809 }
810}
811
Tobias Grosser80998e72012-03-02 11:27:28 +0000812bool VectorBlockGenerator::hasVectorOperands(const Instruction *Inst,
813 ValueMapT &VectorMap) {
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000814 for (Instruction::const_op_iterator OI = Inst->op_begin(),
815 OE = Inst->op_end(); OI != OE; ++OI)
816 if (VectorMap.count(*OI))
817 return true;
818 return false;
819}
820
Tobias Grosser80998e72012-03-02 11:27:28 +0000821int VectorBlockGenerator::getVectorWidth() {
Tobias Grosserdf382372012-03-02 15:20:35 +0000822 return GlobalMaps.size();
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000823}
824
Tobias Grosser80998e72012-03-02 11:27:28 +0000825void VectorBlockGenerator::copyInstruction(const Instruction *Inst,
Tobias Grosser32152cb2012-03-02 11:27:18 +0000826 ValueMapT &VectorMap,
827 VectorValueMapT &ScalarMaps) {
Tobias Grosser80998e72012-03-02 11:27:28 +0000828 // Terminator instructions control the control flow. They are explicitly
829 // expressed in the clast and do not need to be copied.
830 if (Inst->isTerminator())
831 return;
832
Tobias Grosser32152cb2012-03-02 11:27:18 +0000833 if (const LoadInst *Load = dyn_cast<LoadInst>(Inst)) {
Tobias Grosser80998e72012-03-02 11:27:28 +0000834 generateLoad(Load, VectorMap, ScalarMaps);
Tobias Grosser32152cb2012-03-02 11:27:18 +0000835 return;
836 }
837
838 if (hasVectorOperands(Inst, VectorMap)) {
839 if (const StoreInst *Store = dyn_cast<StoreInst>(Inst)) {
Tobias Grosserdf382372012-03-02 15:20:35 +0000840 copyStore(Store, VectorMap, ScalarMaps);
Tobias Grosser32152cb2012-03-02 11:27:18 +0000841 return;
842 }
843
844 if (const UnaryInstruction *Unary = dyn_cast<UnaryInstruction>(Inst)) {
Tobias Grosserdf382372012-03-02 15:20:35 +0000845 copyUnaryInst(Unary, VectorMap, ScalarMaps);
Tobias Grosser32152cb2012-03-02 11:27:18 +0000846 return;
847 }
848
849 if (const BinaryOperator *Binary = dyn_cast<BinaryOperator>(Inst)) {
Tobias Grosserdf382372012-03-02 15:20:35 +0000850 copyBinaryInst(Binary, VectorMap, ScalarMaps);
Tobias Grosser32152cb2012-03-02 11:27:18 +0000851 return;
852 }
853
854 llvm_unreachable("Cannot issue vector code for this instruction");
855 }
856
857 for (int VectorLane = 0; VectorLane < getVectorWidth(); VectorLane++)
Tobias Grosserdf382372012-03-02 15:20:35 +0000858 copyInstScalar(Inst, ScalarMaps[VectorLane], GlobalMaps[VectorLane]);
Tobias Grosser32152cb2012-03-02 11:27:18 +0000859}
860
Tobias Grosser80998e72012-03-02 11:27:28 +0000861void VectorBlockGenerator::copyBB() {
Tobias Grosser14bcbd52012-03-02 11:26:52 +0000862 BasicBlock *BB = Statement.getBasicBlock();
Tobias Grosser0ac92142012-02-14 14:02:27 +0000863 BasicBlock *CopyBB = SplitBlock(Builder.GetInsertBlock(),
864 Builder.GetInsertPoint(), P);
Tobias Grosserb61e6312012-02-15 09:58:46 +0000865 CopyBB->setName("polly.stmt." + BB->getName());
Tobias Grosser0ac92142012-02-14 14:02:27 +0000866 Builder.SetInsertPoint(CopyBB->begin());
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000867
868 // Create two maps that store the mapping from the original instructions of
869 // the old basic block to their copies in the new basic block. Those maps
870 // are basic block local.
871 //
872 // As vector code generation is supported there is one map for scalar values
873 // and one for vector values.
874 //
875 // In case we just do scalar code generation, the vectorMap is not used and
876 // the scalarMap has just one dimension, which contains the mapping.
877 //
878 // In case vector code generation is done, an instruction may either appear
879 // in the vector map once (as it is calculating >vectorwidth< values at a
880 // time. Or (if the values are calculated using scalar operations), it
881 // appears once in every dimension of the scalarMap.
Tobias Grosserf81a691e2012-03-02 11:27:02 +0000882 VectorValueMapT ScalarBlockMap(getVectorWidth());
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000883 ValueMapT VectorBlockMap;
884
885 for (BasicBlock::const_iterator II = BB->begin(), IE = BB->end();
886 II != IE; ++II)
Tobias Grosserfc1153f2012-03-02 11:27:15 +0000887 copyInstruction(II, VectorBlockMap, ScalarBlockMap);
Tobias Grosser70e8cdb2012-01-24 16:42:21 +0000888}
889
Tobias Grosser75805372011-04-29 06:27:02 +0000890/// Class to generate LLVM-IR that calculates the value of a clast_expr.
891class ClastExpCodeGen {
892 IRBuilder<> &Builder;
893 const CharMapT *IVS;
894
Tobias Grosserbb137e32012-01-24 16:42:28 +0000895 Value *codegen(const clast_name *e, Type *Ty);
896 Value *codegen(const clast_term *e, Type *Ty);
897 Value *codegen(const clast_binary *e, Type *Ty);
898 Value *codegen(const clast_reduction *r, Type *Ty);
Tobias Grosser75805372011-04-29 06:27:02 +0000899public:
900
901 // A generator for clast expressions.
902 //
903 // @param B The IRBuilder that defines where the code to calculate the
904 // clast expressions should be inserted.
905 // @param IVMAP A Map that translates strings describing the induction
906 // variables to the Values* that represent these variables
907 // on the LLVM side.
Tobias Grosserbb137e32012-01-24 16:42:28 +0000908 ClastExpCodeGen(IRBuilder<> &B, CharMapT *IVMap);
Tobias Grosser75805372011-04-29 06:27:02 +0000909
910 // Generates code to calculate a given clast expression.
911 //
912 // @param e The expression to calculate.
913 // @return The Value that holds the result.
Tobias Grosserbb137e32012-01-24 16:42:28 +0000914 Value *codegen(const clast_expr *e, Type *Ty);
Tobias Grosser75805372011-04-29 06:27:02 +0000915
916 // @brief Reset the CharMap.
917 //
918 // This function is called to reset the CharMap to new one, while generating
919 // OpenMP code.
Tobias Grosserbb137e32012-01-24 16:42:28 +0000920 void setIVS(CharMapT *IVSNew);
921};
922
923Value *ClastExpCodeGen::codegen(const clast_name *e, Type *Ty) {
924 CharMapT::const_iterator I = IVS->find(e->name);
925
926 assert(I != IVS->end() && "Clast name not found");
927
928 return Builder.CreateSExtOrBitCast(I->second, Ty);
929}
930
931Value *ClastExpCodeGen::codegen(const clast_term *e, Type *Ty) {
932 APInt a = APInt_from_MPZ(e->val);
933
934 Value *ConstOne = ConstantInt::get(Builder.getContext(), a);
935 ConstOne = Builder.CreateSExtOrBitCast(ConstOne, Ty);
936
937 if (!e->var)
938 return ConstOne;
939
940 Value *var = codegen(e->var, Ty);
941 return Builder.CreateMul(ConstOne, var);
942}
943
944Value *ClastExpCodeGen::codegen(const clast_binary *e, Type *Ty) {
945 Value *LHS = codegen(e->LHS, Ty);
946
947 APInt RHS_AP = APInt_from_MPZ(e->RHS);
948
949 Value *RHS = ConstantInt::get(Builder.getContext(), RHS_AP);
950 RHS = Builder.CreateSExtOrBitCast(RHS, Ty);
951
952 switch (e->type) {
953 case clast_bin_mod:
954 return Builder.CreateSRem(LHS, RHS);
955 case clast_bin_fdiv:
956 {
Tobias Grosser9a44b972012-02-16 14:13:19 +0000957 // floord(n,d) ((n < 0) ? (n - d + 1) : n) / d
Tobias Grosser906eafe2012-02-16 09:56:10 +0000958 Value *One = ConstantInt::get(Ty, 1);
959 Value *Zero = ConstantInt::get(Ty, 0);
Tobias Grosser9a44b972012-02-16 14:13:19 +0000960 Value *Sum1 = Builder.CreateSub(LHS, RHS);
961 Value *Sum2 = Builder.CreateAdd(Sum1, One);
962 Value *isNegative = Builder.CreateICmpSLT(LHS, Zero);
963 Value *Dividend = Builder.CreateSelect(isNegative, Sum2, LHS);
964 return Builder.CreateSDiv(Dividend, RHS);
Tobias Grosserbb137e32012-01-24 16:42:28 +0000965 }
966 case clast_bin_cdiv:
967 {
Tobias Grosser9a44b972012-02-16 14:13:19 +0000968 // ceild(n,d) ((n < 0) ? n : (n + d - 1)) / d
969 Value *One = ConstantInt::get(Ty, 1);
Tobias Grosser906eafe2012-02-16 09:56:10 +0000970 Value *Zero = ConstantInt::get(Ty, 0);
Tobias Grosser9a44b972012-02-16 14:13:19 +0000971 Value *Sum1 = Builder.CreateAdd(LHS, RHS);
972 Value *Sum2 = Builder.CreateSub(Sum1, One);
973 Value *isNegative = Builder.CreateICmpSLT(LHS, Zero);
974 Value *Dividend = Builder.CreateSelect(isNegative, LHS, Sum2);
975 return Builder.CreateSDiv(Dividend, RHS);
Tobias Grosserbb137e32012-01-24 16:42:28 +0000976 }
977 case clast_bin_div:
978 return Builder.CreateSDiv(LHS, RHS);
979 };
980
981 llvm_unreachable("Unknown clast binary expression type");
982}
983
984Value *ClastExpCodeGen::codegen(const clast_reduction *r, Type *Ty) {
985 assert(( r->type == clast_red_min
986 || r->type == clast_red_max
987 || r->type == clast_red_sum)
988 && "Clast reduction type not supported");
989 Value *old = codegen(r->elts[0], Ty);
990
991 for (int i=1; i < r->n; ++i) {
992 Value *exprValue = codegen(r->elts[i], Ty);
993
994 switch (r->type) {
995 case clast_red_min:
996 {
997 Value *cmp = Builder.CreateICmpSLT(old, exprValue);
998 old = Builder.CreateSelect(cmp, old, exprValue);
999 break;
1000 }
1001 case clast_red_max:
1002 {
1003 Value *cmp = Builder.CreateICmpSGT(old, exprValue);
1004 old = Builder.CreateSelect(cmp, old, exprValue);
1005 break;
1006 }
1007 case clast_red_sum:
1008 old = Builder.CreateAdd(old, exprValue);
1009 break;
Tobias Grosserbb137e32012-01-24 16:42:28 +00001010 }
Tobias Grosser75805372011-04-29 06:27:02 +00001011 }
1012
Tobias Grosserbb137e32012-01-24 16:42:28 +00001013 return old;
1014}
1015
1016ClastExpCodeGen::ClastExpCodeGen(IRBuilder<> &B, CharMapT *IVMap)
1017 : Builder(B), IVS(IVMap) {}
1018
1019Value *ClastExpCodeGen::codegen(const clast_expr *e, Type *Ty) {
1020 switch(e->type) {
1021 case clast_expr_name:
1022 return codegen((const clast_name *)e, Ty);
1023 case clast_expr_term:
1024 return codegen((const clast_term *)e, Ty);
1025 case clast_expr_bin:
1026 return codegen((const clast_binary *)e, Ty);
1027 case clast_expr_red:
1028 return codegen((const clast_reduction *)e, Ty);
1029 }
1030
1031 llvm_unreachable("Unknown clast expression!");
1032}
1033
1034void ClastExpCodeGen::setIVS(CharMapT *IVSNew) {
1035 IVS = IVSNew;
1036}
Tobias Grosser75805372011-04-29 06:27:02 +00001037
1038class ClastStmtCodeGen {
1039 // The Scop we code generate.
1040 Scop *S;
Tobias Grosser0ac92142012-02-14 14:02:27 +00001041 Pass *P;
Tobias Grosser75805372011-04-29 06:27:02 +00001042
1043 // The Builder specifies the current location to code generate at.
1044 IRBuilder<> &Builder;
1045
1046 // Map the Values from the old code to their counterparts in the new code.
1047 ValueMapT ValueMap;
1048
1049 // clastVars maps from the textual representation of a clast variable to its
1050 // current *Value. clast variables are scheduling variables, original
1051 // induction variables or parameters. They are used either in loop bounds or
1052 // to define the statement instance that is executed.
1053 //
1054 // for (s = 0; s < n + 3; ++i)
1055 // for (t = s; t < m; ++j)
1056 // Stmt(i = s + 3 * m, j = t);
1057 //
1058 // {s,t,i,j,n,m} is the set of clast variables in this clast.
Tobias Grosser46fc9ca2012-03-23 08:24:10 +00001059 CharMapT *ClastVars;
Tobias Grosser75805372011-04-29 06:27:02 +00001060
1061 // Codegenerator for clast expressions.
1062 ClastExpCodeGen ExpGen;
1063
1064 // Do we currently generate parallel code?
1065 bool parallelCodeGeneration;
1066
1067 std::vector<std::string> parallelLoops;
1068
1069public:
1070
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001071 const std::vector<std::string> &getParallelLoops();
Tobias Grosser75805372011-04-29 06:27:02 +00001072
1073 protected:
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001074 void codegen(const clast_assignment *a);
Tobias Grosser75805372011-04-29 06:27:02 +00001075
1076 void codegen(const clast_assignment *a, ScopStmt *Statement,
1077 unsigned Dimension, int vectorDim,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001078 std::vector<ValueMapT> *VectorVMap = 0);
Tobias Grosser75805372011-04-29 06:27:02 +00001079
1080 void codegenSubstitutions(const clast_stmt *Assignment,
1081 ScopStmt *Statement, int vectorDim = 0,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001082 std::vector<ValueMapT> *VectorVMap = 0);
Tobias Grosser75805372011-04-29 06:27:02 +00001083
1084 void codegen(const clast_user_stmt *u, std::vector<Value*> *IVS = NULL,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001085 const char *iterator = NULL, isl_set *scatteringDomain = 0);
Tobias Grosser75805372011-04-29 06:27:02 +00001086
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001087 void codegen(const clast_block *b);
Tobias Grosser75805372011-04-29 06:27:02 +00001088
1089 /// @brief Create a classical sequential loop.
Tobias Grosser545bc312011-12-06 10:48:27 +00001090 void codegenForSequential(const clast_for *f, Value *LowerBound = 0,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001091 Value *UpperBound = 0);
Tobias Grosser75805372011-04-29 06:27:02 +00001092
Tobias Grosser75805372011-04-29 06:27:02 +00001093 /// @brief Add a new definition of an openmp subfunction.
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001094 Function *addOpenMPSubfunction(Module *M);
Tobias Grosser75805372011-04-29 06:27:02 +00001095
1096 /// @brief Add values to the OpenMP structure.
1097 ///
1098 /// Create the subfunction structure and add the values from the list.
1099 Value *addValuesToOpenMPStruct(SetVector<Value*> OMPDataVals,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001100 Function *SubFunction);
Tobias Grosser75805372011-04-29 06:27:02 +00001101
1102 /// @brief Create OpenMP structure values.
1103 ///
1104 /// Create a list of values that has to be stored into the subfuncition
1105 /// structure.
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001106 SetVector<Value*> createOpenMPStructValues();
Tobias Grosser75805372011-04-29 06:27:02 +00001107
1108 /// @brief Extract the values from the subfunction parameter.
1109 ///
1110 /// Extract the values from the subfunction parameter and update the clast
1111 /// variables to point to the new values.
1112 void extractValuesFromOpenMPStruct(CharMapT *clastVarsOMP,
1113 SetVector<Value*> OMPDataVals,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001114 Value *userContext);
Tobias Grosser75805372011-04-29 06:27:02 +00001115
1116 /// @brief Add body to the subfunction.
1117 void addOpenMPSubfunctionBody(Function *FN, const clast_for *f,
1118 Value *structData,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001119 SetVector<Value*> OMPDataVals);
Tobias Grosser75805372011-04-29 06:27:02 +00001120
1121 /// @brief Create an OpenMP parallel for loop.
1122 ///
1123 /// This loop reflects a loop as if it would have been created by an OpenMP
1124 /// statement.
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001125 void codegenForOpenMP(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +00001126
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001127 bool isInnermostLoop(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +00001128
1129 /// @brief Get the number of loop iterations for this loop.
1130 /// @param f The clast for loop to check.
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001131 int getNumberOfIterations(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +00001132
1133 /// @brief Create vector instructions for this loop.
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001134 void codegenForVector(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +00001135
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001136 void codegen(const clast_for *f);
Tobias Grosser75805372011-04-29 06:27:02 +00001137
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001138 Value *codegen(const clast_equation *eq);
Tobias Grosser75805372011-04-29 06:27:02 +00001139
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001140 void codegen(const clast_guard *g);
Tobias Grosser75805372011-04-29 06:27:02 +00001141
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001142 void codegen(const clast_stmt *stmt);
Tobias Grosser75805372011-04-29 06:27:02 +00001143
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001144 void addParameters(const CloogNames *names);
Tobias Grosser75805372011-04-29 06:27:02 +00001145
Tobias Grossere9ffea22012-03-15 09:34:48 +00001146 IntegerType *getIntPtrTy();
1147
Tobias Grosser75805372011-04-29 06:27:02 +00001148 public:
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001149 void codegen(const clast_root *r);
Tobias Grosser75805372011-04-29 06:27:02 +00001150
Tobias Grosserd596b372012-03-15 09:34:52 +00001151 ClastStmtCodeGen(Scop *scop, IRBuilder<> &B, Pass *P);
Tobias Grosser75805372011-04-29 06:27:02 +00001152};
1153}
1154
Tobias Grossere9ffea22012-03-15 09:34:48 +00001155IntegerType *ClastStmtCodeGen::getIntPtrTy() {
1156 return P->getAnalysis<TargetData>().getIntPtrType(Builder.getContext());
1157}
1158
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001159const std::vector<std::string> &ClastStmtCodeGen::getParallelLoops() {
1160 return parallelLoops;
1161}
1162
1163void ClastStmtCodeGen::codegen(const clast_assignment *a) {
Tobias Grossere9ffea22012-03-15 09:34:48 +00001164 Value *V= ExpGen.codegen(a->RHS, getIntPtrTy());
Tobias Grosser46fc9ca2012-03-23 08:24:10 +00001165 (*ClastVars)[a->LHS] = V;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001166}
1167
1168void ClastStmtCodeGen::codegen(const clast_assignment *a, ScopStmt *Statement,
1169 unsigned Dimension, int vectorDim,
1170 std::vector<ValueMapT> *VectorVMap) {
Tobias Grossere9ffea22012-03-15 09:34:48 +00001171 Value *RHS = ExpGen.codegen(a->RHS, getIntPtrTy());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001172
1173 assert(!a->LHS && "Statement assignments do not have left hand side");
1174 const PHINode *PN;
1175 PN = Statement->getInductionVariableForDimension(Dimension);
1176 const Value *V = PN;
1177
1178 if (VectorVMap)
1179 (*VectorVMap)[vectorDim][V] = RHS;
1180
1181 ValueMap[V] = RHS;
1182}
1183
1184void ClastStmtCodeGen::codegenSubstitutions(const clast_stmt *Assignment,
1185 ScopStmt *Statement, int vectorDim,
1186 std::vector<ValueMapT> *VectorVMap) {
1187 int Dimension = 0;
1188
1189 while (Assignment) {
1190 assert(CLAST_STMT_IS_A(Assignment, stmt_ass)
1191 && "Substitions are expected to be assignments");
1192 codegen((const clast_assignment *)Assignment, Statement, Dimension,
1193 vectorDim, VectorVMap);
1194 Assignment = Assignment->next;
1195 Dimension++;
1196 }
1197}
1198
1199void ClastStmtCodeGen::codegen(const clast_user_stmt *u,
1200 std::vector<Value*> *IVS , const char *iterator,
Tobias Grosser14bcbd52012-03-02 11:26:52 +00001201 isl_set *Domain) {
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001202 ScopStmt *Statement = (ScopStmt *)u->statement->usr;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001203
1204 if (u->substitutions)
1205 codegenSubstitutions(u->substitutions, Statement);
1206
Tobias Grosser80998e72012-03-02 11:27:28 +00001207 int VectorDimensions = IVS ? IVS->size() : 1;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001208
Tobias Grosser80998e72012-03-02 11:27:28 +00001209 if (VectorDimensions == 1) {
Tobias Grosser55d52082012-03-02 15:20:39 +00001210 BlockGenerator::generate(Builder, *Statement, ValueMap, P);
Tobias Grosser80998e72012-03-02 11:27:28 +00001211 return;
1212 }
1213
1214 VectorValueMapT VectorMap(VectorDimensions);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001215
1216 if (IVS) {
1217 assert (u->substitutions && "Substitutions expected!");
1218 int i = 0;
1219 for (std::vector<Value*>::iterator II = IVS->begin(), IE = IVS->end();
1220 II != IE; ++II) {
Tobias Grosser46fc9ca2012-03-23 08:24:10 +00001221 (*ClastVars)[iterator] = *II;
Tobias Grosser14bcbd52012-03-02 11:26:52 +00001222 codegenSubstitutions(u->substitutions, Statement, i, &VectorMap);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001223 i++;
1224 }
1225 }
1226
Tobias Grosser55d52082012-03-02 15:20:39 +00001227 VectorBlockGenerator::generate(Builder, *Statement, VectorMap, Domain, P);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001228}
1229
1230void ClastStmtCodeGen::codegen(const clast_block *b) {
1231 if (b->body)
1232 codegen(b->body);
1233}
1234
1235void ClastStmtCodeGen::codegenForSequential(const clast_for *f,
1236 Value *LowerBound,
1237 Value *UpperBound) {
Tobias Grosser0ac92142012-02-14 14:02:27 +00001238 BasicBlock *AfterBB;
Tobias Grossere9ffea22012-03-15 09:34:48 +00001239 Type *IntPtrTy = getIntPtrTy();
1240 APInt Stride = APInt_from_MPZ(f->stride);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001241
1242 // The value of lowerbound and upperbound will be supplied, if this
1243 // function is called while generating OpenMP code. Otherwise get
1244 // the values.
1245 assert(!!LowerBound == !!UpperBound && "Either give both bounds or none");
1246
1247 if (LowerBound == 0) {
1248 LowerBound = ExpGen.codegen(f->LB, IntPtrTy);
1249 UpperBound = ExpGen.codegen(f->UB, IntPtrTy);
1250 }
1251
Tobias Grosserd596b372012-03-15 09:34:52 +00001252 Value *IV = createLoop(&Builder, LowerBound, UpperBound, Stride, P, &AfterBB);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001253
1254 // Add loop iv to symbols.
Tobias Grosser46fc9ca2012-03-23 08:24:10 +00001255 (*ClastVars)[f->iterator] = IV;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001256
1257 if (f->body)
1258 codegen(f->body);
1259
1260 // Loop is finished, so remove its iv from the live symbols.
Tobias Grosser46fc9ca2012-03-23 08:24:10 +00001261 ClastVars->erase(f->iterator);
Tobias Grosser0ac92142012-02-14 14:02:27 +00001262 Builder.SetInsertPoint(AfterBB->begin());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001263}
1264
1265Function *ClastStmtCodeGen::addOpenMPSubfunction(Module *M) {
1266 Function *F = Builder.GetInsertBlock()->getParent();
1267 std::vector<Type*> Arguments(1, Builder.getInt8PtrTy());
1268 FunctionType *FT = FunctionType::get(Builder.getVoidTy(), Arguments, false);
1269 Function *FN = Function::Create(FT, Function::InternalLinkage,
1270 F->getName() + ".omp_subfn", M);
1271 // Do not run any polly pass on the new function.
Tobias Grosserd596b372012-03-15 09:34:52 +00001272 P->getAnalysis<ScopDetection>().markFunctionAsInvalid(FN);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001273
1274 Function::arg_iterator AI = FN->arg_begin();
1275 AI->setName("omp.userContext");
1276
1277 return FN;
1278}
1279
1280Value *ClastStmtCodeGen::addValuesToOpenMPStruct(SetVector<Value*> OMPDataVals,
1281 Function *SubFunction) {
1282 std::vector<Type*> structMembers;
1283
1284 // Create the structure.
1285 for (unsigned i = 0; i < OMPDataVals.size(); i++)
1286 structMembers.push_back(OMPDataVals[i]->getType());
1287
1288 StructType *structTy = StructType::get(Builder.getContext(),
1289 structMembers);
1290 // Store the values into the structure.
1291 Value *structData = Builder.CreateAlloca(structTy, 0, "omp.userContext");
1292 for (unsigned i = 0; i < OMPDataVals.size(); i++) {
1293 Value *storeAddr = Builder.CreateStructGEP(structData, i);
1294 Builder.CreateStore(OMPDataVals[i], storeAddr);
1295 }
1296
1297 return structData;
1298}
1299
1300SetVector<Value*> ClastStmtCodeGen::createOpenMPStructValues() {
1301 SetVector<Value*> OMPDataVals;
1302
1303 // Push the clast variables available in the clastVars.
Tobias Grosser46fc9ca2012-03-23 08:24:10 +00001304 for (CharMapT::iterator I = ClastVars->begin(), E = ClastVars->end();
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001305 I != E; I++)
1306 OMPDataVals.insert(I->second);
1307
1308 // Push the base addresses of memory references.
1309 for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI) {
1310 ScopStmt *Stmt = *SI;
1311 for (SmallVector<MemoryAccess*, 8>::iterator I = Stmt->memacc_begin(),
1312 E = Stmt->memacc_end(); I != E; ++I) {
1313 Value *BaseAddr = const_cast<Value*>((*I)->getBaseAddr());
1314 OMPDataVals.insert((BaseAddr));
1315 }
1316 }
1317
1318 return OMPDataVals;
1319}
1320
1321void ClastStmtCodeGen::extractValuesFromOpenMPStruct(CharMapT *clastVarsOMP,
1322 SetVector<Value*> OMPDataVals, Value *userContext) {
1323 // Extract the clast variables.
1324 unsigned i = 0;
Tobias Grosser46fc9ca2012-03-23 08:24:10 +00001325 for (CharMapT::iterator I = ClastVars->begin(), E = ClastVars->end();
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001326 I != E; I++) {
1327 Value *loadAddr = Builder.CreateStructGEP(userContext, i);
1328 (*clastVarsOMP)[I->first] = Builder.CreateLoad(loadAddr);
1329 i++;
1330 }
1331
1332 // Extract the base addresses of memory references.
1333 for (unsigned j = i; j < OMPDataVals.size(); j++) {
1334 Value *loadAddr = Builder.CreateStructGEP(userContext, j);
1335 Value *baseAddr = OMPDataVals[j];
1336 ValueMap[baseAddr] = Builder.CreateLoad(loadAddr);
1337 }
1338}
1339
1340void ClastStmtCodeGen::addOpenMPSubfunctionBody(Function *FN,
1341 const clast_for *f,
Tobias Grosser46fc9ca2012-03-23 08:24:10 +00001342 Value *StructData,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001343 SetVector<Value*> OMPDataVals) {
Tobias Grossere9ffea22012-03-15 09:34:48 +00001344 Type *IntPtrTy = getIntPtrTy();
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001345 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
1346 LLVMContext &Context = FN->getContext();
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001347
1348 // Store the previous basic block.
Tobias Grosser0ac92142012-02-14 14:02:27 +00001349 BasicBlock::iterator PrevInsertPoint = Builder.GetInsertPoint();
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001350 BasicBlock *PrevBB = Builder.GetInsertBlock();
1351
1352 // Create basic blocks.
1353 BasicBlock *HeaderBB = BasicBlock::Create(Context, "omp.setup", FN);
1354 BasicBlock *ExitBB = BasicBlock::Create(Context, "omp.exit", FN);
Tobias Grosser46fc9ca2012-03-23 08:24:10 +00001355 BasicBlock *CheckNextBB = BasicBlock::Create(Context, "omp.checkNext", FN);
1356 BasicBlock *LoadIVBoundsBB = BasicBlock::Create(Context, "omp.loadIVBounds",
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001357 FN);
1358
Tobias Grosserd596b372012-03-15 09:34:52 +00001359 DominatorTree &DT = P->getAnalysis<DominatorTree>();
1360 DT.addNewBlock(HeaderBB, PrevBB);
1361 DT.addNewBlock(ExitBB, HeaderBB);
Tobias Grosser46fc9ca2012-03-23 08:24:10 +00001362 DT.addNewBlock(CheckNextBB, HeaderBB);
1363 DT.addNewBlock(LoadIVBoundsBB, HeaderBB);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001364
1365 // Fill up basic block HeaderBB.
1366 Builder.SetInsertPoint(HeaderBB);
Tobias Grosser46fc9ca2012-03-23 08:24:10 +00001367 Value *LowerBoundPtr = Builder.CreateAlloca(IntPtrTy, 0, "omp.lowerBoundPtr");
1368 Value *UpperBoundPtr = Builder.CreateAlloca(IntPtrTy, 0, "omp.upperBoundPtr");
1369 Value *UserContext = Builder.CreateBitCast(FN->arg_begin(),
1370 StructData->getType(),
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001371 "omp.userContext");
1372
Tobias Grosser46fc9ca2012-03-23 08:24:10 +00001373 CharMapT ClastVarsOMP;
1374 extractValuesFromOpenMPStruct(&ClastVarsOMP, OMPDataVals, UserContext);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001375
Tobias Grosser46fc9ca2012-03-23 08:24:10 +00001376 Builder.CreateBr(CheckNextBB);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001377
1378 // Add code to check if another set of iterations will be executed.
Tobias Grosser46fc9ca2012-03-23 08:24:10 +00001379 Builder.SetInsertPoint(CheckNextBB);
1380 Function *RuntimeNextFunction = M->getFunction("GOMP_loop_runtime_next");
1381 Value *Ret1 = Builder.CreateCall2(RuntimeNextFunction,
1382 LowerBoundPtr, UpperBoundPtr);
1383 Value *HasNextSchedule = Builder.CreateTrunc(Ret1, Builder.getInt1Ty(),
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001384 "omp.hasNextScheduleBlock");
Tobias Grosser46fc9ca2012-03-23 08:24:10 +00001385 Builder.CreateCondBr(HasNextSchedule, LoadIVBoundsBB, ExitBB);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001386
1387 // Add code to to load the iv bounds for this set of iterations.
Tobias Grosser46fc9ca2012-03-23 08:24:10 +00001388 Builder.SetInsertPoint(LoadIVBoundsBB);
1389 Value *LowerBound = Builder.CreateLoad(LowerBoundPtr, "omp.lowerBound");
1390 Value *UpperBound = Builder.CreateLoad(UpperBoundPtr, "omp.upperBound");
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001391
1392 // Subtract one as the upper bound provided by openmp is a < comparison
1393 // whereas the codegenForSequential function creates a <= comparison.
Tobias Grosser46fc9ca2012-03-23 08:24:10 +00001394 UpperBound = Builder.CreateSub(UpperBound, ConstantInt::get(IntPtrTy, 1),
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001395 "omp.upperBoundAdjusted");
1396
1397 // Use clastVarsOMP during code generation of the OpenMP subfunction.
Tobias Grosser46fc9ca2012-03-23 08:24:10 +00001398 CharMapT *OldClastVars = ClastVars;
1399 ClastVars = &ClastVarsOMP;
1400 ExpGen.setIVS(&ClastVarsOMP);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001401
Tobias Grosser46fc9ca2012-03-23 08:24:10 +00001402 Builder.CreateBr(CheckNextBB);
Tobias Grosser0ac92142012-02-14 14:02:27 +00001403 Builder.SetInsertPoint(--Builder.GetInsertPoint());
Tobias Grosser46fc9ca2012-03-23 08:24:10 +00001404 codegenForSequential(f, LowerBound, UpperBound);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001405
1406 // Restore the old clastVars.
Tobias Grosser46fc9ca2012-03-23 08:24:10 +00001407 ClastVars = OldClastVars;
1408 ExpGen.setIVS(OldClastVars);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001409
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001410 // Add code to terminate this openmp subfunction.
1411 Builder.SetInsertPoint(ExitBB);
Tobias Grosser46fc9ca2012-03-23 08:24:10 +00001412 Function *EndnowaitFunction = M->getFunction("GOMP_loop_end_nowait");
1413 Builder.CreateCall(EndnowaitFunction);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001414 Builder.CreateRetVoid();
1415
Tobias Grosser0ac92142012-02-14 14:02:27 +00001416 // Restore the previous insert point.
1417 Builder.SetInsertPoint(PrevInsertPoint);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001418}
1419
Tobias Grosser415245d2012-03-02 15:20:17 +00001420void ClastStmtCodeGen::codegenForOpenMP(const clast_for *For) {
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001421 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
Tobias Grossere9ffea22012-03-15 09:34:48 +00001422 IntegerType *IntPtrTy = getIntPtrTy();
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001423
1424 Function *SubFunction = addOpenMPSubfunction(M);
1425 SetVector<Value*> OMPDataVals = createOpenMPStructValues();
Tobias Grosser415245d2012-03-02 15:20:17 +00001426 Value *StructData = addValuesToOpenMPStruct(OMPDataVals, SubFunction);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001427
Tobias Grosser415245d2012-03-02 15:20:17 +00001428 addOpenMPSubfunctionBody(SubFunction, For, StructData, OMPDataVals);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001429
1430 // Create call for GOMP_parallel_loop_runtime_start.
Tobias Grosser415245d2012-03-02 15:20:17 +00001431 Value *SubfunctionParam = Builder.CreateBitCast(StructData,
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001432 Builder.getInt8PtrTy(),
1433 "omp_data");
1434
Tobias Grosser415245d2012-03-02 15:20:17 +00001435 Value *NumberOfThreads = Builder.getInt32(0);
1436 Value *LowerBound = ExpGen.codegen(For->LB, IntPtrTy);
1437 Value *UpperBound = ExpGen.codegen(For->UB, IntPtrTy);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001438
1439 // Add one as the upper bound provided by openmp is a < comparison
1440 // whereas the codegenForSequential function creates a <= comparison.
Tobias Grosser415245d2012-03-02 15:20:17 +00001441 UpperBound = Builder.CreateAdd(UpperBound, ConstantInt::get(IntPtrTy, 1));
1442 APInt APStride = APInt_from_MPZ(For->stride);
1443 Value *Stride = ConstantInt::get(IntPtrTy,
1444 APStride.zext(IntPtrTy->getBitWidth()));
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001445
Tobias Grosser415245d2012-03-02 15:20:17 +00001446 Value *Arguments[] = { SubFunction, SubfunctionParam, NumberOfThreads,
1447 LowerBound, UpperBound, Stride};
1448 Builder.CreateCall(M->getFunction("GOMP_parallel_loop_runtime_start"),
1449 Arguments);
1450 Builder.CreateCall(SubFunction, SubfunctionParam);
1451 Builder.CreateCall(M->getFunction("GOMP_parallel_end"));
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001452}
1453
1454bool ClastStmtCodeGen::isInnermostLoop(const clast_for *f) {
1455 const clast_stmt *stmt = f->body;
1456
1457 while (stmt) {
1458 if (!CLAST_STMT_IS_A(stmt, stmt_user))
1459 return false;
1460
1461 stmt = stmt->next;
1462 }
1463
1464 return true;
1465}
1466
1467int ClastStmtCodeGen::getNumberOfIterations(const clast_for *f) {
1468 isl_set *loopDomain = isl_set_copy(isl_set_from_cloog_domain(f->domain));
1469 isl_set *tmp = isl_set_copy(loopDomain);
1470
1471 // Calculate a map similar to the identity map, but with the last input
1472 // and output dimension not related.
1473 // [i0, i1, i2, i3] -> [i0, i1, i2, o0]
1474 isl_space *Space = isl_set_get_space(loopDomain);
1475 Space = isl_space_drop_outputs(Space,
1476 isl_set_dim(loopDomain, isl_dim_set) - 2, 1);
1477 Space = isl_space_map_from_set(Space);
1478 isl_map *identity = isl_map_identity(Space);
1479 identity = isl_map_add_dims(identity, isl_dim_in, 1);
1480 identity = isl_map_add_dims(identity, isl_dim_out, 1);
1481
1482 isl_map *map = isl_map_from_domain_and_range(tmp, loopDomain);
1483 map = isl_map_intersect(map, identity);
1484
1485 isl_map *lexmax = isl_map_lexmax(isl_map_copy(map));
1486 isl_map *lexmin = isl_map_lexmin(map);
1487 isl_map *sub = isl_map_sum(lexmax, isl_map_neg(lexmin));
1488
1489 isl_set *elements = isl_map_range(sub);
1490
1491 if (!isl_set_is_singleton(elements)) {
1492 isl_set_free(elements);
1493 return -1;
1494 }
1495
1496 isl_point *p = isl_set_sample_point(elements);
1497
1498 isl_int v;
1499 isl_int_init(v);
1500 isl_point_get_coordinate(p, isl_dim_set, isl_set_n_dim(loopDomain) - 1, &v);
1501 int numberIterations = isl_int_get_si(v);
1502 isl_int_clear(v);
1503 isl_point_free(p);
1504
1505 return (numberIterations) / isl_int_get_si(f->stride) + 1;
1506}
1507
Tobias Grosser2da263e2012-03-15 09:34:55 +00001508void ClastStmtCodeGen::codegenForVector(const clast_for *F) {
1509 DEBUG(dbgs() << "Vectorizing loop '" << F->iterator << "'\n";);
1510 int VectorWidth = getNumberOfIterations(F);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001511
Tobias Grosser2da263e2012-03-15 09:34:55 +00001512 Value *LB = ExpGen.codegen(F->LB, getIntPtrTy());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001513
Tobias Grosser2da263e2012-03-15 09:34:55 +00001514 APInt Stride = APInt_from_MPZ(F->stride);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001515 IntegerType *LoopIVType = dyn_cast<IntegerType>(LB->getType());
1516 Stride = Stride.zext(LoopIVType->getBitWidth());
1517 Value *StrideValue = ConstantInt::get(LoopIVType, Stride);
1518
Tobias Grosser2da263e2012-03-15 09:34:55 +00001519 std::vector<Value*> IVS(VectorWidth);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001520 IVS[0] = LB;
1521
Tobias Grosser2da263e2012-03-15 09:34:55 +00001522 for (int i = 1; i < VectorWidth; i++)
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001523 IVS[i] = Builder.CreateAdd(IVS[i-1], StrideValue, "p_vector_iv");
1524
Tobias Grosser00d898d2012-03-15 09:34:58 +00001525 isl_set *Domain = isl_set_from_cloog_domain(F->domain);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001526
1527 // Add loop iv to symbols.
Tobias Grosser46fc9ca2012-03-23 08:24:10 +00001528 (*ClastVars)[F->iterator] = LB;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001529
Tobias Grosser2da263e2012-03-15 09:34:55 +00001530 const clast_stmt *Stmt = F->body;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001531
Tobias Grosser2da263e2012-03-15 09:34:55 +00001532 while (Stmt) {
Tobias Grosser00d898d2012-03-15 09:34:58 +00001533 codegen((const clast_user_stmt *)Stmt, &IVS, F->iterator,
1534 isl_set_copy(Domain));
Tobias Grosser2da263e2012-03-15 09:34:55 +00001535 Stmt = Stmt->next;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001536 }
1537
1538 // Loop is finished, so remove its iv from the live symbols.
Tobias Grosser00d898d2012-03-15 09:34:58 +00001539 isl_set_free(Domain);
Tobias Grosser46fc9ca2012-03-23 08:24:10 +00001540 ClastVars->erase(F->iterator);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001541}
1542
1543void ClastStmtCodeGen::codegen(const clast_for *f) {
Tobias Grosserd596b372012-03-15 09:34:52 +00001544 if ((Vector || OpenMP) && P->getAnalysis<Dependences>().isParallelFor(f)) {
Tobias Grosserce3f5372012-03-02 11:26:42 +00001545 if (Vector && isInnermostLoop(f) && (-1 != getNumberOfIterations(f))
1546 && (getNumberOfIterations(f) <= 16)) {
1547 codegenForVector(f);
1548 return;
1549 }
1550
1551 if (OpenMP && !parallelCodeGeneration) {
1552 parallelCodeGeneration = true;
1553 parallelLoops.push_back(f->iterator);
1554 codegenForOpenMP(f);
1555 parallelCodeGeneration = false;
1556 return;
1557 }
1558 }
1559
1560 codegenForSequential(f);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001561}
1562
1563Value *ClastStmtCodeGen::codegen(const clast_equation *eq) {
Tobias Grossere9ffea22012-03-15 09:34:48 +00001564 Value *LHS = ExpGen.codegen(eq->LHS, getIntPtrTy());
1565 Value *RHS = ExpGen.codegen(eq->RHS, getIntPtrTy());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001566 CmpInst::Predicate P;
1567
1568 if (eq->sign == 0)
1569 P = ICmpInst::ICMP_EQ;
1570 else if (eq->sign > 0)
1571 P = ICmpInst::ICMP_SGE;
1572 else
1573 P = ICmpInst::ICMP_SLE;
1574
1575 return Builder.CreateICmp(P, LHS, RHS);
1576}
1577
1578void ClastStmtCodeGen::codegen(const clast_guard *g) {
1579 Function *F = Builder.GetInsertBlock()->getParent();
1580 LLVMContext &Context = F->getContext();
Tobias Grosser0ac92142012-02-14 14:02:27 +00001581
1582 BasicBlock *CondBB = SplitBlock(Builder.GetInsertBlock(),
1583 Builder.GetInsertPoint(), P);
1584 CondBB->setName("polly.cond");
1585 BasicBlock *MergeBB = SplitBlock(CondBB, CondBB->begin(), P);
1586 MergeBB->setName("polly.merge");
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001587 BasicBlock *ThenBB = BasicBlock::Create(Context, "polly.then", F);
Tobias Grosser0ac92142012-02-14 14:02:27 +00001588
Tobias Grosserd596b372012-03-15 09:34:52 +00001589 DominatorTree &DT = P->getAnalysis<DominatorTree>();
1590 DT.addNewBlock(ThenBB, CondBB);
1591 DT.changeImmediateDominator(MergeBB, CondBB);
Tobias Grosser0ac92142012-02-14 14:02:27 +00001592
1593 CondBB->getTerminator()->eraseFromParent();
1594
1595 Builder.SetInsertPoint(CondBB);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001596
1597 Value *Predicate = codegen(&(g->eq[0]));
1598
1599 for (int i = 1; i < g->n; ++i) {
1600 Value *TmpPredicate = codegen(&(g->eq[i]));
1601 Predicate = Builder.CreateAnd(Predicate, TmpPredicate);
1602 }
1603
1604 Builder.CreateCondBr(Predicate, ThenBB, MergeBB);
1605 Builder.SetInsertPoint(ThenBB);
Tobias Grosser0ac92142012-02-14 14:02:27 +00001606 Builder.CreateBr(MergeBB);
1607 Builder.SetInsertPoint(ThenBB->begin());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001608
1609 codegen(g->then);
Tobias Grosser62a3c962012-02-16 09:56:21 +00001610
1611 Builder.SetInsertPoint(MergeBB->begin());
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001612}
1613
1614void ClastStmtCodeGen::codegen(const clast_stmt *stmt) {
1615 if (CLAST_STMT_IS_A(stmt, stmt_root))
1616 assert(false && "No second root statement expected");
1617 else if (CLAST_STMT_IS_A(stmt, stmt_ass))
1618 codegen((const clast_assignment *)stmt);
1619 else if (CLAST_STMT_IS_A(stmt, stmt_user))
1620 codegen((const clast_user_stmt *)stmt);
1621 else if (CLAST_STMT_IS_A(stmt, stmt_block))
1622 codegen((const clast_block *)stmt);
1623 else if (CLAST_STMT_IS_A(stmt, stmt_for))
1624 codegen((const clast_for *)stmt);
1625 else if (CLAST_STMT_IS_A(stmt, stmt_guard))
1626 codegen((const clast_guard *)stmt);
1627
1628 if (stmt->next)
1629 codegen(stmt->next);
1630}
1631
1632void ClastStmtCodeGen::addParameters(const CloogNames *names) {
Tobias Grosserd596b372012-03-15 09:34:52 +00001633 SCEVExpander Rewriter(P->getAnalysis<ScalarEvolution>(), "polly");
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001634
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001635 int i = 0;
1636 for (Scop::param_iterator PI = S->param_begin(), PE = S->param_end();
1637 PI != PE; ++PI) {
1638 assert(i < names->nb_parameters && "Not enough parameter names");
1639
1640 const SCEV *Param = *PI;
1641 Type *Ty = Param->getType();
1642
1643 Instruction *insertLocation = --(Builder.GetInsertBlock()->end());
1644 Value *V = Rewriter.expandCodeFor(Param, Ty, insertLocation);
Tobias Grosser46fc9ca2012-03-23 08:24:10 +00001645 (*ClastVars)[names->parameters[i]] = V;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001646
1647 ++i;
1648 }
1649}
1650
1651void ClastStmtCodeGen::codegen(const clast_root *r) {
Tobias Grosser46fc9ca2012-03-23 08:24:10 +00001652 ClastVars = new CharMapT();
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001653 addParameters(r->names);
Tobias Grosser46fc9ca2012-03-23 08:24:10 +00001654 ExpGen.setIVS(ClastVars);
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001655
1656 parallelCodeGeneration = false;
1657
1658 const clast_stmt *stmt = (const clast_stmt*) r;
1659 if (stmt->next)
1660 codegen(stmt->next);
1661
Tobias Grosser46fc9ca2012-03-23 08:24:10 +00001662 delete ClastVars;
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001663}
1664
Tobias Grosserd596b372012-03-15 09:34:52 +00001665ClastStmtCodeGen::ClastStmtCodeGen(Scop *scop, IRBuilder<> &B, Pass *P) :
1666 S(scop), P(P), Builder(B), ExpGen(Builder, NULL) {}
Tobias Grosser9bc5eb082012-01-24 16:42:32 +00001667
Tobias Grosser75805372011-04-29 06:27:02 +00001668namespace {
1669class CodeGeneration : public ScopPass {
1670 Region *region;
1671 Scop *S;
1672 DominatorTree *DT;
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001673 RegionInfo *RI;
Tobias Grosser75805372011-04-29 06:27:02 +00001674
1675 std::vector<std::string> parallelLoops;
1676
1677 public:
1678 static char ID;
1679
1680 CodeGeneration() : ScopPass(ID) {}
1681
Tobias Grosserb1c95992012-02-12 12:09:27 +00001682 // Add the declarations needed by the OpenMP function calls that we insert in
1683 // OpenMP mode.
1684 void addOpenMPDeclarations(Module *M)
Tobias Grosser75805372011-04-29 06:27:02 +00001685 {
Tobias Grosserd855cc52012-02-12 12:09:32 +00001686 IRBuilder<> Builder(M->getContext());
Tobias Grosserd596b372012-03-15 09:34:52 +00001687 Type *LongTy = getAnalysis<TargetData>().getIntPtrType(M->getContext());
Tobias Grosserd855cc52012-02-12 12:09:32 +00001688
1689 llvm::GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
Tobias Grosser75805372011-04-29 06:27:02 +00001690
1691 if (!M->getFunction("GOMP_parallel_end")) {
Tobias Grosserd855cc52012-02-12 12:09:32 +00001692 FunctionType *Ty = FunctionType::get(Builder.getVoidTy(), false);
1693 Function::Create(Ty, Linkage, "GOMP_parallel_end", M);
Tobias Grosser75805372011-04-29 06:27:02 +00001694 }
1695
1696 if (!M->getFunction("GOMP_parallel_loop_runtime_start")) {
Tobias Grosserd855cc52012-02-12 12:09:32 +00001697 Type *Params[] = {
1698 PointerType::getUnqual(FunctionType::get(Builder.getVoidTy(),
1699 Builder.getInt8PtrTy(),
1700 false)),
1701 Builder.getInt8PtrTy(),
1702 Builder.getInt32Ty(),
1703 LongTy,
1704 LongTy,
1705 LongTy,
1706 };
Tobias Grosser75805372011-04-29 06:27:02 +00001707
Tobias Grosserd855cc52012-02-12 12:09:32 +00001708 FunctionType *Ty = FunctionType::get(Builder.getVoidTy(), Params, false);
1709 Function::Create(Ty, Linkage, "GOMP_parallel_loop_runtime_start", M);
Tobias Grosser75805372011-04-29 06:27:02 +00001710 }
1711
1712 if (!M->getFunction("GOMP_loop_runtime_next")) {
Tobias Grosserd855cc52012-02-12 12:09:32 +00001713 PointerType *LongPtrTy = PointerType::getUnqual(LongTy);
1714 Type *Params[] = {
1715 LongPtrTy,
1716 LongPtrTy,
1717 };
Tobias Grosser75805372011-04-29 06:27:02 +00001718
Tobias Grosserd855cc52012-02-12 12:09:32 +00001719 FunctionType *Ty = FunctionType::get(Builder.getInt8Ty(), Params, false);
1720 Function::Create(Ty, Linkage, "GOMP_loop_runtime_next", M);
Tobias Grosser75805372011-04-29 06:27:02 +00001721 }
1722
1723 if (!M->getFunction("GOMP_loop_end_nowait")) {
Tobias Grosserd855cc52012-02-12 12:09:32 +00001724 FunctionType *Ty = FunctionType::get(Builder.getVoidTy(), false);
1725 Function::Create(Ty, Linkage, "GOMP_loop_end_nowait", M);
Tobias Grosser75805372011-04-29 06:27:02 +00001726 }
1727 }
1728
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001729 // Split the entry edge of the region and generate a new basic block on this
1730 // edge. This function also updates ScopInfo and RegionInfo.
1731 //
1732 // @param region The region where the entry edge will be splitted.
1733 BasicBlock *splitEdgeAdvanced(Region *region) {
1734 BasicBlock *newBlock;
1735 BasicBlock *splitBlock;
1736
1737 newBlock = SplitEdge(region->getEnteringBlock(), region->getEntry(), this);
1738
1739 if (DT->dominates(region->getEntry(), newBlock)) {
Tobias Grossercb47dfe2012-02-15 09:58:50 +00001740 BasicBlock *OldBlock = region->getEntry();
1741 std::string OldName = OldBlock->getName();
1742
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001743 // Update ScopInfo.
1744 for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI)
Tobias Grosserf12cea42012-02-15 09:58:53 +00001745 if ((*SI)->getBasicBlock() == OldBlock) {
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001746 (*SI)->setBasicBlock(newBlock);
1747 break;
1748 }
1749
1750 // Update RegionInfo.
Tobias Grossercb47dfe2012-02-15 09:58:50 +00001751 splitBlock = OldBlock;
1752 OldBlock->setName("polly.split");
1753 newBlock->setName(OldName);
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001754 region->replaceEntry(newBlock);
Tobias Grosser7a16c892011-05-14 19:01:55 +00001755 RI->setRegionFor(newBlock, region);
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001756 } else {
1757 RI->setRegionFor(newBlock, region->getParent());
1758 splitBlock = newBlock;
1759 }
1760
1761 return splitBlock;
1762 }
1763
1764 // Create a split block that branches either to the old code or to a new basic
1765 // block where the new code can be inserted.
1766 //
Tobias Grosserbd608a82012-02-12 12:09:41 +00001767 // @param Builder A builder that will be set to point to a basic block, where
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001768 // the new code can be generated.
1769 // @return The split basic block.
Tobias Grosserbd608a82012-02-12 12:09:41 +00001770 BasicBlock *addSplitAndStartBlock(IRBuilder<> *Builder) {
1771 BasicBlock *StartBlock, *SplitBlock;
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001772
Tobias Grosserbd608a82012-02-12 12:09:41 +00001773 SplitBlock = splitEdgeAdvanced(region);
1774 SplitBlock->setName("polly.split_new_and_old");
1775 Function *F = SplitBlock->getParent();
1776 StartBlock = BasicBlock::Create(F->getContext(), "polly.start", F);
1777 SplitBlock->getTerminator()->eraseFromParent();
1778 Builder->SetInsertPoint(SplitBlock);
1779 Builder->CreateCondBr(Builder->getTrue(), StartBlock, region->getEntry());
1780 DT->addNewBlock(StartBlock, SplitBlock);
1781 Builder->SetInsertPoint(StartBlock);
1782 return SplitBlock;
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001783 }
1784
1785 // Merge the control flow of the newly generated code with the existing code.
1786 //
Tobias Grosserbd608a82012-02-12 12:09:41 +00001787 // @param SplitBlock The basic block where the control flow was split between
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001788 // old and new version of the Scop.
Tobias Grosserbd608a82012-02-12 12:09:41 +00001789 // @param Builder An IRBuilder that points to the last instruction of the
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001790 // newly generated code.
Tobias Grosserbd608a82012-02-12 12:09:41 +00001791 void mergeControlFlow(BasicBlock *SplitBlock, IRBuilder<> *Builder) {
1792 BasicBlock *MergeBlock;
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001793 Region *R = region;
1794
1795 if (R->getExit()->getSinglePredecessor())
1796 // No splitEdge required. A block with a single predecessor cannot have
1797 // PHI nodes that would complicate life.
Tobias Grosserbd608a82012-02-12 12:09:41 +00001798 MergeBlock = R->getExit();
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001799 else {
Tobias Grosserbd608a82012-02-12 12:09:41 +00001800 MergeBlock = SplitEdge(R->getExitingBlock(), R->getExit(), this);
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001801 // SplitEdge will never split R->getExit(), as R->getExit() has more than
1802 // one predecessor. Hence, mergeBlock is always a newly generated block.
Tobias Grosserbd608a82012-02-12 12:09:41 +00001803 R->replaceExit(MergeBlock);
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001804 }
1805
Tobias Grosserbd608a82012-02-12 12:09:41 +00001806 Builder->CreateBr(MergeBlock);
Tobias Grosser8518bbe2012-02-12 12:09:46 +00001807 MergeBlock->setName("polly.merge_new_and_old");
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001808
Tobias Grosserbd608a82012-02-12 12:09:41 +00001809 if (DT->dominates(SplitBlock, MergeBlock))
1810 DT->changeImmediateDominator(MergeBlock, SplitBlock);
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001811 }
1812
Tobias Grosser75805372011-04-29 06:27:02 +00001813 bool runOnScop(Scop &scop) {
1814 S = &scop;
1815 region = &S->getRegion();
Tobias Grosser75805372011-04-29 06:27:02 +00001816 DT = &getAnalysis<DominatorTree>();
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001817 RI = &getAnalysis<RegionInfo>();
Tobias Grosser75805372011-04-29 06:27:02 +00001818
1819 parallelLoops.clear();
1820
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001821 assert(region->isSimple() && "Only simple regions are supported");
Tobias Grosser76d7c522011-05-14 19:01:37 +00001822
Tobias Grosserb1c95992012-02-12 12:09:27 +00001823 Module *M = region->getEntry()->getParent()->getParent();
1824
Tobias Grosserd855cc52012-02-12 12:09:32 +00001825 if (OpenMP) addOpenMPDeclarations(M);
Tobias Grosserb1c95992012-02-12 12:09:27 +00001826
Tobias Grosser5772e652012-02-01 14:23:33 +00001827 // In the CFG the optimized code of the SCoP is generated next to the
1828 // original code. Both the new and the original version of the code remain
1829 // in the CFG. A branch statement decides which version is executed.
1830 // For now, we always execute the new version (the old one is dead code
1831 // eliminated by the cleanup passes). In the future we may decide to execute
1832 // the new version only if certain run time checks succeed. This will be
1833 // useful to support constructs for which we cannot prove all assumptions at
1834 // compile time.
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001835 //
1836 // Before transformation:
1837 //
1838 // bb0
1839 // |
1840 // orig_scop
1841 // |
1842 // bb1
1843 //
1844 // After transformation:
1845 // bb0
1846 // |
1847 // polly.splitBlock
Tobias Grosser2bd3af12011-08-01 22:39:00 +00001848 // / \.
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001849 // | startBlock
1850 // | |
1851 // orig_scop new_scop
1852 // \ /
1853 // \ /
1854 // bb1 (joinBlock)
1855 IRBuilder<> builder(region->getEntry());
Tobias Grosser75805372011-04-29 06:27:02 +00001856
Tobias Grosser8c4cfc322011-05-14 19:01:49 +00001857 // The builder will be set to startBlock.
1858 BasicBlock *splitBlock = addSplitAndStartBlock(&builder);
Tobias Grosser0ac92142012-02-14 14:02:27 +00001859 BasicBlock *StartBlock = builder.GetInsertBlock();
Tobias Grosser75805372011-04-29 06:27:02 +00001860
Tobias Grosser0ac92142012-02-14 14:02:27 +00001861 mergeControlFlow(splitBlock, &builder);
1862 builder.SetInsertPoint(StartBlock->begin());
1863
Tobias Grosserd596b372012-03-15 09:34:52 +00001864 ClastStmtCodeGen CodeGen(S, builder, this);
Tobias Grosser3fdecae2011-05-14 19:02:39 +00001865 CloogInfo &C = getAnalysis<CloogInfo>();
1866 CodeGen.codegen(C.getClast());
Tobias Grosser75805372011-04-29 06:27:02 +00001867
Tobias Grosser75805372011-04-29 06:27:02 +00001868 parallelLoops.insert(parallelLoops.begin(),
1869 CodeGen.getParallelLoops().begin(),
1870 CodeGen.getParallelLoops().end());
1871
Tobias Grosserabb6dcd2011-05-14 19:02:34 +00001872 return true;
Tobias Grosser75805372011-04-29 06:27:02 +00001873 }
1874
1875 virtual void printScop(raw_ostream &OS) const {
1876 for (std::vector<std::string>::const_iterator PI = parallelLoops.begin(),
1877 PE = parallelLoops.end(); PI != PE; ++PI)
1878 OS << "Parallel loop with iterator '" << *PI << "' generated\n";
1879 }
1880
1881 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
1882 AU.addRequired<CloogInfo>();
1883 AU.addRequired<Dependences>();
1884 AU.addRequired<DominatorTree>();
Tobias Grosser75805372011-04-29 06:27:02 +00001885 AU.addRequired<RegionInfo>();
Tobias Grosser73600b82011-10-08 00:30:40 +00001886 AU.addRequired<ScalarEvolution>();
Tobias Grosser75805372011-04-29 06:27:02 +00001887 AU.addRequired<ScopDetection>();
1888 AU.addRequired<ScopInfo>();
1889 AU.addRequired<TargetData>();
1890
1891 AU.addPreserved<CloogInfo>();
1892 AU.addPreserved<Dependences>();
Tobias Grosser5d6eb862011-05-14 19:02:45 +00001893
Tobias Grosser4e3f9a42011-05-23 15:23:36 +00001894 // FIXME: We do not create LoopInfo for the newly generated loops.
Tobias Grosser75805372011-04-29 06:27:02 +00001895 AU.addPreserved<LoopInfo>();
1896 AU.addPreserved<DominatorTree>();
Tobias Grosser75805372011-04-29 06:27:02 +00001897 AU.addPreserved<ScopDetection>();
1898 AU.addPreserved<ScalarEvolution>();
Tobias Grosser5d6eb862011-05-14 19:02:45 +00001899
Tobias Grosser4e3f9a42011-05-23 15:23:36 +00001900 // FIXME: We do not yet add regions for the newly generated code to the
1901 // region tree.
Tobias Grosser75805372011-04-29 06:27:02 +00001902 AU.addPreserved<RegionInfo>();
1903 AU.addPreserved<TempScopInfo>();
1904 AU.addPreserved<ScopInfo>();
1905 AU.addPreservedID(IndependentBlocksID);
1906 }
1907};
1908}
1909
1910char CodeGeneration::ID = 1;
1911
Tobias Grosser73600b82011-10-08 00:30:40 +00001912INITIALIZE_PASS_BEGIN(CodeGeneration, "polly-codegen",
Tobias Grosser3c2efba2012-03-06 07:38:57 +00001913 "Polly - Create LLVM-IR from SCoPs", false, false)
Tobias Grosser73600b82011-10-08 00:30:40 +00001914INITIALIZE_PASS_DEPENDENCY(CloogInfo)
1915INITIALIZE_PASS_DEPENDENCY(Dependences)
1916INITIALIZE_PASS_DEPENDENCY(DominatorTree)
1917INITIALIZE_PASS_DEPENDENCY(RegionInfo)
1918INITIALIZE_PASS_DEPENDENCY(ScalarEvolution)
1919INITIALIZE_PASS_DEPENDENCY(ScopDetection)
1920INITIALIZE_PASS_DEPENDENCY(TargetData)
1921INITIALIZE_PASS_END(CodeGeneration, "polly-codegen",
Tobias Grosser3c2efba2012-03-06 07:38:57 +00001922 "Polly - Create LLVM-IR from SCoPs", false, false)
Tobias Grosser75805372011-04-29 06:27:02 +00001923
Tobias Grosser7ffe4e82011-11-17 12:56:10 +00001924Pass *polly::createCodeGenerationPass() {
Tobias Grosser75805372011-04-29 06:27:02 +00001925 return new CodeGeneration();
1926}