blob: 852fc18854277fdfcd3e2a0548027e442fa20a4e [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 Krusea6b2de32017-07-22 14:02:47 +0000140 ForwardingDecision canForwardTree(ScopStmt *TargetStmt, Value *UseVal,
141 ScopStmt *UseStmt, Loop *UseLoop,
142 bool DoIt) {
Michael Krusea6b2de32017-07-22 14:02:47 +0000143 VirtualUse VUse = VirtualUse::create(UseStmt, UseLoop, UseVal, true);
144 switch (VUse.getKind()) {
145 case VirtualUse::Constant:
146 case VirtualUse::Block:
Michael Krusee5f47062017-07-22 14:30:02 +0000147 case VirtualUse::Hoisted:
Michael Krusea6b2de32017-07-22 14:02:47 +0000148 // These can be used anywhere without special considerations.
149 if (DoIt)
150 return FD_DidForward;
Michael Kruse67752072017-07-24 15:33:58 +0000151 return FD_CanForwardLeaf;
Michael Krusea6b2de32017-07-22 14:02:47 +0000152
Michael Kruse9f6e41c2017-07-31 19:46:21 +0000153 case VirtualUse::Synthesizable: {
154 // ScopExpander will take care for of generating the code at the new
155 // location.
156 if (DoIt)
157 return FD_DidForward;
158
159 // Check if the value is synthesizable at the new location as well. This
160 // might be possible when leaving a loop for which ScalarEvolution is
161 // unable to derive the exit value for.
162 // TODO: If there is a LCSSA PHI at the loop exit, use that one.
163 // If the SCEV contains a SCEVAddRecExpr, we currently depend on that we
164 // do not forward past its loop header. This would require us to use a
165 // previous loop induction variable instead the current one. We currently
166 // do not allow forwarding PHI nodes, thus this should never occur (the
167 // only exception where no phi is necessary being an unreachable loop
168 // without edge from the outside).
169 VirtualUse TargetUse = VirtualUse::create(
170 S, TargetStmt, TargetStmt->getSurroundingLoop(), UseVal, true);
171 if (TargetUse.getKind() == VirtualUse::Synthesizable)
172 return FD_CanForwardLeaf;
173
174 DEBUG(dbgs() << " Synthesizable would not be synthesizable anymore: "
175 << *UseVal << "\n");
Michael Krusea6b2de32017-07-22 14:02:47 +0000176 return FD_CannotForward;
Michael Kruse9f6e41c2017-07-31 19:46:21 +0000177 }
Michael Krusea6b2de32017-07-22 14:02:47 +0000178
Michael Krusea6b2de32017-07-22 14:02:47 +0000179 case VirtualUse::ReadOnly:
Michael Krused85e3452017-07-24 15:33:53 +0000180 // Note that we cannot return FD_CanForwardTree here. With a operand tree
181 // depth of 0, UseVal is the use in TargetStmt that we try to replace.
182 // With -polly-analyze-read-only-scalars=true we would ensure the
183 // existence of a MemoryAccess (which already exists for a leaf) and be
184 // removed again by tryForwardTree because it's goal is to remove this
185 // scalar MemoryAccess. It interprets FD_CanForwardTree as the permission
186 // to do so.
Michael Kruse07e8c362017-07-24 12:43:27 +0000187 if (!DoIt)
Michael Kruse67752072017-07-24 15:33:58 +0000188 return FD_CanForwardLeaf;
Michael Kruse07e8c362017-07-24 12:43:27 +0000189
190 // If we model read-only scalars, we need to create a MemoryAccess for it.
191 if (ModelReadOnlyScalars)
192 TargetStmt->ensureValueRead(UseVal);
193
194 NumReadOnlyCopied++;
195 TotalReadOnlyCopied++;
196 return FD_DidForward;
Michael Krusea6b2de32017-07-22 14:02:47 +0000197
198 case VirtualUse::Intra:
199 case VirtualUse::Inter:
200 auto Inst = cast<Instruction>(UseVal);
201
Michael Kruse9f6e41c2017-07-31 19:46:21 +0000202 // PHIs, unless synthesizable, are not yet supported.
203 if (isa<PHINode>(Inst)) {
204 DEBUG(dbgs() << " Cannot forward PHI: " << *UseVal << "\n");
205 return FD_CannotForward;
206 }
207
Michael Krusea6b2de32017-07-22 14:02:47 +0000208 // Compatible instructions must satisfy the following conditions:
209 // 1. Idempotent (instruction will be copied, not moved; although its
Michael Kruse54071122017-07-24 15:34:03 +0000210 // original instance might be removed by simplification)
Michael Krusea6b2de32017-07-22 14:02:47 +0000211 // 2. Not access memory (There might be memory writes between)
212 // 3. Not cause undefined behaviour (we might copy to a location when the
Michael Kruse54071122017-07-24 15:34:03 +0000213 // original instruction was no executed; this is currently not possible
214 // because we do not forward PHINodes)
Michael Krusea6b2de32017-07-22 14:02:47 +0000215 // 4. Not leak memory if executed multiple times (I am looking at you,
Michael Kruse54071122017-07-24 15:34:03 +0000216 // malloc!)
Michael Krusea6b2de32017-07-22 14:02:47 +0000217 //
218 // Instruction::mayHaveSideEffects is not sufficient because it considers
219 // malloc to not have side-effects. llvm::isSafeToSpeculativelyExecute is
220 // not sufficient because it allows memory accesses.
221 if (mayBeMemoryDependent(*Inst)) {
222 DEBUG(dbgs() << " Cannot forward side-effect instruction: " << *Inst
223 << "\n");
224 return FD_CannotForward;
225 }
226
227 Loop *DefLoop = LI->getLoopFor(Inst->getParent());
228 ScopStmt *DefStmt = S->getStmtFor(Inst);
229 assert(DefStmt && "Value must be defined somewhere");
230
231 if (DoIt) {
232 // To ensure the right order, prepend this instruction before its
233 // operands. This ensures that its operands are inserted before the
234 // instruction using them.
235 // TODO: The operand tree is not really a tree, but a DAG. We should be
236 // able to handle DAGs without duplication.
Michael Kruse25a68812017-07-24 12:39:41 +0000237 TargetStmt->prependInstruction(Inst);
Michael Krusea6b2de32017-07-22 14:02:47 +0000238 NumInstructionsCopied++;
239 TotalInstructionsCopied++;
240 }
241
242 for (Value *OpVal : Inst->operand_values()) {
243 ForwardingDecision OpDecision =
244 canForwardTree(TargetStmt, OpVal, DefStmt, DefLoop, DoIt);
245 switch (OpDecision) {
246 case FD_CannotForward:
247 assert(!DoIt);
248 return FD_CannotForward;
249
Michael Kruse67752072017-07-24 15:33:58 +0000250 case FD_CanForwardLeaf:
Michael Kruse07e8c362017-07-24 12:43:27 +0000251 case FD_CanForwardTree:
Michael Krusea6b2de32017-07-22 14:02:47 +0000252 assert(!DoIt);
253 break;
254
255 case FD_DidForward:
256 assert(DoIt);
257 break;
258 }
259 }
260
261 if (DoIt)
262 return FD_DidForward;
Michael Kruse07e8c362017-07-24 12:43:27 +0000263 return FD_CanForwardTree;
Michael Krusea6b2de32017-07-22 14:02:47 +0000264 }
265
266 llvm_unreachable("Case unhandled");
267 }
268
269 /// Try to forward an operand tree rooted in @p RA.
270 bool tryForwardTree(MemoryAccess *RA) {
271 assert(RA->isLatestScalarKind());
272 DEBUG(dbgs() << "Trying to forward operand tree " << RA << "...\n");
273
274 ScopStmt *Stmt = RA->getStatement();
275 Loop *InLoop = Stmt->getSurroundingLoop();
276
277 ForwardingDecision Assessment =
278 canForwardTree(Stmt, RA->getAccessValue(), Stmt, InLoop, false);
279 assert(Assessment != FD_DidForward);
Michael Kruse07e8c362017-07-24 12:43:27 +0000280 if (Assessment != FD_CanForwardTree)
Michael Krusea6b2de32017-07-22 14:02:47 +0000281 return false;
282
283 ForwardingDecision Execution =
284 canForwardTree(Stmt, RA->getAccessValue(), Stmt, InLoop, true);
285 assert(Execution == FD_DidForward);
286
287 Stmt->removeSingleMemoryAccess(RA);
288 return true;
289 }
290
291public:
292 ForwardOpTreeImpl(Scop *S, LoopInfo *LI) : S(S), LI(LI) {}
293
294 /// Return which SCoP this instance is processing.
295 Scop *getScop() const { return S; }
296
297 /// Run the algorithm: Use value read accesses as operand tree roots and try
298 /// to forward them into the statement.
299 bool forwardOperandTrees() {
300 for (ScopStmt &Stmt : *S) {
301 // Currently we cannot modify the instruction list of region statements.
302 if (!Stmt.isBlockStmt())
303 continue;
304
305 bool StmtModified = false;
306
307 // Because we are modifying the MemoryAccess list, collect them first to
308 // avoid iterator invalidation.
309 SmallVector<MemoryAccess *, 16> Accs;
310 for (MemoryAccess *RA : Stmt) {
311 if (!RA->isRead())
312 continue;
313 if (!RA->isLatestScalarKind())
314 continue;
315
316 Accs.push_back(RA);
317 }
318
319 for (MemoryAccess *RA : Accs) {
320 if (tryForwardTree(RA)) {
321 Modified = true;
322 StmtModified = true;
323 NumForwardedTrees++;
324 TotalForwardedTrees++;
325 }
326 }
327
328 if (StmtModified) {
329 NumModifiedStmts++;
330 TotalModifiedStmts++;
331 }
332 }
333
334 if (Modified)
335 ScopsModified++;
336 return Modified;
337 }
338
339 /// Print the pass result, performed transformations and the SCoP after the
340 /// transformation.
341 void print(llvm::raw_ostream &OS, int Indent = 0) {
342 printStatistics(OS, Indent);
343
344 if (!Modified) {
345 // This line can easily be checked in regression tests.
346 OS << "ForwardOpTree executed, but did not modify anything\n";
347 return;
348 }
349
350 printStatements(OS, Indent);
351 }
352};
353
354/// Pass that redirects scalar reads to array elements that are known to contain
355/// the same value.
356///
357/// This reduces the number of scalar accesses and therefore potentially
358/// increases the freedom of the scheduler. In the ideal case, all reads of a
359/// scalar definition are redirected (We currently do not care about removing
360/// the write in this case). This is also useful for the main DeLICM pass as
361/// there are less scalars to be mapped.
362class ForwardOpTree : public ScopPass {
363private:
364 ForwardOpTree(const ForwardOpTree &) = delete;
365 const ForwardOpTree &operator=(const ForwardOpTree &) = delete;
366
367 /// The pass implementation, also holding per-scop data.
368 std::unique_ptr<ForwardOpTreeImpl> Impl;
369
370public:
371 static char ID;
372
373 explicit ForwardOpTree() : ScopPass(ID) {}
374
375 virtual void getAnalysisUsage(AnalysisUsage &AU) const override {
376 AU.addRequiredTransitive<ScopInfoRegionPass>();
377 AU.addRequired<LoopInfoWrapperPass>();
378 AU.setPreservesAll();
379 }
380
381 virtual bool runOnScop(Scop &S) override {
382 // Free resources for previous SCoP's computation, if not yet done.
383 releaseMemory();
384
385 LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
386 Impl = make_unique<ForwardOpTreeImpl>(&S, &LI);
387
388 DEBUG(dbgs() << "Forwarding operand trees...\n");
389 Impl->forwardOperandTrees();
390
391 DEBUG(dbgs() << "\nFinal Scop:\n");
392 DEBUG(dbgs() << S);
393
394 return false;
395 }
396
397 virtual void printScop(raw_ostream &OS, Scop &S) const override {
398 if (!Impl)
399 return;
400
401 assert(Impl->getScop() == &S);
402 Impl->print(OS);
403 }
404
405 virtual void releaseMemory() override { Impl.reset(); }
406
407}; // class ForwardOpTree
408
409char ForwardOpTree::ID;
410} // anonymous namespace
411
412ScopPass *polly::createForwardOpTreePass() { return new ForwardOpTree(); }
413
414INITIALIZE_PASS_BEGIN(ForwardOpTree, "polly-optree",
415 "Polly - Forward operand tree", false, false)
416INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
417INITIALIZE_PASS_END(ForwardOpTree, "polly-optree",
418 "Polly - Forward operand tree", false, false)