annotate polly/lib/Support/ScopHelper.cpp @ 150:1d019706d866

LLVM10
author anatofuz
date Thu, 13 Feb 2020 15:10:13 +0900
parents
children 0572611fdcc8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
150
anatofuz
parents:
diff changeset
1 //===- ScopHelper.cpp - Some Helper Functions for Scop. ------------------===//
anatofuz
parents:
diff changeset
2 //
anatofuz
parents:
diff changeset
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
anatofuz
parents:
diff changeset
4 // See https://llvm.org/LICENSE.txt for license information.
anatofuz
parents:
diff changeset
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
anatofuz
parents:
diff changeset
6 //
anatofuz
parents:
diff changeset
7 //===----------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
8 //
anatofuz
parents:
diff changeset
9 // Small functions that help with Scop and LLVM-IR.
anatofuz
parents:
diff changeset
10 //
anatofuz
parents:
diff changeset
11 //===----------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
12
anatofuz
parents:
diff changeset
13 #include "polly/Support/ScopHelper.h"
anatofuz
parents:
diff changeset
14 #include "polly/Options.h"
anatofuz
parents:
diff changeset
15 #include "polly/ScopInfo.h"
anatofuz
parents:
diff changeset
16 #include "polly/Support/SCEVValidator.h"
anatofuz
parents:
diff changeset
17 #include "llvm/Analysis/LoopInfo.h"
anatofuz
parents:
diff changeset
18 #include "llvm/Analysis/RegionInfo.h"
anatofuz
parents:
diff changeset
19 #include "llvm/Analysis/ScalarEvolution.h"
anatofuz
parents:
diff changeset
20 #include "llvm/Analysis/ScalarEvolutionExpander.h"
anatofuz
parents:
diff changeset
21 #include "llvm/Analysis/ScalarEvolutionExpressions.h"
anatofuz
parents:
diff changeset
22 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
anatofuz
parents:
diff changeset
23
anatofuz
parents:
diff changeset
24 using namespace llvm;
anatofuz
parents:
diff changeset
25 using namespace polly;
anatofuz
parents:
diff changeset
26
anatofuz
parents:
diff changeset
27 #define DEBUG_TYPE "polly-scop-helper"
anatofuz
parents:
diff changeset
28
anatofuz
parents:
diff changeset
29 static cl::opt<bool> PollyAllowErrorBlocks(
anatofuz
parents:
diff changeset
30 "polly-allow-error-blocks",
anatofuz
parents:
diff changeset
31 cl::desc("Allow to speculate on the execution of 'error blocks'."),
anatofuz
parents:
diff changeset
32 cl::Hidden, cl::init(true), cl::ZeroOrMore, cl::cat(PollyCategory));
anatofuz
parents:
diff changeset
33
anatofuz
parents:
diff changeset
34 static cl::list<std::string> DebugFunctions(
anatofuz
parents:
diff changeset
35 "polly-debug-func",
anatofuz
parents:
diff changeset
36 cl::desc("Allow calls to the specified functions in SCoPs even if their "
anatofuz
parents:
diff changeset
37 "side-effects are unknown. This can be used to do debug output in "
anatofuz
parents:
diff changeset
38 "Polly-transformed code."),
anatofuz
parents:
diff changeset
39 cl::Hidden, cl::ZeroOrMore, cl::CommaSeparated, cl::cat(PollyCategory));
anatofuz
parents:
diff changeset
40
anatofuz
parents:
diff changeset
41 // Ensures that there is just one predecessor to the entry node from outside the
anatofuz
parents:
diff changeset
42 // region.
anatofuz
parents:
diff changeset
43 // The identity of the region entry node is preserved.
anatofuz
parents:
diff changeset
44 static void simplifyRegionEntry(Region *R, DominatorTree *DT, LoopInfo *LI,
anatofuz
parents:
diff changeset
45 RegionInfo *RI) {
anatofuz
parents:
diff changeset
46 BasicBlock *EnteringBB = R->getEnteringBlock();
anatofuz
parents:
diff changeset
47 BasicBlock *Entry = R->getEntry();
anatofuz
parents:
diff changeset
48
anatofuz
parents:
diff changeset
49 // Before (one of):
anatofuz
parents:
diff changeset
50 //
anatofuz
parents:
diff changeset
51 // \ / //
anatofuz
parents:
diff changeset
52 // EnteringBB //
anatofuz
parents:
diff changeset
53 // | \------> //
anatofuz
parents:
diff changeset
54 // \ / | //
anatofuz
parents:
diff changeset
55 // Entry <--\ Entry <--\ //
anatofuz
parents:
diff changeset
56 // / \ / / \ / //
anatofuz
parents:
diff changeset
57 // .... .... //
anatofuz
parents:
diff changeset
58
anatofuz
parents:
diff changeset
59 // Create single entry edge if the region has multiple entry edges.
anatofuz
parents:
diff changeset
60 if (!EnteringBB) {
anatofuz
parents:
diff changeset
61 SmallVector<BasicBlock *, 4> Preds;
anatofuz
parents:
diff changeset
62 for (BasicBlock *P : predecessors(Entry))
anatofuz
parents:
diff changeset
63 if (!R->contains(P))
anatofuz
parents:
diff changeset
64 Preds.push_back(P);
anatofuz
parents:
diff changeset
65
anatofuz
parents:
diff changeset
66 BasicBlock *NewEntering =
anatofuz
parents:
diff changeset
67 SplitBlockPredecessors(Entry, Preds, ".region_entering", DT, LI);
anatofuz
parents:
diff changeset
68
anatofuz
parents:
diff changeset
69 if (RI) {
anatofuz
parents:
diff changeset
70 // The exit block of predecessing regions must be changed to NewEntering
anatofuz
parents:
diff changeset
71 for (BasicBlock *ExitPred : predecessors(NewEntering)) {
anatofuz
parents:
diff changeset
72 Region *RegionOfPred = RI->getRegionFor(ExitPred);
anatofuz
parents:
diff changeset
73 if (RegionOfPred->getExit() != Entry)
anatofuz
parents:
diff changeset
74 continue;
anatofuz
parents:
diff changeset
75
anatofuz
parents:
diff changeset
76 while (!RegionOfPred->isTopLevelRegion() &&
anatofuz
parents:
diff changeset
77 RegionOfPred->getExit() == Entry) {
anatofuz
parents:
diff changeset
78 RegionOfPred->replaceExit(NewEntering);
anatofuz
parents:
diff changeset
79 RegionOfPred = RegionOfPred->getParent();
anatofuz
parents:
diff changeset
80 }
anatofuz
parents:
diff changeset
81 }
anatofuz
parents:
diff changeset
82
anatofuz
parents:
diff changeset
83 // Make all ancestors use EnteringBB as entry; there might be edges to it
anatofuz
parents:
diff changeset
84 Region *AncestorR = R->getParent();
anatofuz
parents:
diff changeset
85 RI->setRegionFor(NewEntering, AncestorR);
anatofuz
parents:
diff changeset
86 while (!AncestorR->isTopLevelRegion() && AncestorR->getEntry() == Entry) {
anatofuz
parents:
diff changeset
87 AncestorR->replaceEntry(NewEntering);
anatofuz
parents:
diff changeset
88 AncestorR = AncestorR->getParent();
anatofuz
parents:
diff changeset
89 }
anatofuz
parents:
diff changeset
90 }
anatofuz
parents:
diff changeset
91
anatofuz
parents:
diff changeset
92 EnteringBB = NewEntering;
anatofuz
parents:
diff changeset
93 }
anatofuz
parents:
diff changeset
94 assert(R->getEnteringBlock() == EnteringBB);
anatofuz
parents:
diff changeset
95
anatofuz
parents:
diff changeset
96 // After:
anatofuz
parents:
diff changeset
97 //
anatofuz
parents:
diff changeset
98 // \ / //
anatofuz
parents:
diff changeset
99 // EnteringBB //
anatofuz
parents:
diff changeset
100 // | //
anatofuz
parents:
diff changeset
101 // | //
anatofuz
parents:
diff changeset
102 // Entry <--\ //
anatofuz
parents:
diff changeset
103 // / \ / //
anatofuz
parents:
diff changeset
104 // .... //
anatofuz
parents:
diff changeset
105 }
anatofuz
parents:
diff changeset
106
anatofuz
parents:
diff changeset
107 // Ensure that the region has a single block that branches to the exit node.
anatofuz
parents:
diff changeset
108 static void simplifyRegionExit(Region *R, DominatorTree *DT, LoopInfo *LI,
anatofuz
parents:
diff changeset
109 RegionInfo *RI) {
anatofuz
parents:
diff changeset
110 BasicBlock *ExitBB = R->getExit();
anatofuz
parents:
diff changeset
111 BasicBlock *ExitingBB = R->getExitingBlock();
anatofuz
parents:
diff changeset
112
anatofuz
parents:
diff changeset
113 // Before:
anatofuz
parents:
diff changeset
114 //
anatofuz
parents:
diff changeset
115 // (Region) ______/ //
anatofuz
parents:
diff changeset
116 // \ | / //
anatofuz
parents:
diff changeset
117 // ExitBB //
anatofuz
parents:
diff changeset
118 // / \ //
anatofuz
parents:
diff changeset
119
anatofuz
parents:
diff changeset
120 if (!ExitingBB) {
anatofuz
parents:
diff changeset
121 SmallVector<BasicBlock *, 4> Preds;
anatofuz
parents:
diff changeset
122 for (BasicBlock *P : predecessors(ExitBB))
anatofuz
parents:
diff changeset
123 if (R->contains(P))
anatofuz
parents:
diff changeset
124 Preds.push_back(P);
anatofuz
parents:
diff changeset
125
anatofuz
parents:
diff changeset
126 // Preds[0] Preds[1] otherBB //
anatofuz
parents:
diff changeset
127 // \ | ________/ //
anatofuz
parents:
diff changeset
128 // \ | / //
anatofuz
parents:
diff changeset
129 // BB //
anatofuz
parents:
diff changeset
130 ExitingBB =
anatofuz
parents:
diff changeset
131 SplitBlockPredecessors(ExitBB, Preds, ".region_exiting", DT, LI);
anatofuz
parents:
diff changeset
132 // Preds[0] Preds[1] otherBB //
anatofuz
parents:
diff changeset
133 // \ / / //
anatofuz
parents:
diff changeset
134 // BB.region_exiting / //
anatofuz
parents:
diff changeset
135 // \ / //
anatofuz
parents:
diff changeset
136 // BB //
anatofuz
parents:
diff changeset
137
anatofuz
parents:
diff changeset
138 if (RI)
anatofuz
parents:
diff changeset
139 RI->setRegionFor(ExitingBB, R);
anatofuz
parents:
diff changeset
140
anatofuz
parents:
diff changeset
141 // Change the exit of nested regions, but not the region itself,
anatofuz
parents:
diff changeset
142 R->replaceExitRecursive(ExitingBB);
anatofuz
parents:
diff changeset
143 R->replaceExit(ExitBB);
anatofuz
parents:
diff changeset
144 }
anatofuz
parents:
diff changeset
145 assert(ExitingBB == R->getExitingBlock());
anatofuz
parents:
diff changeset
146
anatofuz
parents:
diff changeset
147 // After:
anatofuz
parents:
diff changeset
148 //
anatofuz
parents:
diff changeset
149 // \ / //
anatofuz
parents:
diff changeset
150 // ExitingBB _____/ //
anatofuz
parents:
diff changeset
151 // \ / //
anatofuz
parents:
diff changeset
152 // ExitBB //
anatofuz
parents:
diff changeset
153 // / \ //
anatofuz
parents:
diff changeset
154 }
anatofuz
parents:
diff changeset
155
anatofuz
parents:
diff changeset
156 void polly::simplifyRegion(Region *R, DominatorTree *DT, LoopInfo *LI,
anatofuz
parents:
diff changeset
157 RegionInfo *RI) {
anatofuz
parents:
diff changeset
158 assert(R && !R->isTopLevelRegion());
anatofuz
parents:
diff changeset
159 assert(!RI || RI == R->getRegionInfo());
anatofuz
parents:
diff changeset
160 assert((!RI || DT) &&
anatofuz
parents:
diff changeset
161 "RegionInfo requires DominatorTree to be updated as well");
anatofuz
parents:
diff changeset
162
anatofuz
parents:
diff changeset
163 simplifyRegionEntry(R, DT, LI, RI);
anatofuz
parents:
diff changeset
164 simplifyRegionExit(R, DT, LI, RI);
anatofuz
parents:
diff changeset
165 assert(R->isSimple());
anatofuz
parents:
diff changeset
166 }
anatofuz
parents:
diff changeset
167
anatofuz
parents:
diff changeset
168 // Split the block into two successive blocks.
anatofuz
parents:
diff changeset
169 //
anatofuz
parents:
diff changeset
170 // Like llvm::SplitBlock, but also preserves RegionInfo
anatofuz
parents:
diff changeset
171 static BasicBlock *splitBlock(BasicBlock *Old, Instruction *SplitPt,
anatofuz
parents:
diff changeset
172 DominatorTree *DT, llvm::LoopInfo *LI,
anatofuz
parents:
diff changeset
173 RegionInfo *RI) {
anatofuz
parents:
diff changeset
174 assert(Old && SplitPt);
anatofuz
parents:
diff changeset
175
anatofuz
parents:
diff changeset
176 // Before:
anatofuz
parents:
diff changeset
177 //
anatofuz
parents:
diff changeset
178 // \ / //
anatofuz
parents:
diff changeset
179 // Old //
anatofuz
parents:
diff changeset
180 // / \ //
anatofuz
parents:
diff changeset
181
anatofuz
parents:
diff changeset
182 BasicBlock *NewBlock = llvm::SplitBlock(Old, SplitPt, DT, LI);
anatofuz
parents:
diff changeset
183
anatofuz
parents:
diff changeset
184 if (RI) {
anatofuz
parents:
diff changeset
185 Region *R = RI->getRegionFor(Old);
anatofuz
parents:
diff changeset
186 RI->setRegionFor(NewBlock, R);
anatofuz
parents:
diff changeset
187 }
anatofuz
parents:
diff changeset
188
anatofuz
parents:
diff changeset
189 // After:
anatofuz
parents:
diff changeset
190 //
anatofuz
parents:
diff changeset
191 // \ / //
anatofuz
parents:
diff changeset
192 // Old //
anatofuz
parents:
diff changeset
193 // | //
anatofuz
parents:
diff changeset
194 // NewBlock //
anatofuz
parents:
diff changeset
195 // / \ //
anatofuz
parents:
diff changeset
196
anatofuz
parents:
diff changeset
197 return NewBlock;
anatofuz
parents:
diff changeset
198 }
anatofuz
parents:
diff changeset
199
anatofuz
parents:
diff changeset
200 void polly::splitEntryBlockForAlloca(BasicBlock *EntryBlock, DominatorTree *DT,
anatofuz
parents:
diff changeset
201 LoopInfo *LI, RegionInfo *RI) {
anatofuz
parents:
diff changeset
202 // Find first non-alloca instruction. Every basic block has a non-alloca
anatofuz
parents:
diff changeset
203 // instruction, as every well formed basic block has a terminator.
anatofuz
parents:
diff changeset
204 BasicBlock::iterator I = EntryBlock->begin();
anatofuz
parents:
diff changeset
205 while (isa<AllocaInst>(I))
anatofuz
parents:
diff changeset
206 ++I;
anatofuz
parents:
diff changeset
207
anatofuz
parents:
diff changeset
208 // splitBlock updates DT, LI and RI.
anatofuz
parents:
diff changeset
209 splitBlock(EntryBlock, &*I, DT, LI, RI);
anatofuz
parents:
diff changeset
210 }
anatofuz
parents:
diff changeset
211
anatofuz
parents:
diff changeset
212 void polly::splitEntryBlockForAlloca(BasicBlock *EntryBlock, Pass *P) {
anatofuz
parents:
diff changeset
213 auto *DTWP = P->getAnalysisIfAvailable<DominatorTreeWrapperPass>();
anatofuz
parents:
diff changeset
214 auto *DT = DTWP ? &DTWP->getDomTree() : nullptr;
anatofuz
parents:
diff changeset
215 auto *LIWP = P->getAnalysisIfAvailable<LoopInfoWrapperPass>();
anatofuz
parents:
diff changeset
216 auto *LI = LIWP ? &LIWP->getLoopInfo() : nullptr;
anatofuz
parents:
diff changeset
217 RegionInfoPass *RIP = P->getAnalysisIfAvailable<RegionInfoPass>();
anatofuz
parents:
diff changeset
218 RegionInfo *RI = RIP ? &RIP->getRegionInfo() : nullptr;
anatofuz
parents:
diff changeset
219
anatofuz
parents:
diff changeset
220 // splitBlock updates DT, LI and RI.
anatofuz
parents:
diff changeset
221 polly::splitEntryBlockForAlloca(EntryBlock, DT, LI, RI);
anatofuz
parents:
diff changeset
222 }
anatofuz
parents:
diff changeset
223
anatofuz
parents:
diff changeset
224 void polly::recordAssumption(polly::RecordedAssumptionsTy *RecordedAssumptions,
anatofuz
parents:
diff changeset
225 polly::AssumptionKind Kind, isl::set Set,
anatofuz
parents:
diff changeset
226 DebugLoc Loc, polly::AssumptionSign Sign,
anatofuz
parents:
diff changeset
227 BasicBlock *BB) {
anatofuz
parents:
diff changeset
228 assert((Set.is_params() || BB) &&
anatofuz
parents:
diff changeset
229 "Assumptions without a basic block must be parameter sets");
anatofuz
parents:
diff changeset
230 if (RecordedAssumptions)
anatofuz
parents:
diff changeset
231 RecordedAssumptions->push_back({Kind, Sign, Set, Loc, BB});
anatofuz
parents:
diff changeset
232 }
anatofuz
parents:
diff changeset
233
anatofuz
parents:
diff changeset
234 /// The SCEVExpander will __not__ generate any code for an existing SDiv/SRem
anatofuz
parents:
diff changeset
235 /// instruction but just use it, if it is referenced as a SCEVUnknown. We want
anatofuz
parents:
diff changeset
236 /// however to generate new code if the instruction is in the analyzed region
anatofuz
parents:
diff changeset
237 /// and we generate code outside/in front of that region. Hence, we generate the
anatofuz
parents:
diff changeset
238 /// code for the SDiv/SRem operands in front of the analyzed region and then
anatofuz
parents:
diff changeset
239 /// create a new SDiv/SRem operation there too.
anatofuz
parents:
diff changeset
240 struct ScopExpander : SCEVVisitor<ScopExpander, const SCEV *> {
anatofuz
parents:
diff changeset
241 friend struct SCEVVisitor<ScopExpander, const SCEV *>;
anatofuz
parents:
diff changeset
242
anatofuz
parents:
diff changeset
243 explicit ScopExpander(const Region &R, ScalarEvolution &SE,
anatofuz
parents:
diff changeset
244 const DataLayout &DL, const char *Name, ValueMapT *VMap,
anatofuz
parents:
diff changeset
245 BasicBlock *RTCBB)
anatofuz
parents:
diff changeset
246 : Expander(SCEVExpander(SE, DL, Name)), SE(SE), Name(Name), R(R),
anatofuz
parents:
diff changeset
247 VMap(VMap), RTCBB(RTCBB) {}
anatofuz
parents:
diff changeset
248
anatofuz
parents:
diff changeset
249 Value *expandCodeFor(const SCEV *E, Type *Ty, Instruction *I) {
anatofuz
parents:
diff changeset
250 // If we generate code in the region we will immediately fall back to the
anatofuz
parents:
diff changeset
251 // SCEVExpander, otherwise we will stop at all unknowns in the SCEV and if
anatofuz
parents:
diff changeset
252 // needed replace them by copies computed in the entering block.
anatofuz
parents:
diff changeset
253 if (!R.contains(I))
anatofuz
parents:
diff changeset
254 E = visit(E);
anatofuz
parents:
diff changeset
255 return Expander.expandCodeFor(E, Ty, I);
anatofuz
parents:
diff changeset
256 }
anatofuz
parents:
diff changeset
257
anatofuz
parents:
diff changeset
258 const SCEV *visit(const SCEV *E) {
anatofuz
parents:
diff changeset
259 // Cache the expansion results for intermediate SCEV expressions. A SCEV
anatofuz
parents:
diff changeset
260 // expression can refer to an operand multiple times (e.g. "x*x), so
anatofuz
parents:
diff changeset
261 // a naive visitor takes exponential time.
anatofuz
parents:
diff changeset
262 if (SCEVCache.count(E))
anatofuz
parents:
diff changeset
263 return SCEVCache[E];
anatofuz
parents:
diff changeset
264 const SCEV *Result = SCEVVisitor::visit(E);
anatofuz
parents:
diff changeset
265 SCEVCache[E] = Result;
anatofuz
parents:
diff changeset
266 return Result;
anatofuz
parents:
diff changeset
267 }
anatofuz
parents:
diff changeset
268
anatofuz
parents:
diff changeset
269 private:
anatofuz
parents:
diff changeset
270 SCEVExpander Expander;
anatofuz
parents:
diff changeset
271 ScalarEvolution &SE;
anatofuz
parents:
diff changeset
272 const char *Name;
anatofuz
parents:
diff changeset
273 const Region &R;
anatofuz
parents:
diff changeset
274 ValueMapT *VMap;
anatofuz
parents:
diff changeset
275 BasicBlock *RTCBB;
anatofuz
parents:
diff changeset
276 DenseMap<const SCEV *, const SCEV *> SCEVCache;
anatofuz
parents:
diff changeset
277
anatofuz
parents:
diff changeset
278 const SCEV *visitGenericInst(const SCEVUnknown *E, Instruction *Inst,
anatofuz
parents:
diff changeset
279 Instruction *IP) {
anatofuz
parents:
diff changeset
280 if (!Inst || !R.contains(Inst))
anatofuz
parents:
diff changeset
281 return E;
anatofuz
parents:
diff changeset
282
anatofuz
parents:
diff changeset
283 assert(!Inst->mayThrow() && !Inst->mayReadOrWriteMemory() &&
anatofuz
parents:
diff changeset
284 !isa<PHINode>(Inst));
anatofuz
parents:
diff changeset
285
anatofuz
parents:
diff changeset
286 auto *InstClone = Inst->clone();
anatofuz
parents:
diff changeset
287 for (auto &Op : Inst->operands()) {
anatofuz
parents:
diff changeset
288 assert(SE.isSCEVable(Op->getType()));
anatofuz
parents:
diff changeset
289 auto *OpSCEV = SE.getSCEV(Op);
anatofuz
parents:
diff changeset
290 auto *OpClone = expandCodeFor(OpSCEV, Op->getType(), IP);
anatofuz
parents:
diff changeset
291 InstClone->replaceUsesOfWith(Op, OpClone);
anatofuz
parents:
diff changeset
292 }
anatofuz
parents:
diff changeset
293
anatofuz
parents:
diff changeset
294 InstClone->setName(Name + Inst->getName());
anatofuz
parents:
diff changeset
295 InstClone->insertBefore(IP);
anatofuz
parents:
diff changeset
296 return SE.getSCEV(InstClone);
anatofuz
parents:
diff changeset
297 }
anatofuz
parents:
diff changeset
298
anatofuz
parents:
diff changeset
299 const SCEV *visitUnknown(const SCEVUnknown *E) {
anatofuz
parents:
diff changeset
300
anatofuz
parents:
diff changeset
301 // If a value mapping was given try if the underlying value is remapped.
anatofuz
parents:
diff changeset
302 Value *NewVal = VMap ? VMap->lookup(E->getValue()) : nullptr;
anatofuz
parents:
diff changeset
303 if (NewVal) {
anatofuz
parents:
diff changeset
304 auto *NewE = SE.getSCEV(NewVal);
anatofuz
parents:
diff changeset
305
anatofuz
parents:
diff changeset
306 // While the mapped value might be different the SCEV representation might
anatofuz
parents:
diff changeset
307 // not be. To this end we will check before we go into recursion here.
anatofuz
parents:
diff changeset
308 if (E != NewE)
anatofuz
parents:
diff changeset
309 return visit(NewE);
anatofuz
parents:
diff changeset
310 }
anatofuz
parents:
diff changeset
311
anatofuz
parents:
diff changeset
312 Instruction *Inst = dyn_cast<Instruction>(E->getValue());
anatofuz
parents:
diff changeset
313 Instruction *IP;
anatofuz
parents:
diff changeset
314 if (Inst && !R.contains(Inst))
anatofuz
parents:
diff changeset
315 IP = Inst;
anatofuz
parents:
diff changeset
316 else if (Inst && RTCBB->getParent() == Inst->getFunction())
anatofuz
parents:
diff changeset
317 IP = RTCBB->getTerminator();
anatofuz
parents:
diff changeset
318 else
anatofuz
parents:
diff changeset
319 IP = RTCBB->getParent()->getEntryBlock().getTerminator();
anatofuz
parents:
diff changeset
320
anatofuz
parents:
diff changeset
321 if (!Inst || (Inst->getOpcode() != Instruction::SRem &&
anatofuz
parents:
diff changeset
322 Inst->getOpcode() != Instruction::SDiv))
anatofuz
parents:
diff changeset
323 return visitGenericInst(E, Inst, IP);
anatofuz
parents:
diff changeset
324
anatofuz
parents:
diff changeset
325 const SCEV *LHSScev = SE.getSCEV(Inst->getOperand(0));
anatofuz
parents:
diff changeset
326 const SCEV *RHSScev = SE.getSCEV(Inst->getOperand(1));
anatofuz
parents:
diff changeset
327
anatofuz
parents:
diff changeset
328 if (!SE.isKnownNonZero(RHSScev))
anatofuz
parents:
diff changeset
329 RHSScev = SE.getUMaxExpr(RHSScev, SE.getConstant(E->getType(), 1));
anatofuz
parents:
diff changeset
330
anatofuz
parents:
diff changeset
331 Value *LHS = expandCodeFor(LHSScev, E->getType(), IP);
anatofuz
parents:
diff changeset
332 Value *RHS = expandCodeFor(RHSScev, E->getType(), IP);
anatofuz
parents:
diff changeset
333
anatofuz
parents:
diff changeset
334 Inst = BinaryOperator::Create((Instruction::BinaryOps)Inst->getOpcode(),
anatofuz
parents:
diff changeset
335 LHS, RHS, Inst->getName() + Name, IP);
anatofuz
parents:
diff changeset
336 return SE.getSCEV(Inst);
anatofuz
parents:
diff changeset
337 }
anatofuz
parents:
diff changeset
338
anatofuz
parents:
diff changeset
339 /// The following functions will just traverse the SCEV and rebuild it with
anatofuz
parents:
diff changeset
340 /// the new operands returned by the traversal.
anatofuz
parents:
diff changeset
341 ///
anatofuz
parents:
diff changeset
342 ///{
anatofuz
parents:
diff changeset
343 const SCEV *visitConstant(const SCEVConstant *E) { return E; }
anatofuz
parents:
diff changeset
344 const SCEV *visitTruncateExpr(const SCEVTruncateExpr *E) {
anatofuz
parents:
diff changeset
345 return SE.getTruncateExpr(visit(E->getOperand()), E->getType());
anatofuz
parents:
diff changeset
346 }
anatofuz
parents:
diff changeset
347 const SCEV *visitZeroExtendExpr(const SCEVZeroExtendExpr *E) {
anatofuz
parents:
diff changeset
348 return SE.getZeroExtendExpr(visit(E->getOperand()), E->getType());
anatofuz
parents:
diff changeset
349 }
anatofuz
parents:
diff changeset
350 const SCEV *visitSignExtendExpr(const SCEVSignExtendExpr *E) {
anatofuz
parents:
diff changeset
351 return SE.getSignExtendExpr(visit(E->getOperand()), E->getType());
anatofuz
parents:
diff changeset
352 }
anatofuz
parents:
diff changeset
353 const SCEV *visitUDivExpr(const SCEVUDivExpr *E) {
anatofuz
parents:
diff changeset
354 auto *RHSScev = visit(E->getRHS());
anatofuz
parents:
diff changeset
355 if (!SE.isKnownNonZero(RHSScev))
anatofuz
parents:
diff changeset
356 RHSScev = SE.getUMaxExpr(RHSScev, SE.getConstant(E->getType(), 1));
anatofuz
parents:
diff changeset
357 return SE.getUDivExpr(visit(E->getLHS()), RHSScev);
anatofuz
parents:
diff changeset
358 }
anatofuz
parents:
diff changeset
359 const SCEV *visitAddExpr(const SCEVAddExpr *E) {
anatofuz
parents:
diff changeset
360 SmallVector<const SCEV *, 4> NewOps;
anatofuz
parents:
diff changeset
361 for (const SCEV *Op : E->operands())
anatofuz
parents:
diff changeset
362 NewOps.push_back(visit(Op));
anatofuz
parents:
diff changeset
363 return SE.getAddExpr(NewOps);
anatofuz
parents:
diff changeset
364 }
anatofuz
parents:
diff changeset
365 const SCEV *visitMulExpr(const SCEVMulExpr *E) {
anatofuz
parents:
diff changeset
366 SmallVector<const SCEV *, 4> NewOps;
anatofuz
parents:
diff changeset
367 for (const SCEV *Op : E->operands())
anatofuz
parents:
diff changeset
368 NewOps.push_back(visit(Op));
anatofuz
parents:
diff changeset
369 return SE.getMulExpr(NewOps);
anatofuz
parents:
diff changeset
370 }
anatofuz
parents:
diff changeset
371 const SCEV *visitUMaxExpr(const SCEVUMaxExpr *E) {
anatofuz
parents:
diff changeset
372 SmallVector<const SCEV *, 4> NewOps;
anatofuz
parents:
diff changeset
373 for (const SCEV *Op : E->operands())
anatofuz
parents:
diff changeset
374 NewOps.push_back(visit(Op));
anatofuz
parents:
diff changeset
375 return SE.getUMaxExpr(NewOps);
anatofuz
parents:
diff changeset
376 }
anatofuz
parents:
diff changeset
377 const SCEV *visitSMaxExpr(const SCEVSMaxExpr *E) {
anatofuz
parents:
diff changeset
378 SmallVector<const SCEV *, 4> NewOps;
anatofuz
parents:
diff changeset
379 for (const SCEV *Op : E->operands())
anatofuz
parents:
diff changeset
380 NewOps.push_back(visit(Op));
anatofuz
parents:
diff changeset
381 return SE.getSMaxExpr(NewOps);
anatofuz
parents:
diff changeset
382 }
anatofuz
parents:
diff changeset
383 const SCEV *visitUMinExpr(const SCEVUMinExpr *E) {
anatofuz
parents:
diff changeset
384 SmallVector<const SCEV *, 4> NewOps;
anatofuz
parents:
diff changeset
385 for (const SCEV *Op : E->operands())
anatofuz
parents:
diff changeset
386 NewOps.push_back(visit(Op));
anatofuz
parents:
diff changeset
387 return SE.getUMinExpr(NewOps);
anatofuz
parents:
diff changeset
388 }
anatofuz
parents:
diff changeset
389 const SCEV *visitSMinExpr(const SCEVSMinExpr *E) {
anatofuz
parents:
diff changeset
390 SmallVector<const SCEV *, 4> NewOps;
anatofuz
parents:
diff changeset
391 for (const SCEV *Op : E->operands())
anatofuz
parents:
diff changeset
392 NewOps.push_back(visit(Op));
anatofuz
parents:
diff changeset
393 return SE.getSMinExpr(NewOps);
anatofuz
parents:
diff changeset
394 }
anatofuz
parents:
diff changeset
395 const SCEV *visitAddRecExpr(const SCEVAddRecExpr *E) {
anatofuz
parents:
diff changeset
396 SmallVector<const SCEV *, 4> NewOps;
anatofuz
parents:
diff changeset
397 for (const SCEV *Op : E->operands())
anatofuz
parents:
diff changeset
398 NewOps.push_back(visit(Op));
anatofuz
parents:
diff changeset
399 return SE.getAddRecExpr(NewOps, E->getLoop(), E->getNoWrapFlags());
anatofuz
parents:
diff changeset
400 }
anatofuz
parents:
diff changeset
401 ///}
anatofuz
parents:
diff changeset
402 };
anatofuz
parents:
diff changeset
403
anatofuz
parents:
diff changeset
404 Value *polly::expandCodeFor(Scop &S, ScalarEvolution &SE, const DataLayout &DL,
anatofuz
parents:
diff changeset
405 const char *Name, const SCEV *E, Type *Ty,
anatofuz
parents:
diff changeset
406 Instruction *IP, ValueMapT *VMap,
anatofuz
parents:
diff changeset
407 BasicBlock *RTCBB) {
anatofuz
parents:
diff changeset
408 ScopExpander Expander(S.getRegion(), SE, DL, Name, VMap, RTCBB);
anatofuz
parents:
diff changeset
409 return Expander.expandCodeFor(E, Ty, IP);
anatofuz
parents:
diff changeset
410 }
anatofuz
parents:
diff changeset
411
anatofuz
parents:
diff changeset
412 bool polly::isErrorBlock(BasicBlock &BB, const Region &R, LoopInfo &LI,
anatofuz
parents:
diff changeset
413 const DominatorTree &DT) {
anatofuz
parents:
diff changeset
414 if (!PollyAllowErrorBlocks)
anatofuz
parents:
diff changeset
415 return false;
anatofuz
parents:
diff changeset
416
anatofuz
parents:
diff changeset
417 if (isa<UnreachableInst>(BB.getTerminator()))
anatofuz
parents:
diff changeset
418 return true;
anatofuz
parents:
diff changeset
419
anatofuz
parents:
diff changeset
420 if (LI.isLoopHeader(&BB))
anatofuz
parents:
diff changeset
421 return false;
anatofuz
parents:
diff changeset
422
anatofuz
parents:
diff changeset
423 // Basic blocks that are always executed are not considered error blocks,
anatofuz
parents:
diff changeset
424 // as their execution can not be a rare event.
anatofuz
parents:
diff changeset
425 bool DominatesAllPredecessors = true;
anatofuz
parents:
diff changeset
426 if (R.isTopLevelRegion()) {
anatofuz
parents:
diff changeset
427 for (BasicBlock &I : *R.getEntry()->getParent())
anatofuz
parents:
diff changeset
428 if (isa<ReturnInst>(I.getTerminator()) && !DT.dominates(&BB, &I))
anatofuz
parents:
diff changeset
429 DominatesAllPredecessors = false;
anatofuz
parents:
diff changeset
430 } else {
anatofuz
parents:
diff changeset
431 for (auto Pred : predecessors(R.getExit()))
anatofuz
parents:
diff changeset
432 if (R.contains(Pred) && !DT.dominates(&BB, Pred))
anatofuz
parents:
diff changeset
433 DominatesAllPredecessors = false;
anatofuz
parents:
diff changeset
434 }
anatofuz
parents:
diff changeset
435
anatofuz
parents:
diff changeset
436 if (DominatesAllPredecessors)
anatofuz
parents:
diff changeset
437 return false;
anatofuz
parents:
diff changeset
438
anatofuz
parents:
diff changeset
439 for (Instruction &Inst : BB)
anatofuz
parents:
diff changeset
440 if (CallInst *CI = dyn_cast<CallInst>(&Inst)) {
anatofuz
parents:
diff changeset
441 if (isDebugCall(CI))
anatofuz
parents:
diff changeset
442 continue;
anatofuz
parents:
diff changeset
443
anatofuz
parents:
diff changeset
444 if (isIgnoredIntrinsic(CI))
anatofuz
parents:
diff changeset
445 continue;
anatofuz
parents:
diff changeset
446
anatofuz
parents:
diff changeset
447 // memset, memcpy and memmove are modeled intrinsics.
anatofuz
parents:
diff changeset
448 if (isa<MemSetInst>(CI) || isa<MemTransferInst>(CI))
anatofuz
parents:
diff changeset
449 continue;
anatofuz
parents:
diff changeset
450
anatofuz
parents:
diff changeset
451 if (!CI->doesNotAccessMemory())
anatofuz
parents:
diff changeset
452 return true;
anatofuz
parents:
diff changeset
453 if (CI->doesNotReturn())
anatofuz
parents:
diff changeset
454 return true;
anatofuz
parents:
diff changeset
455 }
anatofuz
parents:
diff changeset
456
anatofuz
parents:
diff changeset
457 return false;
anatofuz
parents:
diff changeset
458 }
anatofuz
parents:
diff changeset
459
anatofuz
parents:
diff changeset
460 Value *polly::getConditionFromTerminator(Instruction *TI) {
anatofuz
parents:
diff changeset
461 if (BranchInst *BR = dyn_cast<BranchInst>(TI)) {
anatofuz
parents:
diff changeset
462 if (BR->isUnconditional())
anatofuz
parents:
diff changeset
463 return ConstantInt::getTrue(Type::getInt1Ty(TI->getContext()));
anatofuz
parents:
diff changeset
464
anatofuz
parents:
diff changeset
465 return BR->getCondition();
anatofuz
parents:
diff changeset
466 }
anatofuz
parents:
diff changeset
467
anatofuz
parents:
diff changeset
468 if (SwitchInst *SI = dyn_cast<SwitchInst>(TI))
anatofuz
parents:
diff changeset
469 return SI->getCondition();
anatofuz
parents:
diff changeset
470
anatofuz
parents:
diff changeset
471 return nullptr;
anatofuz
parents:
diff changeset
472 }
anatofuz
parents:
diff changeset
473
anatofuz
parents:
diff changeset
474 Loop *polly::getLoopSurroundingScop(Scop &S, LoopInfo &LI) {
anatofuz
parents:
diff changeset
475 // Start with the smallest loop containing the entry and expand that
anatofuz
parents:
diff changeset
476 // loop until it contains all blocks in the region. If there is a loop
anatofuz
parents:
diff changeset
477 // containing all blocks in the region check if it is itself contained
anatofuz
parents:
diff changeset
478 // and if so take the parent loop as it will be the smallest containing
anatofuz
parents:
diff changeset
479 // the region but not contained by it.
anatofuz
parents:
diff changeset
480 Loop *L = LI.getLoopFor(S.getEntry());
anatofuz
parents:
diff changeset
481 while (L) {
anatofuz
parents:
diff changeset
482 bool AllContained = true;
anatofuz
parents:
diff changeset
483 for (auto *BB : S.blocks())
anatofuz
parents:
diff changeset
484 AllContained &= L->contains(BB);
anatofuz
parents:
diff changeset
485 if (AllContained)
anatofuz
parents:
diff changeset
486 break;
anatofuz
parents:
diff changeset
487 L = L->getParentLoop();
anatofuz
parents:
diff changeset
488 }
anatofuz
parents:
diff changeset
489
anatofuz
parents:
diff changeset
490 return L ? (S.contains(L) ? L->getParentLoop() : L) : nullptr;
anatofuz
parents:
diff changeset
491 }
anatofuz
parents:
diff changeset
492
anatofuz
parents:
diff changeset
493 unsigned polly::getNumBlocksInLoop(Loop *L) {
anatofuz
parents:
diff changeset
494 unsigned NumBlocks = L->getNumBlocks();
anatofuz
parents:
diff changeset
495 SmallVector<BasicBlock *, 4> ExitBlocks;
anatofuz
parents:
diff changeset
496 L->getExitBlocks(ExitBlocks);
anatofuz
parents:
diff changeset
497
anatofuz
parents:
diff changeset
498 for (auto ExitBlock : ExitBlocks) {
anatofuz
parents:
diff changeset
499 if (isa<UnreachableInst>(ExitBlock->getTerminator()))
anatofuz
parents:
diff changeset
500 NumBlocks++;
anatofuz
parents:
diff changeset
501 }
anatofuz
parents:
diff changeset
502 return NumBlocks;
anatofuz
parents:
diff changeset
503 }
anatofuz
parents:
diff changeset
504
anatofuz
parents:
diff changeset
505 unsigned polly::getNumBlocksInRegionNode(RegionNode *RN) {
anatofuz
parents:
diff changeset
506 if (!RN->isSubRegion())
anatofuz
parents:
diff changeset
507 return 1;
anatofuz
parents:
diff changeset
508
anatofuz
parents:
diff changeset
509 Region *R = RN->getNodeAs<Region>();
anatofuz
parents:
diff changeset
510 return std::distance(R->block_begin(), R->block_end());
anatofuz
parents:
diff changeset
511 }
anatofuz
parents:
diff changeset
512
anatofuz
parents:
diff changeset
513 Loop *polly::getRegionNodeLoop(RegionNode *RN, LoopInfo &LI) {
anatofuz
parents:
diff changeset
514 if (!RN->isSubRegion()) {
anatofuz
parents:
diff changeset
515 BasicBlock *BB = RN->getNodeAs<BasicBlock>();
anatofuz
parents:
diff changeset
516 Loop *L = LI.getLoopFor(BB);
anatofuz
parents:
diff changeset
517
anatofuz
parents:
diff changeset
518 // Unreachable statements are not considered to belong to a LLVM loop, as
anatofuz
parents:
diff changeset
519 // they are not part of an actual loop in the control flow graph.
anatofuz
parents:
diff changeset
520 // Nevertheless, we handle certain unreachable statements that are common
anatofuz
parents:
diff changeset
521 // when modeling run-time bounds checks as being part of the loop to be
anatofuz
parents:
diff changeset
522 // able to model them and to later eliminate the run-time bounds checks.
anatofuz
parents:
diff changeset
523 //
anatofuz
parents:
diff changeset
524 // Specifically, for basic blocks that terminate in an unreachable and
anatofuz
parents:
diff changeset
525 // where the immediate predecessor is part of a loop, we assume these
anatofuz
parents:
diff changeset
526 // basic blocks belong to the loop the predecessor belongs to. This
anatofuz
parents:
diff changeset
527 // allows us to model the following code.
anatofuz
parents:
diff changeset
528 //
anatofuz
parents:
diff changeset
529 // for (i = 0; i < N; i++) {
anatofuz
parents:
diff changeset
530 // if (i > 1024)
anatofuz
parents:
diff changeset
531 // abort(); <- this abort might be translated to an
anatofuz
parents:
diff changeset
532 // unreachable
anatofuz
parents:
diff changeset
533 //
anatofuz
parents:
diff changeset
534 // A[i] = ...
anatofuz
parents:
diff changeset
535 // }
anatofuz
parents:
diff changeset
536 if (!L && isa<UnreachableInst>(BB->getTerminator()) && BB->getPrevNode())
anatofuz
parents:
diff changeset
537 L = LI.getLoopFor(BB->getPrevNode());
anatofuz
parents:
diff changeset
538 return L;
anatofuz
parents:
diff changeset
539 }
anatofuz
parents:
diff changeset
540
anatofuz
parents:
diff changeset
541 Region *NonAffineSubRegion = RN->getNodeAs<Region>();
anatofuz
parents:
diff changeset
542 Loop *L = LI.getLoopFor(NonAffineSubRegion->getEntry());
anatofuz
parents:
diff changeset
543 while (L && NonAffineSubRegion->contains(L))
anatofuz
parents:
diff changeset
544 L = L->getParentLoop();
anatofuz
parents:
diff changeset
545 return L;
anatofuz
parents:
diff changeset
546 }
anatofuz
parents:
diff changeset
547
anatofuz
parents:
diff changeset
548 static bool hasVariantIndex(GetElementPtrInst *Gep, Loop *L, Region &R,
anatofuz
parents:
diff changeset
549 ScalarEvolution &SE) {
anatofuz
parents:
diff changeset
550 for (const Use &Val : llvm::drop_begin(Gep->operands(), 1)) {
anatofuz
parents:
diff changeset
551 const SCEV *PtrSCEV = SE.getSCEVAtScope(Val, L);
anatofuz
parents:
diff changeset
552 Loop *OuterLoop = R.outermostLoopInRegion(L);
anatofuz
parents:
diff changeset
553 if (!SE.isLoopInvariant(PtrSCEV, OuterLoop))
anatofuz
parents:
diff changeset
554 return true;
anatofuz
parents:
diff changeset
555 }
anatofuz
parents:
diff changeset
556 return false;
anatofuz
parents:
diff changeset
557 }
anatofuz
parents:
diff changeset
558
anatofuz
parents:
diff changeset
559 bool polly::isHoistableLoad(LoadInst *LInst, Region &R, LoopInfo &LI,
anatofuz
parents:
diff changeset
560 ScalarEvolution &SE, const DominatorTree &DT,
anatofuz
parents:
diff changeset
561 const InvariantLoadsSetTy &KnownInvariantLoads) {
anatofuz
parents:
diff changeset
562 Loop *L = LI.getLoopFor(LInst->getParent());
anatofuz
parents:
diff changeset
563 auto *Ptr = LInst->getPointerOperand();
anatofuz
parents:
diff changeset
564
anatofuz
parents:
diff changeset
565 // A LoadInst is hoistable if the address it is loading from is also
anatofuz
parents:
diff changeset
566 // invariant; in this case: another invariant load (whether that address
anatofuz
parents:
diff changeset
567 // is also not written to has to be checked separately)
anatofuz
parents:
diff changeset
568 // TODO: This only checks for a LoadInst->GetElementPtrInst->LoadInst
anatofuz
parents:
diff changeset
569 // pattern generated by the Chapel frontend, but generally this applies
anatofuz
parents:
diff changeset
570 // for any chain of instruction that does not also depend on any
anatofuz
parents:
diff changeset
571 // induction variable
anatofuz
parents:
diff changeset
572 if (auto *GepInst = dyn_cast<GetElementPtrInst>(Ptr)) {
anatofuz
parents:
diff changeset
573 if (!hasVariantIndex(GepInst, L, R, SE)) {
anatofuz
parents:
diff changeset
574 if (auto *DecidingLoad =
anatofuz
parents:
diff changeset
575 dyn_cast<LoadInst>(GepInst->getPointerOperand())) {
anatofuz
parents:
diff changeset
576 if (KnownInvariantLoads.count(DecidingLoad))
anatofuz
parents:
diff changeset
577 return true;
anatofuz
parents:
diff changeset
578 }
anatofuz
parents:
diff changeset
579 }
anatofuz
parents:
diff changeset
580 }
anatofuz
parents:
diff changeset
581
anatofuz
parents:
diff changeset
582 const SCEV *PtrSCEV = SE.getSCEVAtScope(Ptr, L);
anatofuz
parents:
diff changeset
583 while (L && R.contains(L)) {
anatofuz
parents:
diff changeset
584 if (!SE.isLoopInvariant(PtrSCEV, L))
anatofuz
parents:
diff changeset
585 return false;
anatofuz
parents:
diff changeset
586 L = L->getParentLoop();
anatofuz
parents:
diff changeset
587 }
anatofuz
parents:
diff changeset
588
anatofuz
parents:
diff changeset
589 for (auto *User : Ptr->users()) {
anatofuz
parents:
diff changeset
590 auto *UserI = dyn_cast<Instruction>(User);
anatofuz
parents:
diff changeset
591 if (!UserI || !R.contains(UserI))
anatofuz
parents:
diff changeset
592 continue;
anatofuz
parents:
diff changeset
593 if (!UserI->mayWriteToMemory())
anatofuz
parents:
diff changeset
594 continue;
anatofuz
parents:
diff changeset
595
anatofuz
parents:
diff changeset
596 auto &BB = *UserI->getParent();
anatofuz
parents:
diff changeset
597 if (DT.dominates(&BB, LInst->getParent()))
anatofuz
parents:
diff changeset
598 return false;
anatofuz
parents:
diff changeset
599
anatofuz
parents:
diff changeset
600 bool DominatesAllPredecessors = true;
anatofuz
parents:
diff changeset
601 if (R.isTopLevelRegion()) {
anatofuz
parents:
diff changeset
602 for (BasicBlock &I : *R.getEntry()->getParent())
anatofuz
parents:
diff changeset
603 if (isa<ReturnInst>(I.getTerminator()) && !DT.dominates(&BB, &I))
anatofuz
parents:
diff changeset
604 DominatesAllPredecessors = false;
anatofuz
parents:
diff changeset
605 } else {
anatofuz
parents:
diff changeset
606 for (auto Pred : predecessors(R.getExit()))
anatofuz
parents:
diff changeset
607 if (R.contains(Pred) && !DT.dominates(&BB, Pred))
anatofuz
parents:
diff changeset
608 DominatesAllPredecessors = false;
anatofuz
parents:
diff changeset
609 }
anatofuz
parents:
diff changeset
610
anatofuz
parents:
diff changeset
611 if (!DominatesAllPredecessors)
anatofuz
parents:
diff changeset
612 continue;
anatofuz
parents:
diff changeset
613
anatofuz
parents:
diff changeset
614 return false;
anatofuz
parents:
diff changeset
615 }
anatofuz
parents:
diff changeset
616
anatofuz
parents:
diff changeset
617 return true;
anatofuz
parents:
diff changeset
618 }
anatofuz
parents:
diff changeset
619
anatofuz
parents:
diff changeset
620 bool polly::isIgnoredIntrinsic(const Value *V) {
anatofuz
parents:
diff changeset
621 if (auto *IT = dyn_cast<IntrinsicInst>(V)) {
anatofuz
parents:
diff changeset
622 switch (IT->getIntrinsicID()) {
anatofuz
parents:
diff changeset
623 // Lifetime markers are supported/ignored.
anatofuz
parents:
diff changeset
624 case llvm::Intrinsic::lifetime_start:
anatofuz
parents:
diff changeset
625 case llvm::Intrinsic::lifetime_end:
anatofuz
parents:
diff changeset
626 // Invariant markers are supported/ignored.
anatofuz
parents:
diff changeset
627 case llvm::Intrinsic::invariant_start:
anatofuz
parents:
diff changeset
628 case llvm::Intrinsic::invariant_end:
anatofuz
parents:
diff changeset
629 // Some misc annotations are supported/ignored.
anatofuz
parents:
diff changeset
630 case llvm::Intrinsic::var_annotation:
anatofuz
parents:
diff changeset
631 case llvm::Intrinsic::ptr_annotation:
anatofuz
parents:
diff changeset
632 case llvm::Intrinsic::annotation:
anatofuz
parents:
diff changeset
633 case llvm::Intrinsic::donothing:
anatofuz
parents:
diff changeset
634 case llvm::Intrinsic::assume:
anatofuz
parents:
diff changeset
635 // Some debug info intrinsics are supported/ignored.
anatofuz
parents:
diff changeset
636 case llvm::Intrinsic::dbg_value:
anatofuz
parents:
diff changeset
637 case llvm::Intrinsic::dbg_declare:
anatofuz
parents:
diff changeset
638 return true;
anatofuz
parents:
diff changeset
639 default:
anatofuz
parents:
diff changeset
640 break;
anatofuz
parents:
diff changeset
641 }
anatofuz
parents:
diff changeset
642 }
anatofuz
parents:
diff changeset
643 return false;
anatofuz
parents:
diff changeset
644 }
anatofuz
parents:
diff changeset
645
anatofuz
parents:
diff changeset
646 bool polly::canSynthesize(const Value *V, const Scop &S, ScalarEvolution *SE,
anatofuz
parents:
diff changeset
647 Loop *Scope) {
anatofuz
parents:
diff changeset
648 if (!V || !SE->isSCEVable(V->getType()))
anatofuz
parents:
diff changeset
649 return false;
anatofuz
parents:
diff changeset
650
anatofuz
parents:
diff changeset
651 const InvariantLoadsSetTy &ILS = S.getRequiredInvariantLoads();
anatofuz
parents:
diff changeset
652 if (const SCEV *Scev = SE->getSCEVAtScope(const_cast<Value *>(V), Scope))
anatofuz
parents:
diff changeset
653 if (!isa<SCEVCouldNotCompute>(Scev))
anatofuz
parents:
diff changeset
654 if (!hasScalarDepsInsideRegion(Scev, &S.getRegion(), Scope, false, ILS))
anatofuz
parents:
diff changeset
655 return true;
anatofuz
parents:
diff changeset
656
anatofuz
parents:
diff changeset
657 return false;
anatofuz
parents:
diff changeset
658 }
anatofuz
parents:
diff changeset
659
anatofuz
parents:
diff changeset
660 llvm::BasicBlock *polly::getUseBlock(const llvm::Use &U) {
anatofuz
parents:
diff changeset
661 Instruction *UI = dyn_cast<Instruction>(U.getUser());
anatofuz
parents:
diff changeset
662 if (!UI)
anatofuz
parents:
diff changeset
663 return nullptr;
anatofuz
parents:
diff changeset
664
anatofuz
parents:
diff changeset
665 if (PHINode *PHI = dyn_cast<PHINode>(UI))
anatofuz
parents:
diff changeset
666 return PHI->getIncomingBlock(U);
anatofuz
parents:
diff changeset
667
anatofuz
parents:
diff changeset
668 return UI->getParent();
anatofuz
parents:
diff changeset
669 }
anatofuz
parents:
diff changeset
670
anatofuz
parents:
diff changeset
671 std::tuple<std::vector<const SCEV *>, std::vector<int>>
anatofuz
parents:
diff changeset
672 polly::getIndexExpressionsFromGEP(GetElementPtrInst *GEP, ScalarEvolution &SE) {
anatofuz
parents:
diff changeset
673 std::vector<const SCEV *> Subscripts;
anatofuz
parents:
diff changeset
674 std::vector<int> Sizes;
anatofuz
parents:
diff changeset
675
anatofuz
parents:
diff changeset
676 Type *Ty = GEP->getPointerOperandType();
anatofuz
parents:
diff changeset
677
anatofuz
parents:
diff changeset
678 bool DroppedFirstDim = false;
anatofuz
parents:
diff changeset
679
anatofuz
parents:
diff changeset
680 for (unsigned i = 1; i < GEP->getNumOperands(); i++) {
anatofuz
parents:
diff changeset
681
anatofuz
parents:
diff changeset
682 const SCEV *Expr = SE.getSCEV(GEP->getOperand(i));
anatofuz
parents:
diff changeset
683
anatofuz
parents:
diff changeset
684 if (i == 1) {
anatofuz
parents:
diff changeset
685 if (auto *PtrTy = dyn_cast<PointerType>(Ty)) {
anatofuz
parents:
diff changeset
686 Ty = PtrTy->getElementType();
anatofuz
parents:
diff changeset
687 } else if (auto *ArrayTy = dyn_cast<ArrayType>(Ty)) {
anatofuz
parents:
diff changeset
688 Ty = ArrayTy->getElementType();
anatofuz
parents:
diff changeset
689 } else {
anatofuz
parents:
diff changeset
690 Subscripts.clear();
anatofuz
parents:
diff changeset
691 Sizes.clear();
anatofuz
parents:
diff changeset
692 break;
anatofuz
parents:
diff changeset
693 }
anatofuz
parents:
diff changeset
694 if (auto *Const = dyn_cast<SCEVConstant>(Expr))
anatofuz
parents:
diff changeset
695 if (Const->getValue()->isZero()) {
anatofuz
parents:
diff changeset
696 DroppedFirstDim = true;
anatofuz
parents:
diff changeset
697 continue;
anatofuz
parents:
diff changeset
698 }
anatofuz
parents:
diff changeset
699 Subscripts.push_back(Expr);
anatofuz
parents:
diff changeset
700 continue;
anatofuz
parents:
diff changeset
701 }
anatofuz
parents:
diff changeset
702
anatofuz
parents:
diff changeset
703 auto *ArrayTy = dyn_cast<ArrayType>(Ty);
anatofuz
parents:
diff changeset
704 if (!ArrayTy) {
anatofuz
parents:
diff changeset
705 Subscripts.clear();
anatofuz
parents:
diff changeset
706 Sizes.clear();
anatofuz
parents:
diff changeset
707 break;
anatofuz
parents:
diff changeset
708 }
anatofuz
parents:
diff changeset
709
anatofuz
parents:
diff changeset
710 Subscripts.push_back(Expr);
anatofuz
parents:
diff changeset
711 if (!(DroppedFirstDim && i == 2))
anatofuz
parents:
diff changeset
712 Sizes.push_back(ArrayTy->getNumElements());
anatofuz
parents:
diff changeset
713
anatofuz
parents:
diff changeset
714 Ty = ArrayTy->getElementType();
anatofuz
parents:
diff changeset
715 }
anatofuz
parents:
diff changeset
716
anatofuz
parents:
diff changeset
717 return std::make_tuple(Subscripts, Sizes);
anatofuz
parents:
diff changeset
718 }
anatofuz
parents:
diff changeset
719
anatofuz
parents:
diff changeset
720 llvm::Loop *polly::getFirstNonBoxedLoopFor(llvm::Loop *L, llvm::LoopInfo &LI,
anatofuz
parents:
diff changeset
721 const BoxedLoopsSetTy &BoxedLoops) {
anatofuz
parents:
diff changeset
722 while (BoxedLoops.count(L))
anatofuz
parents:
diff changeset
723 L = L->getParentLoop();
anatofuz
parents:
diff changeset
724 return L;
anatofuz
parents:
diff changeset
725 }
anatofuz
parents:
diff changeset
726
anatofuz
parents:
diff changeset
727 llvm::Loop *polly::getFirstNonBoxedLoopFor(llvm::BasicBlock *BB,
anatofuz
parents:
diff changeset
728 llvm::LoopInfo &LI,
anatofuz
parents:
diff changeset
729 const BoxedLoopsSetTy &BoxedLoops) {
anatofuz
parents:
diff changeset
730 Loop *L = LI.getLoopFor(BB);
anatofuz
parents:
diff changeset
731 return getFirstNonBoxedLoopFor(L, LI, BoxedLoops);
anatofuz
parents:
diff changeset
732 }
anatofuz
parents:
diff changeset
733
anatofuz
parents:
diff changeset
734 bool polly::isDebugCall(Instruction *Inst) {
anatofuz
parents:
diff changeset
735 auto *CI = dyn_cast<CallInst>(Inst);
anatofuz
parents:
diff changeset
736 if (!CI)
anatofuz
parents:
diff changeset
737 return false;
anatofuz
parents:
diff changeset
738
anatofuz
parents:
diff changeset
739 Function *CF = CI->getCalledFunction();
anatofuz
parents:
diff changeset
740 if (!CF)
anatofuz
parents:
diff changeset
741 return false;
anatofuz
parents:
diff changeset
742
anatofuz
parents:
diff changeset
743 return std::find(DebugFunctions.begin(), DebugFunctions.end(),
anatofuz
parents:
diff changeset
744 CF->getName()) != DebugFunctions.end();
anatofuz
parents:
diff changeset
745 }
anatofuz
parents:
diff changeset
746
anatofuz
parents:
diff changeset
747 static bool hasDebugCall(BasicBlock *BB) {
anatofuz
parents:
diff changeset
748 for (Instruction &Inst : *BB) {
anatofuz
parents:
diff changeset
749 if (isDebugCall(&Inst))
anatofuz
parents:
diff changeset
750 return true;
anatofuz
parents:
diff changeset
751 }
anatofuz
parents:
diff changeset
752 return false;
anatofuz
parents:
diff changeset
753 }
anatofuz
parents:
diff changeset
754
anatofuz
parents:
diff changeset
755 bool polly::hasDebugCall(ScopStmt *Stmt) {
anatofuz
parents:
diff changeset
756 // Quick skip if no debug functions have been defined.
anatofuz
parents:
diff changeset
757 if (DebugFunctions.empty())
anatofuz
parents:
diff changeset
758 return false;
anatofuz
parents:
diff changeset
759
anatofuz
parents:
diff changeset
760 if (!Stmt)
anatofuz
parents:
diff changeset
761 return false;
anatofuz
parents:
diff changeset
762
anatofuz
parents:
diff changeset
763 for (Instruction *Inst : Stmt->getInstructions())
anatofuz
parents:
diff changeset
764 if (isDebugCall(Inst))
anatofuz
parents:
diff changeset
765 return true;
anatofuz
parents:
diff changeset
766
anatofuz
parents:
diff changeset
767 if (Stmt->isRegionStmt()) {
anatofuz
parents:
diff changeset
768 for (BasicBlock *RBB : Stmt->getRegion()->blocks())
anatofuz
parents:
diff changeset
769 if (RBB != Stmt->getEntryBlock() && ::hasDebugCall(RBB))
anatofuz
parents:
diff changeset
770 return true;
anatofuz
parents:
diff changeset
771 }
anatofuz
parents:
diff changeset
772
anatofuz
parents:
diff changeset
773 return false;
anatofuz
parents:
diff changeset
774 }