blob: 02ca41b6e1847712967fdb751f01573c7825ab12 [file] [log] [blame]
Hongbin Zheng3b11a162012-04-25 13:16:49 +00001//===--- BlockGenerators.cpp - Generate code for statements -----*- C++ -*-===//
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// This file implements the BlockGenerator and VectorBlockGenerator classes,
11// which generate sequential code and vectorized code for a polyhedral
12// statement, respectively.
13//
14//===----------------------------------------------------------------------===//
15
16#include "polly/ScopInfo.h"
Hongbin Zheng8a846612012-04-25 13:18:28 +000017#include "polly/CodeGen/BlockGenerators.h"
Tobias Grosser83628182013-05-07 08:11:54 +000018#include "polly/CodeGen/CodeGeneration.h"
Johannes Doerferta63b2572014-08-03 01:51:59 +000019#include "polly/CodeGen/IslExprBuilder.h"
Tobias Grosser637bd632013-05-07 07:31:10 +000020#include "polly/Options.h"
Hongbin Zheng3b11a162012-04-25 13:16:49 +000021#include "polly/Support/GICHelper.h"
Sebastian Pop97cb8132013-03-18 20:21:13 +000022#include "polly/Support/SCEVValidator.h"
Tobias Grosserecfe21b2013-03-20 18:03:18 +000023#include "polly/Support/ScopHelper.h"
Tobias Grossere71c6ab2012-04-27 16:36:14 +000024#include "llvm/Analysis/LoopInfo.h"
Johannes Doerfertf32d6512015-03-01 18:45:58 +000025#include "llvm/Analysis/RegionInfo.h"
Tobias Grossere71c6ab2012-04-27 16:36:14 +000026#include "llvm/Analysis/ScalarEvolution.h"
27#include "llvm/Analysis/ScalarEvolutionExpander.h"
Tobias Grosser030237d2014-02-21 15:06:05 +000028#include "llvm/IR/IntrinsicInst.h"
Tobias Grosserc9895062015-03-10 15:24:33 +000029#include "llvm/IR/Module.h"
Hongbin Zheng3b11a162012-04-25 13:16:49 +000030#include "llvm/Transforms/Utils/BasicBlockUtils.h"
Johannes Doerfertf32d6512015-03-01 18:45:58 +000031#include "isl/aff.h"
32#include "isl/ast.h"
Johannes Doerfertf32d6512015-03-01 18:45:58 +000033#include "isl/ast_build.h"
Tobias Grosserba0d0922015-05-09 09:13:42 +000034#include "isl/set.h"
Johannes Doerfertf32d6512015-03-01 18:45:58 +000035#include <deque>
36
Hongbin Zheng3b11a162012-04-25 13:16:49 +000037using namespace llvm;
38using namespace polly;
39
Tobias Grosser878aba42014-10-22 23:22:41 +000040static cl::opt<bool> Aligned("enable-polly-aligned",
41 cl::desc("Assumed aligned memory accesses."),
42 cl::Hidden, cl::init(false), cl::ZeroOrMore,
43 cl::cat(PollyCategory));
Hongbin Zheng3b11a162012-04-25 13:16:49 +000044
Tobias Grosserecfe21b2013-03-20 18:03:18 +000045bool polly::canSynthesize(const Instruction *I, const llvm::LoopInfo *LI,
46 ScalarEvolution *SE, const Region *R) {
Tobias Grosser683b8e42014-11-30 14:33:31 +000047 if (!I || !SE->isSCEVable(I->getType()))
Tobias Grosserecfe21b2013-03-20 18:03:18 +000048 return false;
Tobias Grosserecfe21b2013-03-20 18:03:18 +000049
Tobias Grosser683b8e42014-11-30 14:33:31 +000050 if (const SCEV *Scev = SE->getSCEV(const_cast<Instruction *>(I)))
51 if (!isa<SCEVCouldNotCompute>(Scev))
52 if (!hasScalarDepsInsideRegion(Scev, R))
53 return true;
54
55 return false;
Tobias Grosserecfe21b2013-03-20 18:03:18 +000056}
57
Johannes Doerfert9e3a5db2015-01-26 15:55:54 +000058bool polly::isIgnoredIntrinsic(const Value *V) {
59 if (auto *IT = dyn_cast<IntrinsicInst>(V)) {
60 switch (IT->getIntrinsicID()) {
61 // Lifetime markers are supported/ignored.
62 case llvm::Intrinsic::lifetime_start:
63 case llvm::Intrinsic::lifetime_end:
64 // Invariant markers are supported/ignored.
65 case llvm::Intrinsic::invariant_start:
66 case llvm::Intrinsic::invariant_end:
67 // Some misc annotations are supported/ignored.
68 case llvm::Intrinsic::var_annotation:
69 case llvm::Intrinsic::ptr_annotation:
70 case llvm::Intrinsic::annotation:
71 case llvm::Intrinsic::donothing:
72 case llvm::Intrinsic::assume:
73 case llvm::Intrinsic::expect:
74 return true;
75 default:
76 break;
77 }
78 }
79 return false;
80}
81
Johannes Doerfertb4f08eb2015-02-23 13:51:35 +000082BlockGenerator::BlockGenerator(PollyIRBuilder &B, LoopInfo &LI,
83 ScalarEvolution &SE, DominatorTree &DT,
84 IslExprBuilder *ExprBuilder)
85 : Builder(B), LI(LI), SE(SE), ExprBuilder(ExprBuilder), DT(DT) {}
Tobias Grossere71c6ab2012-04-27 16:36:14 +000086
Johannes Doerfertbe9c9112015-02-06 21:39:31 +000087Value *BlockGenerator::getNewValue(ScopStmt &Stmt, const Value *Old,
88 ValueMapT &BBMap, ValueMapT &GlobalMap,
89 LoopToScevMapT &LTS, Loop *L) const {
Hongbin Zheng3b11a162012-04-25 13:16:49 +000090 // We assume constants never change.
91 // This avoids map lookups for many calls to this function.
92 if (isa<Constant>(Old))
Tobias Grosserc14582f2013-02-05 18:01:29 +000093 return const_cast<Value *>(Old);
Hongbin Zheng3b11a162012-04-25 13:16:49 +000094
Hongbin Zhengfe11e282013-06-29 13:22:15 +000095 if (Value *New = GlobalMap.lookup(Old)) {
Tobias Grosserc14582f2013-02-05 18:01:29 +000096 if (Old->getType()->getScalarSizeInBits() <
Tobias Grosserd7e58642013-04-10 06:55:45 +000097 New->getType()->getScalarSizeInBits())
Hongbin Zheng3b11a162012-04-25 13:16:49 +000098 New = Builder.CreateTruncOrBitCast(New, Old->getType());
99
100 return New;
101 }
102
Hongbin Zhengfe11e282013-06-29 13:22:15 +0000103 if (Value *New = BBMap.lookup(Old))
104 return New;
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000105
Tobias Grosser683b8e42014-11-30 14:33:31 +0000106 if (SE.isSCEVable(Old->getType()))
Tobias Grosser369430f2013-03-22 23:42:53 +0000107 if (const SCEV *Scev = SE.getSCEVAtScope(const_cast<Value *>(Old), L)) {
Tobias Grossere71c6ab2012-04-27 16:36:14 +0000108 if (!isa<SCEVCouldNotCompute>(Scev)) {
Sebastian Pop637b23d2013-02-15 20:56:01 +0000109 const SCEV *NewScev = apply(Scev, LTS, SE);
110 ValueToValueMap VTV;
111 VTV.insert(BBMap.begin(), BBMap.end());
112 VTV.insert(GlobalMap.begin(), GlobalMap.end());
Sebastian Pop47d4ee32013-02-15 21:26:53 +0000113 NewScev = SCEVParameterRewriter::rewrite(NewScev, SE, VTV);
Tobias Grosserc9895062015-03-10 15:24:33 +0000114 SCEVExpander Expander(SE, Stmt.getParent()
115 ->getRegion()
116 .getEntry()
117 ->getParent()
118 ->getParent()
119 ->getDataLayout(),
120 "polly");
Tobias Grossere71c6ab2012-04-27 16:36:14 +0000121 Value *Expanded = Expander.expandCodeFor(NewScev, Old->getType(),
122 Builder.GetInsertPoint());
123
124 BBMap[Old] = Expanded;
125 return Expanded;
126 }
Tobias Grosser369430f2013-03-22 23:42:53 +0000127 }
Tobias Grossere71c6ab2012-04-27 16:36:14 +0000128
Tobias Grosser16371ac2014-11-05 20:48:56 +0000129 // A scop-constant value defined by a global or a function parameter.
130 if (isa<GlobalValue>(Old) || isa<Argument>(Old))
131 return const_cast<Value *>(Old);
132
133 // A scop-constant value defined by an instruction executed outside the scop.
134 if (const Instruction *Inst = dyn_cast<Instruction>(Old))
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000135 if (!Stmt.getParent()->getRegion().contains(Inst->getParent()))
Tobias Grosser16371ac2014-11-05 20:48:56 +0000136 return const_cast<Value *>(Old);
137
138 // The scalar dependence is neither available nor SCEVCodegenable.
Hongbin Zheng5b463ce2013-07-25 09:12:07 +0000139 llvm_unreachable("Unexpected scalar dependence in region!");
Tobias Grosser5a56cbf2014-04-16 07:33:47 +0000140 return nullptr;
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000141}
142
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000143void BlockGenerator::copyInstScalar(ScopStmt &Stmt, const Instruction *Inst,
144 ValueMapT &BBMap, ValueMapT &GlobalMap,
145 LoopToScevMapT &LTS) {
Tobias Grosser030237d2014-02-21 15:06:05 +0000146 // We do not generate debug intrinsics as we did not investigate how to
147 // copy them correctly. At the current state, they just crash the code
148 // generation as the meta-data operands are not correctly copied.
149 if (isa<DbgInfoIntrinsic>(Inst))
150 return;
151
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000152 Instruction *NewInst = Inst->clone();
153
154 // Replace old operands with the new ones.
Tobias Grosser91f5b262014-06-04 08:06:40 +0000155 for (Value *OldOperand : Inst->operands()) {
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000156 Value *NewOperand = getNewValue(Stmt, OldOperand, BBMap, GlobalMap, LTS,
157 getLoopForInst(Inst));
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000158
159 if (!NewOperand) {
Tobias Grosserc14582f2013-02-05 18:01:29 +0000160 assert(!isa<StoreInst>(NewInst) &&
161 "Store instructions are always needed!");
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000162 delete NewInst;
163 return;
164 }
165
166 NewInst->replaceUsesOfWith(OldOperand, NewOperand);
167 }
168
169 Builder.Insert(NewInst);
170 BBMap[Inst] = NewInst;
171
172 if (!NewInst->getType()->isVoidTy())
173 NewInst->setName("p_" + Inst->getName());
174}
175
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000176Value *BlockGenerator::getNewAccessOperand(ScopStmt &Stmt,
177 const MemoryAccess &MA) {
Johannes Doerferta99130f2014-10-13 12:58:03 +0000178 isl_pw_multi_aff *PWAccRel;
179 isl_union_map *Schedule;
Johannes Doerferta63b2572014-08-03 01:51:59 +0000180 isl_ast_expr *Expr;
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000181 isl_ast_build *Build = Stmt.getAstBuild();
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000182
Johannes Doerferta63b2572014-08-03 01:51:59 +0000183 assert(ExprBuilder && Build &&
184 "Cannot generate new value without IslExprBuilder!");
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000185
Johannes Doerferta99130f2014-10-13 12:58:03 +0000186 Schedule = isl_ast_build_get_schedule(Build);
187 PWAccRel = MA.applyScheduleToAccessRelation(Schedule);
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000188
Johannes Doerferta63b2572014-08-03 01:51:59 +0000189 Expr = isl_ast_build_access_from_pw_multi_aff(Build, PWAccRel);
Johannes Doerfertdcb5f1d2014-09-18 11:14:30 +0000190 Expr = isl_ast_expr_address_of(Expr);
Johannes Doerferta63b2572014-08-03 01:51:59 +0000191
192 return ExprBuilder->create(Expr);
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000193}
194
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000195Value *BlockGenerator::generateLocationAccessed(
196 ScopStmt &Stmt, const Instruction *Inst, const Value *Pointer,
197 ValueMapT &BBMap, ValueMapT &GlobalMap, LoopToScevMapT &LTS) {
198 const MemoryAccess &MA = Stmt.getAccessFor(Inst);
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000199
200 Value *NewPointer;
Johannes Doerferta99130f2014-10-13 12:58:03 +0000201 if (MA.hasNewAccessRelation())
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000202 NewPointer = getNewAccessOperand(Stmt, MA);
Johannes Doerferta63b2572014-08-03 01:51:59 +0000203 else
Tobias Grosser369430f2013-03-22 23:42:53 +0000204 NewPointer =
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000205 getNewValue(Stmt, Pointer, BBMap, GlobalMap, LTS, getLoopForInst(Inst));
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000206
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000207 return NewPointer;
208}
209
Tobias Grosser4d96c8d2013-03-23 01:05:07 +0000210Loop *BlockGenerator::getLoopForInst(const llvm::Instruction *Inst) {
Johannes Doerfert2ef3f4f2014-08-07 17:14:54 +0000211 return LI.getLoopFor(Inst->getParent());
Tobias Grosser369430f2013-03-22 23:42:53 +0000212}
213
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000214Value *BlockGenerator::generateScalarLoad(ScopStmt &Stmt, const LoadInst *Load,
Tobias Grossere602a072013-05-07 07:30:56 +0000215 ValueMapT &BBMap,
216 ValueMapT &GlobalMap,
217 LoopToScevMapT &LTS) {
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000218 const Value *Pointer = Load->getPointerOperand();
Tobias Grosser7242ad92013-02-22 08:07:06 +0000219 Value *NewPointer =
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000220 generateLocationAccessed(Stmt, Load, Pointer, BBMap, GlobalMap, LTS);
Johannes Doerfert87901452014-10-02 16:22:19 +0000221 Value *ScalarLoad = Builder.CreateAlignedLoad(
222 NewPointer, Load->getAlignment(), Load->getName() + "_p_scalar_");
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000223 return ScalarLoad;
224}
225
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000226Value *BlockGenerator::generateScalarStore(ScopStmt &Stmt,
227 const StoreInst *Store,
Tobias Grossere602a072013-05-07 07:30:56 +0000228 ValueMapT &BBMap,
229 ValueMapT &GlobalMap,
230 LoopToScevMapT &LTS) {
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000231 const Value *Pointer = Store->getPointerOperand();
Tobias Grosserc14582f2013-02-05 18:01:29 +0000232 Value *NewPointer =
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000233 generateLocationAccessed(Stmt, Store, Pointer, BBMap, GlobalMap, LTS);
234 Value *ValueOperand = getNewValue(Stmt, Store->getValueOperand(), BBMap,
235 GlobalMap, LTS, getLoopForInst(Store));
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000236
Johannes Doerfert87901452014-10-02 16:22:19 +0000237 Value *NewStore = Builder.CreateAlignedStore(ValueOperand, NewPointer,
238 Store->getAlignment());
239 return NewStore;
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000240}
241
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000242void BlockGenerator::copyInstruction(ScopStmt &Stmt, const Instruction *Inst,
243 ValueMapT &BBMap, ValueMapT &GlobalMap,
Tobias Grossere602a072013-05-07 07:30:56 +0000244 LoopToScevMapT &LTS) {
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000245 // Terminator instructions control the control flow. They are explicitly
246 // expressed in the clast and do not need to be copied.
247 if (Inst->isTerminator())
248 return;
249
Johannes Doerfert1ef52332015-02-08 20:50:42 +0000250 if (canSynthesize(Inst, &LI, &SE, &Stmt.getParent()->getRegion()))
Tobias Grossere71c6ab2012-04-27 16:36:14 +0000251 return;
252
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000253 if (const LoadInst *Load = dyn_cast<LoadInst>(Inst)) {
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000254 Value *NewLoad = generateScalarLoad(Stmt, Load, BBMap, GlobalMap, LTS);
Sebastian Pop3d94fed2013-05-24 18:46:02 +0000255 // Compute NewLoad before its insertion in BBMap to make the insertion
256 // deterministic.
Sebastian Pop753d43f2013-05-24 17:16:02 +0000257 BBMap[Load] = NewLoad;
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000258 return;
259 }
260
261 if (const StoreInst *Store = dyn_cast<StoreInst>(Inst)) {
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000262 Value *NewStore = generateScalarStore(Stmt, Store, BBMap, GlobalMap, LTS);
Sebastian Pop3d94fed2013-05-24 18:46:02 +0000263 // Compute NewStore before its insertion in BBMap to make the insertion
264 // deterministic.
Sebastian Pop753d43f2013-05-24 17:16:02 +0000265 BBMap[Store] = NewStore;
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000266 return;
267 }
268
Johannes Doerfert3f500fa2015-01-25 18:07:30 +0000269 // Skip some special intrinsics for which we do not adjust the semantics to
270 // the new schedule. All others are handled like every other instruction.
271 if (auto *IT = dyn_cast<IntrinsicInst>(Inst)) {
272 switch (IT->getIntrinsicID()) {
273 // Lifetime markers are ignored.
274 case llvm::Intrinsic::lifetime_start:
275 case llvm::Intrinsic::lifetime_end:
276 // Invariant markers are ignored.
277 case llvm::Intrinsic::invariant_start:
278 case llvm::Intrinsic::invariant_end:
279 // Some misc annotations are ignored.
280 case llvm::Intrinsic::var_annotation:
281 case llvm::Intrinsic::ptr_annotation:
282 case llvm::Intrinsic::annotation:
283 case llvm::Intrinsic::donothing:
284 case llvm::Intrinsic::assume:
285 case llvm::Intrinsic::expect:
286 return;
287 default:
288 // Other intrinsics are copied.
289 break;
290 }
291 }
292
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000293 copyInstScalar(Stmt, Inst, BBMap, GlobalMap, LTS);
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000294}
295
Johannes Doerfert275a1752015-02-24 16:16:32 +0000296void BlockGenerator::copyStmt(ScopStmt &Stmt, ValueMapT &GlobalMap,
297 LoopToScevMapT &LTS) {
298 assert(Stmt.isBlockStmt() &&
299 "Only block statements can be copied by the block generator");
300
301 ValueMapT BBMap;
302
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000303 BasicBlock *BB = Stmt.getBasicBlock();
Johannes Doerfert275a1752015-02-24 16:16:32 +0000304 copyBB(Stmt, BB, BBMap, GlobalMap, LTS);
305}
306
Johannes Doerfert514f6ef2015-02-27 18:29:04 +0000307BasicBlock *BlockGenerator::splitBB(BasicBlock *BB) {
Tobias Grosserc14582f2013-02-05 18:01:29 +0000308 BasicBlock *CopyBB =
Johannes Doerfertb4f08eb2015-02-23 13:51:35 +0000309 SplitBlock(Builder.GetInsertBlock(), Builder.GetInsertPoint(), &DT, &LI);
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000310 CopyBB->setName("polly.stmt." + BB->getName());
Johannes Doerfert514f6ef2015-02-27 18:29:04 +0000311 return CopyBB;
312}
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000313
Johannes Doerfert514f6ef2015-02-27 18:29:04 +0000314BasicBlock *BlockGenerator::copyBB(ScopStmt &Stmt, BasicBlock *BB,
315 ValueMapT &BBMap, ValueMapT &GlobalMap,
316 LoopToScevMapT &LTS) {
317 BasicBlock *CopyBB = splitBB(BB);
318 copyBB(Stmt, BB, CopyBB, BBMap, GlobalMap, LTS);
319 return CopyBB;
320}
321
322void BlockGenerator::copyBB(ScopStmt &Stmt, BasicBlock *BB, BasicBlock *CopyBB,
323 ValueMapT &BBMap, ValueMapT &GlobalMap,
324 LoopToScevMapT &LTS) {
325 Builder.SetInsertPoint(CopyBB->begin());
Tobias Grosser91f5b262014-06-04 08:06:40 +0000326 for (Instruction &Inst : *BB)
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000327 copyInstruction(Stmt, &Inst, BBMap, GlobalMap, LTS);
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000328}
329
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000330VectorBlockGenerator::VectorBlockGenerator(BlockGenerator &BlockGen,
331 VectorValueMapT &GlobalMaps,
332 std::vector<LoopToScevMapT> &VLTS,
333 isl_map *Schedule)
334 : BlockGenerator(BlockGen), GlobalMaps(GlobalMaps), VLTS(VLTS),
335 Schedule(Schedule) {
Sebastian Popa00a0292012-12-18 07:46:06 +0000336 assert(GlobalMaps.size() > 1 && "Only one vector lane found");
337 assert(Schedule && "No statement domain provided");
338}
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000339
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000340Value *VectorBlockGenerator::getVectorValue(ScopStmt &Stmt, const Value *Old,
Tobias Grossere602a072013-05-07 07:30:56 +0000341 ValueMapT &VectorMap,
342 VectorValueMapT &ScalarMaps,
343 Loop *L) {
Hongbin Zhengfe11e282013-06-29 13:22:15 +0000344 if (Value *NewValue = VectorMap.lookup(Old))
345 return NewValue;
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000346
347 int Width = getVectorWidth();
348
349 Value *Vector = UndefValue::get(VectorType::get(Old->getType(), Width));
350
351 for (int Lane = 0; Lane < Width; Lane++)
Tobias Grosserc14582f2013-02-05 18:01:29 +0000352 Vector = Builder.CreateInsertElement(
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000353 Vector, getNewValue(Stmt, Old, ScalarMaps[Lane], GlobalMaps[Lane],
354 VLTS[Lane], L),
Tobias Grosser7242ad92013-02-22 08:07:06 +0000355 Builder.getInt32(Lane));
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000356
357 VectorMap[Old] = Vector;
358
359 return Vector;
360}
361
362Type *VectorBlockGenerator::getVectorPtrTy(const Value *Val, int Width) {
363 PointerType *PointerTy = dyn_cast<PointerType>(Val->getType());
364 assert(PointerTy && "PointerType expected");
365
366 Type *ScalarType = PointerTy->getElementType();
367 VectorType *VectorType = VectorType::get(ScalarType, Width);
368
369 return PointerType::getUnqual(VectorType);
370}
371
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000372Value *VectorBlockGenerator::generateStrideOneLoad(
373 ScopStmt &Stmt, const LoadInst *Load, VectorValueMapT &ScalarMaps,
374 bool NegativeStride = false) {
Tobias Grosser0dd463f2014-03-19 19:27:24 +0000375 unsigned VectorWidth = getVectorWidth();
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000376 const Value *Pointer = Load->getPointerOperand();
Tobias Grosser0dd463f2014-03-19 19:27:24 +0000377 Type *VectorPtrType = getVectorPtrTy(Pointer, VectorWidth);
378 unsigned Offset = NegativeStride ? VectorWidth - 1 : 0;
379
Tobias Grosser5a56cbf2014-04-16 07:33:47 +0000380 Value *NewPointer = nullptr;
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000381 NewPointer = generateLocationAccessed(Stmt, Load, Pointer, ScalarMaps[Offset],
Johannes Doerfert731685e2014-10-08 17:25:30 +0000382 GlobalMaps[Offset], VLTS[Offset]);
Tobias Grosserc14582f2013-02-05 18:01:29 +0000383 Value *VectorPtr =
384 Builder.CreateBitCast(NewPointer, VectorPtrType, "vector_ptr");
385 LoadInst *VecLoad =
386 Builder.CreateLoad(VectorPtr, Load->getName() + "_p_vec_full");
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000387 if (!Aligned)
388 VecLoad->setAlignment(8);
389
Tobias Grosser0dd463f2014-03-19 19:27:24 +0000390 if (NegativeStride) {
391 SmallVector<Constant *, 16> Indices;
392 for (int i = VectorWidth - 1; i >= 0; i--)
393 Indices.push_back(ConstantInt::get(Builder.getInt32Ty(), i));
394 Constant *SV = llvm::ConstantVector::get(Indices);
395 Value *RevVecLoad = Builder.CreateShuffleVector(
396 VecLoad, VecLoad, SV, Load->getName() + "_reverse");
397 return RevVecLoad;
398 }
399
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000400 return VecLoad;
401}
402
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000403Value *VectorBlockGenerator::generateStrideZeroLoad(ScopStmt &Stmt,
404 const LoadInst *Load,
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000405 ValueMapT &BBMap) {
406 const Value *Pointer = Load->getPointerOperand();
407 Type *VectorPtrType = getVectorPtrTy(Pointer, 1);
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000408 Value *NewPointer = generateLocationAccessed(Stmt, Load, Pointer, BBMap,
409 GlobalMaps[0], VLTS[0]);
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000410 Value *VectorPtr = Builder.CreateBitCast(NewPointer, VectorPtrType,
411 Load->getName() + "_p_vec_p");
Tobias Grosserc14582f2013-02-05 18:01:29 +0000412 LoadInst *ScalarLoad =
413 Builder.CreateLoad(VectorPtr, Load->getName() + "_p_splat_one");
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000414
415 if (!Aligned)
416 ScalarLoad->setAlignment(8);
417
Tobias Grosserc14582f2013-02-05 18:01:29 +0000418 Constant *SplatVector = Constant::getNullValue(
419 VectorType::get(Builder.getInt32Ty(), getVectorWidth()));
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000420
Tobias Grosserc14582f2013-02-05 18:01:29 +0000421 Value *VectorLoad = Builder.CreateShuffleVector(
422 ScalarLoad, ScalarLoad, SplatVector, Load->getName() + "_p_splat");
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000423 return VectorLoad;
424}
425
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000426Value *VectorBlockGenerator::generateUnknownStrideLoad(
427 ScopStmt &Stmt, const LoadInst *Load, VectorValueMapT &ScalarMaps) {
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000428 int VectorWidth = getVectorWidth();
429 const Value *Pointer = Load->getPointerOperand();
430 VectorType *VectorType = VectorType::get(
Tobias Grosserc14582f2013-02-05 18:01:29 +0000431 dyn_cast<PointerType>(Pointer->getType())->getElementType(), VectorWidth);
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000432
433 Value *Vector = UndefValue::get(VectorType);
434
435 for (int i = 0; i < VectorWidth; i++) {
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000436 Value *NewPointer = generateLocationAccessed(
437 Stmt, Load, Pointer, ScalarMaps[i], GlobalMaps[i], VLTS[i]);
Tobias Grosserc14582f2013-02-05 18:01:29 +0000438 Value *ScalarLoad =
439 Builder.CreateLoad(NewPointer, Load->getName() + "_p_scalar_");
440 Vector = Builder.CreateInsertElement(
441 Vector, ScalarLoad, Builder.getInt32(i), Load->getName() + "_p_vec_");
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000442 }
443
444 return Vector;
445}
446
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000447void VectorBlockGenerator::generateLoad(ScopStmt &Stmt, const LoadInst *Load,
Tobias Grossere602a072013-05-07 07:30:56 +0000448 ValueMapT &VectorMap,
449 VectorValueMapT &ScalarMaps) {
Tobias Grosser28736452015-03-23 07:00:36 +0000450 if (!VectorType::isValidElementType(Load->getType())) {
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000451 for (int i = 0; i < getVectorWidth(); i++)
Tobias Grosserc14582f2013-02-05 18:01:29 +0000452 ScalarMaps[i][Load] =
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000453 generateScalarLoad(Stmt, Load, ScalarMaps[i], GlobalMaps[i], VLTS[i]);
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000454 return;
455 }
456
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000457 const MemoryAccess &Access = Stmt.getAccessFor(Load);
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000458
Tobias Grosser95493982014-04-18 09:46:35 +0000459 // Make sure we have scalar values available to access the pointer to
460 // the data location.
461 extractScalarValues(Load, VectorMap, ScalarMaps);
462
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000463 Value *NewLoad;
Sebastian Popa00a0292012-12-18 07:46:06 +0000464 if (Access.isStrideZero(isl_map_copy(Schedule)))
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000465 NewLoad = generateStrideZeroLoad(Stmt, Load, ScalarMaps[0]);
Sebastian Popa00a0292012-12-18 07:46:06 +0000466 else if (Access.isStrideOne(isl_map_copy(Schedule)))
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000467 NewLoad = generateStrideOneLoad(Stmt, Load, ScalarMaps);
Tobias Grosser0dd463f2014-03-19 19:27:24 +0000468 else if (Access.isStrideX(isl_map_copy(Schedule), -1))
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000469 NewLoad = generateStrideOneLoad(Stmt, Load, ScalarMaps, true);
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000470 else
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000471 NewLoad = generateUnknownStrideLoad(Stmt, Load, ScalarMaps);
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000472
473 VectorMap[Load] = NewLoad;
474}
475
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000476void VectorBlockGenerator::copyUnaryInst(ScopStmt &Stmt,
477 const UnaryInstruction *Inst,
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000478 ValueMapT &VectorMap,
479 VectorValueMapT &ScalarMaps) {
480 int VectorWidth = getVectorWidth();
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000481 Value *NewOperand = getVectorValue(Stmt, Inst->getOperand(0), VectorMap,
482 ScalarMaps, getLoopForInst(Inst));
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000483
484 assert(isa<CastInst>(Inst) && "Can not generate vector code for instruction");
485
486 const CastInst *Cast = dyn_cast<CastInst>(Inst);
487 VectorType *DestType = VectorType::get(Inst->getType(), VectorWidth);
488 VectorMap[Inst] = Builder.CreateCast(Cast->getOpcode(), NewOperand, DestType);
489}
490
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000491void VectorBlockGenerator::copyBinaryInst(ScopStmt &Stmt,
492 const BinaryOperator *Inst,
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000493 ValueMapT &VectorMap,
494 VectorValueMapT &ScalarMaps) {
Tobias Grosser369430f2013-03-22 23:42:53 +0000495 Loop *L = getLoopForInst(Inst);
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000496 Value *OpZero = Inst->getOperand(0);
497 Value *OpOne = Inst->getOperand(1);
498
499 Value *NewOpZero, *NewOpOne;
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000500 NewOpZero = getVectorValue(Stmt, OpZero, VectorMap, ScalarMaps, L);
501 NewOpOne = getVectorValue(Stmt, OpOne, VectorMap, ScalarMaps, L);
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000502
Tobias Grosser1bb59b02012-12-29 23:47:38 +0000503 Value *NewInst = Builder.CreateBinOp(Inst->getOpcode(), NewOpZero, NewOpOne,
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000504 Inst->getName() + "p_vec");
505 VectorMap[Inst] = NewInst;
506}
507
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000508void VectorBlockGenerator::copyStore(ScopStmt &Stmt, const StoreInst *Store,
Tobias Grossere602a072013-05-07 07:30:56 +0000509 ValueMapT &VectorMap,
510 VectorValueMapT &ScalarMaps) {
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000511 const MemoryAccess &Access = Stmt.getAccessFor(Store);
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000512
513 const Value *Pointer = Store->getPointerOperand();
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000514 Value *Vector = getVectorValue(Stmt, Store->getValueOperand(), VectorMap,
Tobias Grosser369430f2013-03-22 23:42:53 +0000515 ScalarMaps, getLoopForInst(Store));
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000516
Tobias Grosser50fd7012014-04-17 23:13:49 +0000517 // Make sure we have scalar values available to access the pointer to
518 // the data location.
519 extractScalarValues(Store, VectorMap, ScalarMaps);
520
Sebastian Popa00a0292012-12-18 07:46:06 +0000521 if (Access.isStrideOne(isl_map_copy(Schedule))) {
Johannes Doerfert1947f862014-10-08 20:18:32 +0000522 Type *VectorPtrType = getVectorPtrTy(Pointer, getVectorWidth());
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000523 Value *NewPointer = generateLocationAccessed(
524 Stmt, Store, Pointer, ScalarMaps[0], GlobalMaps[0], VLTS[0]);
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000525
Tobias Grosserc14582f2013-02-05 18:01:29 +0000526 Value *VectorPtr =
527 Builder.CreateBitCast(NewPointer, VectorPtrType, "vector_ptr");
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000528 StoreInst *Store = Builder.CreateStore(Vector, VectorPtr);
529
530 if (!Aligned)
531 Store->setAlignment(8);
532 } else {
533 for (unsigned i = 0; i < ScalarMaps.size(); i++) {
Tobias Grosser1bb59b02012-12-29 23:47:38 +0000534 Value *Scalar = Builder.CreateExtractElement(Vector, Builder.getInt32(i));
Johannes Doerfert731685e2014-10-08 17:25:30 +0000535 Value *NewPointer = generateLocationAccessed(
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000536 Stmt, Store, Pointer, ScalarMaps[i], GlobalMaps[i], VLTS[i]);
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000537 Builder.CreateStore(Scalar, NewPointer);
538 }
539 }
540}
541
542bool VectorBlockGenerator::hasVectorOperands(const Instruction *Inst,
543 ValueMapT &VectorMap) {
Tobias Grosser91f5b262014-06-04 08:06:40 +0000544 for (Value *Operand : Inst->operands())
545 if (VectorMap.count(Operand))
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000546 return true;
547 return false;
548}
549
550bool VectorBlockGenerator::extractScalarValues(const Instruction *Inst,
551 ValueMapT &VectorMap,
552 VectorValueMapT &ScalarMaps) {
553 bool HasVectorOperand = false;
554 int VectorWidth = getVectorWidth();
555
Tobias Grosser91f5b262014-06-04 08:06:40 +0000556 for (Value *Operand : Inst->operands()) {
557 ValueMapT::iterator VecOp = VectorMap.find(Operand);
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000558
559 if (VecOp == VectorMap.end())
560 continue;
561
562 HasVectorOperand = true;
563 Value *NewVector = VecOp->second;
564
565 for (int i = 0; i < VectorWidth; ++i) {
566 ValueMapT &SM = ScalarMaps[i];
567
568 // If there is one scalar extracted, all scalar elements should have
569 // already been extracted by the code here. So no need to check for the
570 // existance of all of them.
Tobias Grosser91f5b262014-06-04 08:06:40 +0000571 if (SM.count(Operand))
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000572 break;
573
Tobias Grosser91f5b262014-06-04 08:06:40 +0000574 SM[Operand] =
575 Builder.CreateExtractElement(NewVector, Builder.getInt32(i));
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000576 }
577 }
578
579 return HasVectorOperand;
580}
581
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000582void VectorBlockGenerator::copyInstScalarized(ScopStmt &Stmt,
583 const Instruction *Inst,
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000584 ValueMapT &VectorMap,
585 VectorValueMapT &ScalarMaps) {
586 bool HasVectorOperand;
587 int VectorWidth = getVectorWidth();
588
589 HasVectorOperand = extractScalarValues(Inst, VectorMap, ScalarMaps);
590
591 for (int VectorLane = 0; VectorLane < getVectorWidth(); VectorLane++)
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000592 BlockGenerator::copyInstruction(Stmt, Inst, ScalarMaps[VectorLane],
Johannes Doerfert731685e2014-10-08 17:25:30 +0000593 GlobalMaps[VectorLane], VLTS[VectorLane]);
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000594
595 if (!VectorType::isValidElementType(Inst->getType()) || !HasVectorOperand)
596 return;
597
598 // Make the result available as vector value.
599 VectorType *VectorType = VectorType::get(Inst->getType(), VectorWidth);
600 Value *Vector = UndefValue::get(VectorType);
601
602 for (int i = 0; i < VectorWidth; i++)
603 Vector = Builder.CreateInsertElement(Vector, ScalarMaps[i][Inst],
604 Builder.getInt32(i));
605
606 VectorMap[Inst] = Vector;
607}
608
Tobias Grosserc14582f2013-02-05 18:01:29 +0000609int VectorBlockGenerator::getVectorWidth() { return GlobalMaps.size(); }
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000610
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000611void VectorBlockGenerator::copyInstruction(ScopStmt &Stmt,
612 const Instruction *Inst,
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000613 ValueMapT &VectorMap,
614 VectorValueMapT &ScalarMaps) {
615 // Terminator instructions control the control flow. They are explicitly
616 // expressed in the clast and do not need to be copied.
617 if (Inst->isTerminator())
618 return;
619
Johannes Doerfert1ef52332015-02-08 20:50:42 +0000620 if (canSynthesize(Inst, &LI, &SE, &Stmt.getParent()->getRegion()))
Tobias Grossere71c6ab2012-04-27 16:36:14 +0000621 return;
622
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000623 if (const LoadInst *Load = dyn_cast<LoadInst>(Inst)) {
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000624 generateLoad(Stmt, Load, VectorMap, ScalarMaps);
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000625 return;
626 }
627
628 if (hasVectorOperands(Inst, VectorMap)) {
629 if (const StoreInst *Store = dyn_cast<StoreInst>(Inst)) {
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000630 copyStore(Stmt, Store, VectorMap, ScalarMaps);
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000631 return;
632 }
633
634 if (const UnaryInstruction *Unary = dyn_cast<UnaryInstruction>(Inst)) {
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000635 copyUnaryInst(Stmt, Unary, VectorMap, ScalarMaps);
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000636 return;
637 }
638
639 if (const BinaryOperator *Binary = dyn_cast<BinaryOperator>(Inst)) {
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000640 copyBinaryInst(Stmt, Binary, VectorMap, ScalarMaps);
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000641 return;
642 }
643
644 // Falltrough: We generate scalar instructions, if we don't know how to
645 // generate vector code.
646 }
647
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000648 copyInstScalarized(Stmt, Inst, VectorMap, ScalarMaps);
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000649}
650
Johannes Doerfert275a1752015-02-24 16:16:32 +0000651void VectorBlockGenerator::copyStmt(ScopStmt &Stmt) {
652 assert(Stmt.isBlockStmt() && "TODO: Only block statements can be copied by "
653 "the vector block generator");
654
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000655 BasicBlock *BB = Stmt.getBasicBlock();
Tobias Grosserc14582f2013-02-05 18:01:29 +0000656 BasicBlock *CopyBB =
Johannes Doerfertb4f08eb2015-02-23 13:51:35 +0000657 SplitBlock(Builder.GetInsertBlock(), Builder.GetInsertPoint(), &DT, &LI);
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000658 CopyBB->setName("polly.stmt." + BB->getName());
659 Builder.SetInsertPoint(CopyBB->begin());
660
661 // Create two maps that store the mapping from the original instructions of
662 // the old basic block to their copies in the new basic block. Those maps
663 // are basic block local.
664 //
665 // As vector code generation is supported there is one map for scalar values
666 // and one for vector values.
667 //
668 // In case we just do scalar code generation, the vectorMap is not used and
669 // the scalarMap has just one dimension, which contains the mapping.
670 //
671 // In case vector code generation is done, an instruction may either appear
672 // in the vector map once (as it is calculating >vectorwidth< values at a
673 // time. Or (if the values are calculated using scalar operations), it
674 // appears once in every dimension of the scalarMap.
675 VectorValueMapT ScalarBlockMap(getVectorWidth());
676 ValueMapT VectorBlockMap;
677
Tobias Grosser91f5b262014-06-04 08:06:40 +0000678 for (Instruction &Inst : *BB)
Johannes Doerfertbe9c9112015-02-06 21:39:31 +0000679 copyInstruction(Stmt, &Inst, VectorBlockMap, ScalarBlockMap);
Hongbin Zheng3b11a162012-04-25 13:16:49 +0000680}
Johannes Doerfert275a1752015-02-24 16:16:32 +0000681
Johannes Doerfert514f6ef2015-02-27 18:29:04 +0000682BasicBlock *RegionGenerator::repairDominance(
683 BasicBlock *BB, BasicBlock *BBCopy,
684 DenseMap<BasicBlock *, BasicBlock *> &BlockMap) {
685
686 BasicBlock *BBIDom = DT.getNode(BB)->getIDom()->getBlock();
687 BasicBlock *BBCopyIDom = BlockMap.lookup(BBIDom);
688
689 if (BBCopyIDom)
690 DT.changeImmediateDominator(BBCopy, BBCopyIDom);
691
692 return BBCopyIDom;
693}
694
Johannes Doerfert275a1752015-02-24 16:16:32 +0000695void RegionGenerator::copyStmt(ScopStmt &Stmt, ValueMapT &GlobalMap,
696 LoopToScevMapT &LTS) {
697 assert(Stmt.isRegionStmt() &&
698 "Only region statements can be copied by the block generator");
699
700 // The region represented by the statement.
701 Region *R = Stmt.getRegion();
702
Johannes Doerfert514f6ef2015-02-27 18:29:04 +0000703 // The "BBMaps" for the whole region.
704 DenseMap<BasicBlock *, ValueMapT> RegionMaps;
705
706 // A map from old to new blocks in the region
707 DenseMap<BasicBlock *, BasicBlock *> BlockMap;
Johannes Doerfert275a1752015-02-24 16:16:32 +0000708
709 // Iterate over all blocks in the region in a breadth-first search.
710 std::deque<BasicBlock *> Blocks;
711 SmallPtrSet<BasicBlock *, 8> SeenBlocks;
712 Blocks.push_back(R->getEntry());
713 SeenBlocks.insert(R->getEntry());
714
715 while (!Blocks.empty()) {
716 BasicBlock *BB = Blocks.front();
717 Blocks.pop_front();
718
Johannes Doerfert514f6ef2015-02-27 18:29:04 +0000719 // First split the block and update dominance information.
720 BasicBlock *BBCopy = splitBB(BB);
721 BasicBlock *BBCopyIDom = repairDominance(BB, BBCopy, BlockMap);
722
723 // Get the mapping for this block and initialize it with the mapping
724 // available at its immediate dominator (in the new region).
725 ValueMapT &RegionMap = RegionMaps[BBCopy];
726 RegionMap = RegionMaps[BBCopyIDom];
727
Johannes Doerfert275a1752015-02-24 16:16:32 +0000728 // Copy the block with the BlockGenerator.
Johannes Doerfert514f6ef2015-02-27 18:29:04 +0000729 copyBB(Stmt, BB, BBCopy, RegionMap, GlobalMap, LTS);
Johannes Doerfert275a1752015-02-24 16:16:32 +0000730
731 // And continue with new successors inside the region.
732 for (auto SI = succ_begin(BB), SE = succ_end(BB); SI != SE; SI++)
733 if (R->contains(*SI) && SeenBlocks.insert(*SI).second)
734 Blocks.push_back(*SI);
735
736 // In order to remap PHI nodes we store also basic block mappings.
Johannes Doerfert514f6ef2015-02-27 18:29:04 +0000737 BlockMap[BB] = BBCopy;
Johannes Doerfert275a1752015-02-24 16:16:32 +0000738 }
739
740 // Now create a new dedicated region exit block and add it to the region map.
Johannes Doerfert514f6ef2015-02-27 18:29:04 +0000741 BasicBlock *ExitBBCopy =
Johannes Doerfert275a1752015-02-24 16:16:32 +0000742 SplitBlock(Builder.GetInsertBlock(), Builder.GetInsertPoint(), &DT, &LI);
Johannes Doerfert514f6ef2015-02-27 18:29:04 +0000743 ExitBBCopy->setName("polly.stmt." + R->getExit()->getName() + ".as.exit");
744 BlockMap[R->getExit()] = ExitBBCopy;
745
746 repairDominance(R->getExit(), ExitBBCopy, BlockMap);
Johannes Doerfert275a1752015-02-24 16:16:32 +0000747
748 // As the block generator doesn't handle control flow we need to add the
749 // region control flow by hand after all blocks have been copied.
750 for (BasicBlock *BB : SeenBlocks) {
751
752 BranchInst *BI = cast<BranchInst>(BB->getTerminator());
753
Johannes Doerfert514f6ef2015-02-27 18:29:04 +0000754 BasicBlock *BBCopy = BlockMap[BB];
Johannes Doerfert275a1752015-02-24 16:16:32 +0000755 Instruction *BICopy = BBCopy->getTerminator();
756
Johannes Doerfert514f6ef2015-02-27 18:29:04 +0000757 ValueMapT &RegionMap = RegionMaps[BBCopy];
758 RegionMap.insert(BlockMap.begin(), BlockMap.end());
759
Johannes Doerfert275a1752015-02-24 16:16:32 +0000760 Builder.SetInsertPoint(BBCopy);
761 copyInstScalar(Stmt, BI, RegionMap, GlobalMap, LTS);
762 BICopy->eraseFromParent();
763 }
764
765 // Reset the old insert point for the build.
Johannes Doerfert514f6ef2015-02-27 18:29:04 +0000766 Builder.SetInsertPoint(ExitBBCopy->begin());
Johannes Doerfert275a1752015-02-24 16:16:32 +0000767}