blob: 507478f6c608ecfbf3b6785c13fc41b252ff9b3c [file] [log] [blame]
Michael Krusea6b2de32017-07-22 14:02:47 +00001//===------ ForwardOpTree.h -------------------------------------*- 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// Move instructions between statements.
11//
12//===----------------------------------------------------------------------===//
13
14#include "polly/ForwardOpTree.h"
15
Michael Kruse07e8c362017-07-24 12:43:27 +000016#include "polly/ScopBuilder.h"
Michael Krusea6b2de32017-07-22 14:02:47 +000017#include "polly/ScopInfo.h"
18#include "polly/ScopPass.h"
19#include "polly/Support/GICHelper.h"
20#include "polly/Support/VirtualInstruction.h"
21#include "llvm/Analysis/ValueTracking.h"
22
23#define DEBUG_TYPE "polly-delicm"
24
25using namespace polly;
26using namespace llvm;
27
28STATISTIC(TotalInstructionsCopied, "Number of copied instructions");
Michael Kruse07e8c362017-07-24 12:43:27 +000029STATISTIC(TotalReadOnlyCopied, "Number of copied read-only accesses");
Michael Krusea6b2de32017-07-22 14:02:47 +000030STATISTIC(TotalForwardedTrees, "Number of forwarded operand trees");
31STATISTIC(TotalModifiedStmts,
32 "Number of statements with at least one forwarded tree");
33
34STATISTIC(ScopsModified, "Number of SCoPs with at least one forwarded tree");
35
36namespace {
37
38/// The state of whether an operand tree was/can be forwarded.
Michael Krused85e3452017-07-24 15:33:53 +000039///
40/// The items apply to an instructions and its operand tree with the instruction
41/// as the root element. If the value in question is not an instruction in the
42/// SCoP, it can be a leaf of an instruction's operand tree.
Michael Krusea6b2de32017-07-22 14:02:47 +000043enum ForwardingDecision {
Michael Krused85e3452017-07-24 15:33:53 +000044 /// The root instruction or value cannot be forwarded at all.
Michael Krusea6b2de32017-07-22 14:02:47 +000045 FD_CannotForward,
Michael Krused85e3452017-07-24 15:33:53 +000046
47 /// The root instruction or value can be forwarded as a leaf of a larger
48 /// operand tree.
49 /// It does not make sense to move the value itself, it would just replace it
50 /// by a use of itself. For instance, a constant "5" used in a statement can
51 /// be forwarded, but it would just replace it by the same constant "5".
52 /// However, it makes sense to move as an operand of
53 ///
54 /// %add = add 5, 5
55 ///
56 /// where "5" is moved as part of a larger operand tree. "5" would be placed
57 /// (disregarding for a moment that literal constants don't have a location
58 /// and can be used anywhere) into the same statement as %add would.
Michael Kruse67752072017-07-24 15:33:58 +000059 FD_CanForwardLeaf,
Michael Krused85e3452017-07-24 15:33:53 +000060
61 /// The root instruction can be forwarded in a non-trivial way. This requires
62 /// the operand tree root to be an instruction in some statement.
Michael Kruse07e8c362017-07-24 12:43:27 +000063 FD_CanForwardTree,
Michael Krused85e3452017-07-24 15:33:53 +000064
65 /// Used to indicate that a forwarding has be carried out successfully.
Michael Krusea6b2de32017-07-22 14:02:47 +000066 FD_DidForward,
Michael Krusea9a70862017-08-04 12:28:42 +000067
68 /// A forwarding method cannot be applied to the operand tree.
69 /// The difference to FD_CannotForward is that there might be other methods
70 /// that can handle it.
71 /// The conditions that make an operand tree applicable must be checked even
72 /// with DoIt==true because a method following the one that returned
73 /// FD_NotApplicable might have returned FD_CanForwardTree.
74 FD_NotApplicable
Michael Krusea6b2de32017-07-22 14:02:47 +000075};
76
77/// Implementation of operand tree forwarding for a specific SCoP.
78///
79/// For a statement that requires a scalar value (through a value read
80/// MemoryAccess), see if its operand can be moved into the statement. If so,
81/// the MemoryAccess is removed and the all the operand tree instructions are
82/// moved into the statement. All original instructions are left in the source
83/// statements. The simplification pass can clean these up.
84class ForwardOpTreeImpl {
85private:
86 /// The SCoP we are currently processing.
87 Scop *S;
88
89 /// LoopInfo is required for VirtualUse.
90 LoopInfo *LI;
91
92 /// How many instructions have been copied to other statements.
93 int NumInstructionsCopied = 0;
94
Michael Kruse07e8c362017-07-24 12:43:27 +000095 /// How many read-only accesses have been copied.
96 int NumReadOnlyCopied = 0;
97
Michael Krusea6b2de32017-07-22 14:02:47 +000098 /// How many operand trees have been forwarded.
99 int NumForwardedTrees = 0;
100
101 /// Number of statements with at least one forwarded operand tree.
102 int NumModifiedStmts = 0;
103
104 /// Whether we carried out at least one change to the SCoP.
105 bool Modified = false;
106
107 void printStatistics(raw_ostream &OS, int Indent = 0) {
108 OS.indent(Indent) << "Statistics {\n";
109 OS.indent(Indent + 4) << "Instructions copied: " << NumInstructionsCopied
110 << '\n';
Michael Kruse07e8c362017-07-24 12:43:27 +0000111 OS.indent(Indent + 4) << "Read-only accesses copied: " << NumReadOnlyCopied
112 << '\n';
Michael Krusea6b2de32017-07-22 14:02:47 +0000113 OS.indent(Indent + 4) << "Operand trees forwarded: " << NumForwardedTrees
114 << '\n';
115 OS.indent(Indent + 4) << "Statements with forwarded operand trees: "
116 << NumModifiedStmts << '\n';
117 OS.indent(Indent) << "}\n";
118 }
119
120 void printStatements(llvm::raw_ostream &OS, int Indent = 0) const {
121 OS.indent(Indent) << "After statements {\n";
122 for (auto &Stmt : *S) {
123 OS.indent(Indent + 4) << Stmt.getBaseName() << "\n";
124 for (auto *MA : Stmt)
125 MA->print(OS);
126
127 OS.indent(Indent + 12);
128 Stmt.printInstructions(OS);
129 }
130 OS.indent(Indent) << "}\n";
131 }
132
Michael Krusea9a70862017-08-04 12:28:42 +0000133 /// Forwards a speculatively executable instruction.
134 ///
135 /// If the instruction itself cannot be executed speculatively, returns
136 /// FD_NotApplicable.
137 ///
138 /// The parameters the same as for
139 /// @see forwardTree()
140 ForwardingDecision forwardSpeculatable(ScopStmt *TargetStmt,
141 Instruction *UseInst,
142 ScopStmt *UseStmt, Loop *UseLoop,
143 bool DoIt) {
144 // PHIs, unless synthesizable, are not yet supported.
145 if (isa<PHINode>(UseInst))
146 return FD_NotApplicable;
147
148 // Compatible instructions must satisfy the following conditions:
149 // 1. Idempotent (instruction will be copied, not moved; although its
150 // original instance might be removed by simplification)
151 // 2. Not access memory (There might be memory writes between)
152 // 3. Not cause undefined behaviour (we might copy to a location when the
153 // original instruction was no executed; this is currently not possible
154 // because we do not forward PHINodes)
155 // 4. Not leak memory if executed multiple times (i.e. malloc)
156 //
157 // Instruction::mayHaveSideEffects is not sufficient because it considers
158 // malloc to not have side-effects. llvm::isSafeToSpeculativelyExecute is
159 // not sufficient because it allows memory accesses.
160 if (mayBeMemoryDependent(*UseInst))
161 return FD_NotApplicable;
162
163 Loop *DefLoop = LI->getLoopFor(UseInst->getParent());
164 ScopStmt *DefStmt = S->getStmtFor(UseInst);
165 assert(DefStmt && "Value must be defined somewhere");
166
167 if (DoIt) {
168 // To ensure the right order, prepend this instruction before its
169 // operands. This ensures that its operands are inserted before the
170 // instruction using them.
171 // TODO: The operand tree is not really a tree, but a DAG. We should be
172 // able to handle DAGs without duplication.
173 TargetStmt->prependInstruction(UseInst);
174 NumInstructionsCopied++;
175 TotalInstructionsCopied++;
176 }
177
178 for (Value *OpVal : UseInst->operand_values()) {
179 ForwardingDecision OpDecision =
180 forwardTree(TargetStmt, OpVal, DefStmt, DefLoop, DoIt);
181 switch (OpDecision) {
182 case FD_CannotForward:
183 assert(!DoIt);
184 return FD_CannotForward;
185
186 case FD_CanForwardLeaf:
187 case FD_CanForwardTree:
188 assert(!DoIt);
189 break;
190
191 case FD_DidForward:
192 assert(DoIt);
193 break;
194
195 case FD_NotApplicable:
196 llvm_unreachable("forwardTree should never return FD_NotApplicable");
197 }
198 }
199
200 if (DoIt)
201 return FD_DidForward;
202 return FD_CanForwardTree;
203 }
204
Michael Krusea6b2de32017-07-22 14:02:47 +0000205 /// Determines whether an operand tree can be forwarded or carries out a
206 /// forwarding, depending on the @p DoIt flag.
207 ///
208 /// @param TargetStmt The statement the operand tree will be copied to.
209 /// @param UseVal The value (usually an instruction) which is root of an
210 /// operand tree.
211 /// @param UseStmt The statement that uses @p UseVal.
212 /// @param UseLoop The loop @p UseVal is used in.
213 /// @param DoIt If false, only determine whether an operand tree can be
214 /// forwarded. If true, carry out the forwarding. Do not use
215 /// DoIt==true if an operand tree is not known to be
216 /// forwardable.
217 ///
Michael Kruse5b8a9092017-07-24 12:39:46 +0000218 /// @return If DoIt==false, return whether the operand tree can be forwarded.
219 /// If DoIt==true, return FD_DidForward.
Michael Krusefd350892017-08-01 22:15:04 +0000220 ForwardingDecision forwardTree(ScopStmt *TargetStmt, Value *UseVal,
221 ScopStmt *UseStmt, Loop *UseLoop, bool DoIt) {
Michael Krusea6b2de32017-07-22 14:02:47 +0000222 VirtualUse VUse = VirtualUse::create(UseStmt, UseLoop, UseVal, true);
223 switch (VUse.getKind()) {
224 case VirtualUse::Constant:
225 case VirtualUse::Block:
Michael Krusee5f47062017-07-22 14:30:02 +0000226 case VirtualUse::Hoisted:
Michael Krusea6b2de32017-07-22 14:02:47 +0000227 // These can be used anywhere without special considerations.
228 if (DoIt)
229 return FD_DidForward;
Michael Kruse67752072017-07-24 15:33:58 +0000230 return FD_CanForwardLeaf;
Michael Krusea6b2de32017-07-22 14:02:47 +0000231
Michael Kruse9f6e41c2017-07-31 19:46:21 +0000232 case VirtualUse::Synthesizable: {
233 // ScopExpander will take care for of generating the code at the new
234 // location.
235 if (DoIt)
236 return FD_DidForward;
237
238 // Check if the value is synthesizable at the new location as well. This
239 // might be possible when leaving a loop for which ScalarEvolution is
240 // unable to derive the exit value for.
241 // TODO: If there is a LCSSA PHI at the loop exit, use that one.
242 // If the SCEV contains a SCEVAddRecExpr, we currently depend on that we
243 // do not forward past its loop header. This would require us to use a
244 // previous loop induction variable instead the current one. We currently
245 // do not allow forwarding PHI nodes, thus this should never occur (the
246 // only exception where no phi is necessary being an unreachable loop
247 // without edge from the outside).
248 VirtualUse TargetUse = VirtualUse::create(
249 S, TargetStmt, TargetStmt->getSurroundingLoop(), UseVal, true);
250 if (TargetUse.getKind() == VirtualUse::Synthesizable)
251 return FD_CanForwardLeaf;
252
253 DEBUG(dbgs() << " Synthesizable would not be synthesizable anymore: "
254 << *UseVal << "\n");
Michael Krusea6b2de32017-07-22 14:02:47 +0000255 return FD_CannotForward;
Michael Kruse9f6e41c2017-07-31 19:46:21 +0000256 }
Michael Krusea6b2de32017-07-22 14:02:47 +0000257
Michael Krusea6b2de32017-07-22 14:02:47 +0000258 case VirtualUse::ReadOnly:
Michael Krused85e3452017-07-24 15:33:53 +0000259 // Note that we cannot return FD_CanForwardTree here. With a operand tree
260 // depth of 0, UseVal is the use in TargetStmt that we try to replace.
261 // With -polly-analyze-read-only-scalars=true we would ensure the
262 // existence of a MemoryAccess (which already exists for a leaf) and be
263 // removed again by tryForwardTree because it's goal is to remove this
264 // scalar MemoryAccess. It interprets FD_CanForwardTree as the permission
265 // to do so.
Michael Kruse07e8c362017-07-24 12:43:27 +0000266 if (!DoIt)
Michael Kruse67752072017-07-24 15:33:58 +0000267 return FD_CanForwardLeaf;
Michael Kruse07e8c362017-07-24 12:43:27 +0000268
269 // If we model read-only scalars, we need to create a MemoryAccess for it.
270 if (ModelReadOnlyScalars)
271 TargetStmt->ensureValueRead(UseVal);
272
273 NumReadOnlyCopied++;
274 TotalReadOnlyCopied++;
275 return FD_DidForward;
Michael Krusea6b2de32017-07-22 14:02:47 +0000276
277 case VirtualUse::Intra:
278 case VirtualUse::Inter:
279 auto Inst = cast<Instruction>(UseVal);
280
Michael Krusea9a70862017-08-04 12:28:42 +0000281 ForwardingDecision SpeculativeResult =
282 forwardSpeculatable(TargetStmt, Inst, UseStmt, UseLoop, DoIt);
283 if (SpeculativeResult != FD_NotApplicable)
284 return SpeculativeResult;
Michael Kruse9f6e41c2017-07-31 19:46:21 +0000285
Michael Krusea9a70862017-08-04 12:28:42 +0000286 // When no method is found to forward the operand tree, we effectively
287 // cannot handle it.
288 DEBUG(dbgs() << " Cannot forward instruction: " << *Inst << "\n");
289 return FD_CannotForward;
Michael Krusea6b2de32017-07-22 14:02:47 +0000290 }
291
292 llvm_unreachable("Case unhandled");
293 }
294
295 /// Try to forward an operand tree rooted in @p RA.
296 bool tryForwardTree(MemoryAccess *RA) {
297 assert(RA->isLatestScalarKind());
298 DEBUG(dbgs() << "Trying to forward operand tree " << RA << "...\n");
299
300 ScopStmt *Stmt = RA->getStatement();
301 Loop *InLoop = Stmt->getSurroundingLoop();
302
303 ForwardingDecision Assessment =
Michael Krusefd350892017-08-01 22:15:04 +0000304 forwardTree(Stmt, RA->getAccessValue(), Stmt, InLoop, false);
Michael Krusea6b2de32017-07-22 14:02:47 +0000305 assert(Assessment != FD_DidForward);
Michael Kruse07e8c362017-07-24 12:43:27 +0000306 if (Assessment != FD_CanForwardTree)
Michael Krusea6b2de32017-07-22 14:02:47 +0000307 return false;
308
Michael Krusefd350892017-08-01 22:15:04 +0000309 ForwardingDecision Execution =
310 forwardTree(Stmt, RA->getAccessValue(), Stmt, InLoop, true);
311 assert(Execution == FD_DidForward &&
312 "A previous positive assessment must also be executable");
313 (void)Execution;
Michael Krusea6b2de32017-07-22 14:02:47 +0000314
315 Stmt->removeSingleMemoryAccess(RA);
316 return true;
317 }
318
319public:
320 ForwardOpTreeImpl(Scop *S, LoopInfo *LI) : S(S), LI(LI) {}
321
322 /// Return which SCoP this instance is processing.
323 Scop *getScop() const { return S; }
324
325 /// Run the algorithm: Use value read accesses as operand tree roots and try
326 /// to forward them into the statement.
327 bool forwardOperandTrees() {
328 for (ScopStmt &Stmt : *S) {
329 // Currently we cannot modify the instruction list of region statements.
330 if (!Stmt.isBlockStmt())
331 continue;
332
333 bool StmtModified = false;
334
335 // Because we are modifying the MemoryAccess list, collect them first to
336 // avoid iterator invalidation.
337 SmallVector<MemoryAccess *, 16> Accs;
338 for (MemoryAccess *RA : Stmt) {
339 if (!RA->isRead())
340 continue;
341 if (!RA->isLatestScalarKind())
342 continue;
343
344 Accs.push_back(RA);
345 }
346
347 for (MemoryAccess *RA : Accs) {
348 if (tryForwardTree(RA)) {
349 Modified = true;
350 StmtModified = true;
351 NumForwardedTrees++;
352 TotalForwardedTrees++;
353 }
354 }
355
356 if (StmtModified) {
357 NumModifiedStmts++;
358 TotalModifiedStmts++;
359 }
360 }
361
362 if (Modified)
363 ScopsModified++;
364 return Modified;
365 }
366
367 /// Print the pass result, performed transformations and the SCoP after the
368 /// transformation.
369 void print(llvm::raw_ostream &OS, int Indent = 0) {
370 printStatistics(OS, Indent);
371
372 if (!Modified) {
373 // This line can easily be checked in regression tests.
374 OS << "ForwardOpTree executed, but did not modify anything\n";
375 return;
376 }
377
378 printStatements(OS, Indent);
379 }
380};
381
382/// Pass that redirects scalar reads to array elements that are known to contain
383/// the same value.
384///
385/// This reduces the number of scalar accesses and therefore potentially
386/// increases the freedom of the scheduler. In the ideal case, all reads of a
387/// scalar definition are redirected (We currently do not care about removing
388/// the write in this case). This is also useful for the main DeLICM pass as
389/// there are less scalars to be mapped.
390class ForwardOpTree : public ScopPass {
391private:
392 ForwardOpTree(const ForwardOpTree &) = delete;
393 const ForwardOpTree &operator=(const ForwardOpTree &) = delete;
394
395 /// The pass implementation, also holding per-scop data.
396 std::unique_ptr<ForwardOpTreeImpl> Impl;
397
398public:
399 static char ID;
400
401 explicit ForwardOpTree() : ScopPass(ID) {}
402
403 virtual void getAnalysisUsage(AnalysisUsage &AU) const override {
404 AU.addRequiredTransitive<ScopInfoRegionPass>();
405 AU.addRequired<LoopInfoWrapperPass>();
406 AU.setPreservesAll();
407 }
408
409 virtual bool runOnScop(Scop &S) override {
410 // Free resources for previous SCoP's computation, if not yet done.
411 releaseMemory();
412
413 LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
414 Impl = make_unique<ForwardOpTreeImpl>(&S, &LI);
415
416 DEBUG(dbgs() << "Forwarding operand trees...\n");
417 Impl->forwardOperandTrees();
418
419 DEBUG(dbgs() << "\nFinal Scop:\n");
420 DEBUG(dbgs() << S);
421
422 return false;
423 }
424
425 virtual void printScop(raw_ostream &OS, Scop &S) const override {
426 if (!Impl)
427 return;
428
429 assert(Impl->getScop() == &S);
430 Impl->print(OS);
431 }
432
433 virtual void releaseMemory() override { Impl.reset(); }
434
435}; // class ForwardOpTree
436
437char ForwardOpTree::ID;
438} // anonymous namespace
439
440ScopPass *polly::createForwardOpTreePass() { return new ForwardOpTree(); }
441
442INITIALIZE_PASS_BEGIN(ForwardOpTree, "polly-optree",
443 "Polly - Forward operand tree", false, false)
444INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
445INITIALIZE_PASS_END(ForwardOpTree, "polly-optree",
446 "Polly - Forward operand tree", false, false)