blob: 5c88065f6b6225b7c8a2da0347d6b8af579e0d5b [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,
67};
68
69/// Implementation of operand tree forwarding for a specific SCoP.
70///
71/// For a statement that requires a scalar value (through a value read
72/// MemoryAccess), see if its operand can be moved into the statement. If so,
73/// the MemoryAccess is removed and the all the operand tree instructions are
74/// moved into the statement. All original instructions are left in the source
75/// statements. The simplification pass can clean these up.
76class ForwardOpTreeImpl {
77private:
78 /// The SCoP we are currently processing.
79 Scop *S;
80
81 /// LoopInfo is required for VirtualUse.
82 LoopInfo *LI;
83
84 /// How many instructions have been copied to other statements.
85 int NumInstructionsCopied = 0;
86
Michael Kruse07e8c362017-07-24 12:43:27 +000087 /// How many read-only accesses have been copied.
88 int NumReadOnlyCopied = 0;
89
Michael Krusea6b2de32017-07-22 14:02:47 +000090 /// How many operand trees have been forwarded.
91 int NumForwardedTrees = 0;
92
93 /// Number of statements with at least one forwarded operand tree.
94 int NumModifiedStmts = 0;
95
96 /// Whether we carried out at least one change to the SCoP.
97 bool Modified = false;
98
99 void printStatistics(raw_ostream &OS, int Indent = 0) {
100 OS.indent(Indent) << "Statistics {\n";
101 OS.indent(Indent + 4) << "Instructions copied: " << NumInstructionsCopied
102 << '\n';
Michael Kruse07e8c362017-07-24 12:43:27 +0000103 OS.indent(Indent + 4) << "Read-only accesses copied: " << NumReadOnlyCopied
104 << '\n';
Michael Krusea6b2de32017-07-22 14:02:47 +0000105 OS.indent(Indent + 4) << "Operand trees forwarded: " << NumForwardedTrees
106 << '\n';
107 OS.indent(Indent + 4) << "Statements with forwarded operand trees: "
108 << NumModifiedStmts << '\n';
109 OS.indent(Indent) << "}\n";
110 }
111
112 void printStatements(llvm::raw_ostream &OS, int Indent = 0) const {
113 OS.indent(Indent) << "After statements {\n";
114 for (auto &Stmt : *S) {
115 OS.indent(Indent + 4) << Stmt.getBaseName() << "\n";
116 for (auto *MA : Stmt)
117 MA->print(OS);
118
119 OS.indent(Indent + 12);
120 Stmt.printInstructions(OS);
121 }
122 OS.indent(Indent) << "}\n";
123 }
124
125 /// Determines whether an operand tree can be forwarded or carries out a
126 /// forwarding, depending on the @p DoIt flag.
127 ///
128 /// @param TargetStmt The statement the operand tree will be copied to.
129 /// @param UseVal The value (usually an instruction) which is root of an
130 /// operand tree.
131 /// @param UseStmt The statement that uses @p UseVal.
132 /// @param UseLoop The loop @p UseVal is used in.
133 /// @param DoIt If false, only determine whether an operand tree can be
134 /// forwarded. If true, carry out the forwarding. Do not use
135 /// DoIt==true if an operand tree is not known to be
136 /// forwardable.
137 ///
Michael Kruse5b8a9092017-07-24 12:39:46 +0000138 /// @return If DoIt==false, return whether the operand tree can be forwarded.
139 /// If DoIt==true, return FD_DidForward.
Michael Krusefd350892017-08-01 22:15:04 +0000140 ForwardingDecision forwardTree(ScopStmt *TargetStmt, Value *UseVal,
141 ScopStmt *UseStmt, Loop *UseLoop, bool DoIt) {
Michael Krusea6b2de32017-07-22 14:02:47 +0000142 VirtualUse VUse = VirtualUse::create(UseStmt, UseLoop, UseVal, true);
143 switch (VUse.getKind()) {
144 case VirtualUse::Constant:
145 case VirtualUse::Block:
Michael Krusee5f47062017-07-22 14:30:02 +0000146 case VirtualUse::Hoisted:
Michael Krusea6b2de32017-07-22 14:02:47 +0000147 // These can be used anywhere without special considerations.
148 if (DoIt)
149 return FD_DidForward;
Michael Kruse67752072017-07-24 15:33:58 +0000150 return FD_CanForwardLeaf;
Michael Krusea6b2de32017-07-22 14:02:47 +0000151
Michael Kruse9f6e41c2017-07-31 19:46:21 +0000152 case VirtualUse::Synthesizable: {
153 // ScopExpander will take care for of generating the code at the new
154 // location.
155 if (DoIt)
156 return FD_DidForward;
157
158 // Check if the value is synthesizable at the new location as well. This
159 // might be possible when leaving a loop for which ScalarEvolution is
160 // unable to derive the exit value for.
161 // TODO: If there is a LCSSA PHI at the loop exit, use that one.
162 // If the SCEV contains a SCEVAddRecExpr, we currently depend on that we
163 // do not forward past its loop header. This would require us to use a
164 // previous loop induction variable instead the current one. We currently
165 // do not allow forwarding PHI nodes, thus this should never occur (the
166 // only exception where no phi is necessary being an unreachable loop
167 // without edge from the outside).
168 VirtualUse TargetUse = VirtualUse::create(
169 S, TargetStmt, TargetStmt->getSurroundingLoop(), UseVal, true);
170 if (TargetUse.getKind() == VirtualUse::Synthesizable)
171 return FD_CanForwardLeaf;
172
173 DEBUG(dbgs() << " Synthesizable would not be synthesizable anymore: "
174 << *UseVal << "\n");
Michael Krusea6b2de32017-07-22 14:02:47 +0000175 return FD_CannotForward;
Michael Kruse9f6e41c2017-07-31 19:46:21 +0000176 }
Michael Krusea6b2de32017-07-22 14:02:47 +0000177
Michael Krusea6b2de32017-07-22 14:02:47 +0000178 case VirtualUse::ReadOnly:
Michael Krused85e3452017-07-24 15:33:53 +0000179 // Note that we cannot return FD_CanForwardTree here. With a operand tree
180 // depth of 0, UseVal is the use in TargetStmt that we try to replace.
181 // With -polly-analyze-read-only-scalars=true we would ensure the
182 // existence of a MemoryAccess (which already exists for a leaf) and be
183 // removed again by tryForwardTree because it's goal is to remove this
184 // scalar MemoryAccess. It interprets FD_CanForwardTree as the permission
185 // to do so.
Michael Kruse07e8c362017-07-24 12:43:27 +0000186 if (!DoIt)
Michael Kruse67752072017-07-24 15:33:58 +0000187 return FD_CanForwardLeaf;
Michael Kruse07e8c362017-07-24 12:43:27 +0000188
189 // If we model read-only scalars, we need to create a MemoryAccess for it.
190 if (ModelReadOnlyScalars)
191 TargetStmt->ensureValueRead(UseVal);
192
193 NumReadOnlyCopied++;
194 TotalReadOnlyCopied++;
195 return FD_DidForward;
Michael Krusea6b2de32017-07-22 14:02:47 +0000196
197 case VirtualUse::Intra:
198 case VirtualUse::Inter:
199 auto Inst = cast<Instruction>(UseVal);
200
Michael Kruse9f6e41c2017-07-31 19:46:21 +0000201 // PHIs, unless synthesizable, are not yet supported.
202 if (isa<PHINode>(Inst)) {
203 DEBUG(dbgs() << " Cannot forward PHI: " << *UseVal << "\n");
204 return FD_CannotForward;
205 }
206
Michael Krusea6b2de32017-07-22 14:02:47 +0000207 // Compatible instructions must satisfy the following conditions:
208 // 1. Idempotent (instruction will be copied, not moved; although its
Michael Kruse54071122017-07-24 15:34:03 +0000209 // original instance might be removed by simplification)
Michael Krusea6b2de32017-07-22 14:02:47 +0000210 // 2. Not access memory (There might be memory writes between)
211 // 3. Not cause undefined behaviour (we might copy to a location when the
Michael Kruse54071122017-07-24 15:34:03 +0000212 // original instruction was no executed; this is currently not possible
213 // because we do not forward PHINodes)
Michael Krusea6b2de32017-07-22 14:02:47 +0000214 // 4. Not leak memory if executed multiple times (I am looking at you,
Michael Kruse54071122017-07-24 15:34:03 +0000215 // malloc!)
Michael Krusea6b2de32017-07-22 14:02:47 +0000216 //
217 // Instruction::mayHaveSideEffects is not sufficient because it considers
218 // malloc to not have side-effects. llvm::isSafeToSpeculativelyExecute is
219 // not sufficient because it allows memory accesses.
220 if (mayBeMemoryDependent(*Inst)) {
221 DEBUG(dbgs() << " Cannot forward side-effect instruction: " << *Inst
222 << "\n");
223 return FD_CannotForward;
224 }
225
226 Loop *DefLoop = LI->getLoopFor(Inst->getParent());
227 ScopStmt *DefStmt = S->getStmtFor(Inst);
228 assert(DefStmt && "Value must be defined somewhere");
229
230 if (DoIt) {
231 // To ensure the right order, prepend this instruction before its
232 // operands. This ensures that its operands are inserted before the
233 // instruction using them.
234 // TODO: The operand tree is not really a tree, but a DAG. We should be
235 // able to handle DAGs without duplication.
Michael Kruse25a68812017-07-24 12:39:41 +0000236 TargetStmt->prependInstruction(Inst);
Michael Krusea6b2de32017-07-22 14:02:47 +0000237 NumInstructionsCopied++;
238 TotalInstructionsCopied++;
239 }
240
241 for (Value *OpVal : Inst->operand_values()) {
242 ForwardingDecision OpDecision =
Michael Krusefd350892017-08-01 22:15:04 +0000243 forwardTree(TargetStmt, OpVal, DefStmt, DefLoop, DoIt);
Michael Krusea6b2de32017-07-22 14:02:47 +0000244 switch (OpDecision) {
245 case FD_CannotForward:
246 assert(!DoIt);
247 return FD_CannotForward;
248
Michael Kruse67752072017-07-24 15:33:58 +0000249 case FD_CanForwardLeaf:
Michael Kruse07e8c362017-07-24 12:43:27 +0000250 case FD_CanForwardTree:
Michael Krusea6b2de32017-07-22 14:02:47 +0000251 assert(!DoIt);
252 break;
253
254 case FD_DidForward:
255 assert(DoIt);
256 break;
257 }
258 }
259
260 if (DoIt)
261 return FD_DidForward;
Michael Kruse07e8c362017-07-24 12:43:27 +0000262 return FD_CanForwardTree;
Michael Krusea6b2de32017-07-22 14:02:47 +0000263 }
264
265 llvm_unreachable("Case unhandled");
266 }
267
268 /// Try to forward an operand tree rooted in @p RA.
269 bool tryForwardTree(MemoryAccess *RA) {
270 assert(RA->isLatestScalarKind());
271 DEBUG(dbgs() << "Trying to forward operand tree " << RA << "...\n");
272
273 ScopStmt *Stmt = RA->getStatement();
274 Loop *InLoop = Stmt->getSurroundingLoop();
275
276 ForwardingDecision Assessment =
Michael Krusefd350892017-08-01 22:15:04 +0000277 forwardTree(Stmt, RA->getAccessValue(), Stmt, InLoop, false);
Michael Krusea6b2de32017-07-22 14:02:47 +0000278 assert(Assessment != FD_DidForward);
Michael Kruse07e8c362017-07-24 12:43:27 +0000279 if (Assessment != FD_CanForwardTree)
Michael Krusea6b2de32017-07-22 14:02:47 +0000280 return false;
281
Michael Krusefd350892017-08-01 22:15:04 +0000282 ForwardingDecision Execution =
283 forwardTree(Stmt, RA->getAccessValue(), Stmt, InLoop, true);
284 assert(Execution == FD_DidForward &&
285 "A previous positive assessment must also be executable");
286 (void)Execution;
Michael Krusea6b2de32017-07-22 14:02:47 +0000287
288 Stmt->removeSingleMemoryAccess(RA);
289 return true;
290 }
291
292public:
293 ForwardOpTreeImpl(Scop *S, LoopInfo *LI) : S(S), LI(LI) {}
294
295 /// Return which SCoP this instance is processing.
296 Scop *getScop() const { return S; }
297
298 /// Run the algorithm: Use value read accesses as operand tree roots and try
299 /// to forward them into the statement.
300 bool forwardOperandTrees() {
301 for (ScopStmt &Stmt : *S) {
302 // Currently we cannot modify the instruction list of region statements.
303 if (!Stmt.isBlockStmt())
304 continue;
305
306 bool StmtModified = false;
307
308 // Because we are modifying the MemoryAccess list, collect them first to
309 // avoid iterator invalidation.
310 SmallVector<MemoryAccess *, 16> Accs;
311 for (MemoryAccess *RA : Stmt) {
312 if (!RA->isRead())
313 continue;
314 if (!RA->isLatestScalarKind())
315 continue;
316
317 Accs.push_back(RA);
318 }
319
320 for (MemoryAccess *RA : Accs) {
321 if (tryForwardTree(RA)) {
322 Modified = true;
323 StmtModified = true;
324 NumForwardedTrees++;
325 TotalForwardedTrees++;
326 }
327 }
328
329 if (StmtModified) {
330 NumModifiedStmts++;
331 TotalModifiedStmts++;
332 }
333 }
334
335 if (Modified)
336 ScopsModified++;
337 return Modified;
338 }
339
340 /// Print the pass result, performed transformations and the SCoP after the
341 /// transformation.
342 void print(llvm::raw_ostream &OS, int Indent = 0) {
343 printStatistics(OS, Indent);
344
345 if (!Modified) {
346 // This line can easily be checked in regression tests.
347 OS << "ForwardOpTree executed, but did not modify anything\n";
348 return;
349 }
350
351 printStatements(OS, Indent);
352 }
353};
354
355/// Pass that redirects scalar reads to array elements that are known to contain
356/// the same value.
357///
358/// This reduces the number of scalar accesses and therefore potentially
359/// increases the freedom of the scheduler. In the ideal case, all reads of a
360/// scalar definition are redirected (We currently do not care about removing
361/// the write in this case). This is also useful for the main DeLICM pass as
362/// there are less scalars to be mapped.
363class ForwardOpTree : public ScopPass {
364private:
365 ForwardOpTree(const ForwardOpTree &) = delete;
366 const ForwardOpTree &operator=(const ForwardOpTree &) = delete;
367
368 /// The pass implementation, also holding per-scop data.
369 std::unique_ptr<ForwardOpTreeImpl> Impl;
370
371public:
372 static char ID;
373
374 explicit ForwardOpTree() : ScopPass(ID) {}
375
376 virtual void getAnalysisUsage(AnalysisUsage &AU) const override {
377 AU.addRequiredTransitive<ScopInfoRegionPass>();
378 AU.addRequired<LoopInfoWrapperPass>();
379 AU.setPreservesAll();
380 }
381
382 virtual bool runOnScop(Scop &S) override {
383 // Free resources for previous SCoP's computation, if not yet done.
384 releaseMemory();
385
386 LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
387 Impl = make_unique<ForwardOpTreeImpl>(&S, &LI);
388
389 DEBUG(dbgs() << "Forwarding operand trees...\n");
390 Impl->forwardOperandTrees();
391
392 DEBUG(dbgs() << "\nFinal Scop:\n");
393 DEBUG(dbgs() << S);
394
395 return false;
396 }
397
398 virtual void printScop(raw_ostream &OS, Scop &S) const override {
399 if (!Impl)
400 return;
401
402 assert(Impl->getScop() == &S);
403 Impl->print(OS);
404 }
405
406 virtual void releaseMemory() override { Impl.reset(); }
407
408}; // class ForwardOpTree
409
410char ForwardOpTree::ID;
411} // anonymous namespace
412
413ScopPass *polly::createForwardOpTreePass() { return new ForwardOpTree(); }
414
415INITIALIZE_PASS_BEGIN(ForwardOpTree, "polly-optree",
416 "Polly - Forward operand tree", false, false)
417INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
418INITIALIZE_PASS_END(ForwardOpTree, "polly-optree",
419 "Polly - Forward operand tree", false, false)