blob: 9c24170bcd5550f691e5a64db32c7ea4100da907 [file] [log] [blame]
Eugene Zelenko9248fde2017-08-24 21:22:41 +00001//===- ForwardOpTree.h ------------------------------------------*- C++ -*-===//
Michael Krusea6b2de32017-07-22 14:02:47 +00002//
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"
Michael Kruse70af4f52017-08-07 18:40:29 +000015#include "polly/Options.h"
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"
Michael Kruse70af4f52017-08-07 18:40:29 +000020#include "polly/Support/ISLOStream.h"
21#include "polly/Support/ISLTools.h"
Michael Krusea6b2de32017-07-22 14:02:47 +000022#include "polly/Support/VirtualInstruction.h"
Michael Kruse70af4f52017-08-07 18:40:29 +000023#include "polly/ZoneAlgo.h"
Eugene Zelenko9248fde2017-08-24 21:22:41 +000024#include "llvm/ADT/STLExtras.h"
25#include "llvm/ADT/SmallVector.h"
26#include "llvm/ADT/Statistic.h"
27#include "llvm/Analysis/LoopInfo.h"
Michael Krusea6b2de32017-07-22 14:02:47 +000028#include "llvm/Analysis/ValueTracking.h"
Eugene Zelenko9248fde2017-08-24 21:22:41 +000029#include "llvm/IR/Instruction.h"
30#include "llvm/IR/Instructions.h"
31#include "llvm/IR/Value.h"
32#include "llvm/Pass.h"
33#include "llvm/Support/Casting.h"
34#include "llvm/Support/CommandLine.h"
35#include "llvm/Support/Compiler.h"
36#include "llvm/Support/Debug.h"
37#include "llvm/Support/ErrorHandling.h"
38#include "llvm/Support/raw_ostream.h"
39#include "isl/ctx.h"
40#include "isl/isl-noexceptions.h"
41#include <cassert>
42#include <memory>
Michael Krusea6b2de32017-07-22 14:02:47 +000043
Michael Kruse36550ba2017-08-09 12:27:35 +000044#define DEBUG_TYPE "polly-optree"
Michael Krusea6b2de32017-07-22 14:02:47 +000045
Michael Krusea6b2de32017-07-22 14:02:47 +000046using namespace llvm;
Eugene Zelenko9248fde2017-08-24 21:22:41 +000047using namespace polly;
Michael Krusea6b2de32017-07-22 14:02:47 +000048
Michael Kruse70af4f52017-08-07 18:40:29 +000049static cl::opt<bool>
50 AnalyzeKnown("polly-optree-analyze-known",
51 cl::desc("Analyze array contents for load forwarding"),
52 cl::cat(PollyCategory), cl::init(true), cl::Hidden);
53
Michael Kruse68821a82017-10-31 16:11:46 +000054static cl::opt<bool>
55 NormalizePHIs("polly-optree-normalize-phi",
56 cl::desc("Replace PHIs by their incoming values"),
57 cl::cat(PollyCategory), cl::init(false), cl::Hidden);
58
Michael Kruseef8325b2017-09-18 17:43:50 +000059static cl::opt<unsigned>
Michael Kruse70af4f52017-08-07 18:40:29 +000060 MaxOps("polly-optree-max-ops",
61 cl::desc("Maximum number of ISL operations to invest for known "
62 "analysis; 0=no limit"),
63 cl::init(1000000), cl::cat(PollyCategory), cl::Hidden);
64
65STATISTIC(KnownAnalyzed, "Number of successfully analyzed SCoPs");
66STATISTIC(KnownOutOfQuota,
67 "Analyses aborted because max_operations was reached");
Michael Kruse70af4f52017-08-07 18:40:29 +000068
Michael Krusea6b2de32017-07-22 14:02:47 +000069STATISTIC(TotalInstructionsCopied, "Number of copied instructions");
Michael Kruse70af4f52017-08-07 18:40:29 +000070STATISTIC(TotalKnownLoadsForwarded,
71 "Number of forwarded loads because their value was known");
Michael Kruse822dfe22017-10-27 14:26:14 +000072STATISTIC(TotalReloads, "Number of reloaded values");
Michael Kruse07e8c362017-07-24 12:43:27 +000073STATISTIC(TotalReadOnlyCopied, "Number of copied read-only accesses");
Michael Krusea6b2de32017-07-22 14:02:47 +000074STATISTIC(TotalForwardedTrees, "Number of forwarded operand trees");
75STATISTIC(TotalModifiedStmts,
76 "Number of statements with at least one forwarded tree");
77
78STATISTIC(ScopsModified, "Number of SCoPs with at least one forwarded tree");
79
Michael Kruse06ed5292017-08-23 13:50:30 +000080STATISTIC(NumValueWrites, "Number of scalar value writes after OpTree");
81STATISTIC(NumValueWritesInLoops,
82 "Number of scalar value writes nested in affine loops after OpTree");
83STATISTIC(NumPHIWrites, "Number of scalar phi writes after OpTree");
84STATISTIC(NumPHIWritesInLoops,
85 "Number of scalar phi writes nested in affine loops after OpTree");
86STATISTIC(NumSingletonWrites, "Number of singleton writes after OpTree");
87STATISTIC(NumSingletonWritesInLoops,
88 "Number of singleton writes nested in affine loops after OpTree");
89
Michael Krusea6b2de32017-07-22 14:02:47 +000090namespace {
91
92/// The state of whether an operand tree was/can be forwarded.
Michael Krused85e3452017-07-24 15:33:53 +000093///
94/// The items apply to an instructions and its operand tree with the instruction
95/// as the root element. If the value in question is not an instruction in the
96/// SCoP, it can be a leaf of an instruction's operand tree.
Michael Krusea6b2de32017-07-22 14:02:47 +000097enum ForwardingDecision {
Michael Krused85e3452017-07-24 15:33:53 +000098 /// The root instruction or value cannot be forwarded at all.
Michael Krusea6b2de32017-07-22 14:02:47 +000099 FD_CannotForward,
Michael Krused85e3452017-07-24 15:33:53 +0000100
101 /// The root instruction or value can be forwarded as a leaf of a larger
102 /// operand tree.
103 /// It does not make sense to move the value itself, it would just replace it
104 /// by a use of itself. For instance, a constant "5" used in a statement can
105 /// be forwarded, but it would just replace it by the same constant "5".
106 /// However, it makes sense to move as an operand of
107 ///
108 /// %add = add 5, 5
109 ///
110 /// where "5" is moved as part of a larger operand tree. "5" would be placed
111 /// (disregarding for a moment that literal constants don't have a location
112 /// and can be used anywhere) into the same statement as %add would.
Michael Kruse67752072017-07-24 15:33:58 +0000113 FD_CanForwardLeaf,
Michael Krused85e3452017-07-24 15:33:53 +0000114
Michael Kruse822dfe22017-10-27 14:26:14 +0000115 /// The root instruction can be forwarded and doing so avoids a scalar
116 /// dependency.
117 ///
118 /// This can be either because the operand tree can be moved to the target
119 /// statement, or a memory access is redirected to read from a different
120 /// location.
121 FD_CanForwardProfitably,
Michael Krused85e3452017-07-24 15:33:53 +0000122
Michael Kruse822dfe22017-10-27 14:26:14 +0000123 /// Used to indicate that a forwarding has be carried out successfully, and
124 /// the forwarded memory access can be deleted.
125 FD_DidForwardTree,
126
127 /// Used to indicate that a forwarding has be carried out successfully, and
128 /// the forwarded memory access is being reused.
129 FD_DidForwardLeaf,
Michael Krusea9a70862017-08-04 12:28:42 +0000130
131 /// A forwarding method cannot be applied to the operand tree.
132 /// The difference to FD_CannotForward is that there might be other methods
133 /// that can handle it.
134 /// The conditions that make an operand tree applicable must be checked even
135 /// with DoIt==true because a method following the one that returned
136 /// FD_NotApplicable might have returned FD_CanForwardTree.
137 FD_NotApplicable
Michael Krusea6b2de32017-07-22 14:02:47 +0000138};
139
140/// Implementation of operand tree forwarding for a specific SCoP.
141///
142/// For a statement that requires a scalar value (through a value read
143/// MemoryAccess), see if its operand can be moved into the statement. If so,
144/// the MemoryAccess is removed and the all the operand tree instructions are
145/// moved into the statement. All original instructions are left in the source
146/// statements. The simplification pass can clean these up.
Michael Kruse70af4f52017-08-07 18:40:29 +0000147class ForwardOpTreeImpl : ZoneAlgorithm {
Michael Krusea6b2de32017-07-22 14:02:47 +0000148private:
Michael Kruse89972e22017-09-19 22:53:20 +0000149 /// Scope guard to limit the number of isl operations for this pass.
150 IslMaxOperationsGuard &MaxOpGuard;
151
Michael Krusea6b2de32017-07-22 14:02:47 +0000152 /// How many instructions have been copied to other statements.
153 int NumInstructionsCopied = 0;
154
Michael Kruse70af4f52017-08-07 18:40:29 +0000155 /// Number of loads forwarded because their value was known.
156 int NumKnownLoadsForwarded = 0;
157
Michael Kruse822dfe22017-10-27 14:26:14 +0000158 /// Number of values reloaded from known array elements.
159 int NumReloads = 0;
160
Michael Kruse07e8c362017-07-24 12:43:27 +0000161 /// How many read-only accesses have been copied.
162 int NumReadOnlyCopied = 0;
163
Michael Krusea6b2de32017-07-22 14:02:47 +0000164 /// How many operand trees have been forwarded.
165 int NumForwardedTrees = 0;
166
167 /// Number of statements with at least one forwarded operand tree.
168 int NumModifiedStmts = 0;
169
170 /// Whether we carried out at least one change to the SCoP.
171 bool Modified = false;
172
Michael Kruse70af4f52017-08-07 18:40:29 +0000173 /// Contains the zones where array elements are known to contain a specific
174 /// value.
175 /// { [Element[] -> Zone[]] -> ValInst[] }
176 /// @see computeKnown()
177 isl::union_map Known;
178
179 /// Translator for newly introduced ValInsts to already existing ValInsts such
180 /// that new introduced load instructions can reuse the Known analysis of its
181 /// original load. { ValInst[] -> ValInst[] }
182 isl::union_map Translator;
183
Michael Krused3ce8992018-05-29 15:19:17 +0000184 /// A cache for getDefToTarget().
185 DenseMap<std::pair<ScopStmt *, ScopStmt *>, isl::map> DefToTargetCache;
186
Michael Kruse70af4f52017-08-07 18:40:29 +0000187 /// Get list of array elements that do contain the same ValInst[] at Domain[].
188 ///
189 /// @param ValInst { Domain[] -> ValInst[] }
190 /// The values for which we search for alternative locations,
191 /// per statement instance.
192 ///
193 /// @return { Domain[] -> Element[] }
194 /// For each statement instance, the array elements that contain the
195 /// same ValInst.
196 isl::union_map findSameContentElements(isl::union_map ValInst) {
Michael Krusee276e9f2017-10-02 11:41:06 +0000197 assert(!ValInst.is_single_valued().is_false());
Michael Kruse70af4f52017-08-07 18:40:29 +0000198
199 // { Domain[] }
200 isl::union_set Domain = ValInst.domain();
201
202 // { Domain[] -> Scatter[] }
203 isl::union_map Schedule = getScatterFor(Domain);
204
205 // { Element[] -> [Scatter[] -> ValInst[]] }
206 isl::union_map MustKnownCurried =
207 convertZoneToTimepoints(Known, isl::dim::in, false, true).curry();
208
209 // { [Domain[] -> ValInst[]] -> Scatter[] }
210 isl::union_map DomValSched = ValInst.domain_map().apply_range(Schedule);
211
212 // { [Scatter[] -> ValInst[]] -> [Domain[] -> ValInst[]] }
213 isl::union_map SchedValDomVal =
214 DomValSched.range_product(ValInst.range_map()).reverse();
215
216 // { Element[] -> [Domain[] -> ValInst[]] }
217 isl::union_map MustKnownInst = MustKnownCurried.apply_range(SchedValDomVal);
218
219 // { Domain[] -> Element[] }
220 isl::union_map MustKnownMap =
221 MustKnownInst.uncurry().domain().unwrap().reverse();
222 simplify(MustKnownMap);
223
224 return MustKnownMap;
225 }
226
227 /// Find a single array element for each statement instance, within a single
228 /// array.
229 ///
230 /// @param MustKnown { Domain[] -> Element[] }
231 /// Set of candidate array elements.
232 /// @param Domain { Domain[] }
233 /// The statement instance for which we need elements for.
234 ///
235 /// @return { Domain[] -> Element[] }
236 /// For each statement instance, an array element out of @p MustKnown.
237 /// All array elements must be in the same array (Polly does not yet
238 /// support reading from different accesses using the same
239 /// MemoryAccess). If no mapping for all of @p Domain exists, returns
240 /// null.
241 isl::map singleLocation(isl::union_map MustKnown, isl::set Domain) {
242 // { Domain[] -> Element[] }
243 isl::map Result;
244
245 // MemoryAccesses can read only elements from a single array
246 // (i.e. not: { Dom[0] -> A[0]; Dom[1] -> B[1] }).
247 // Look through all spaces until we find one that contains at least the
248 // wanted statement instance.s
Reid Kleckner8d719a22017-08-10 21:46:22 +0000249 MustKnown.foreach_map([&](isl::map Map) -> isl::stat {
Michael Kruse70af4f52017-08-07 18:40:29 +0000250 // Get the array this is accessing.
251 isl::id ArrayId = Map.get_tuple_id(isl::dim::out);
252 ScopArrayInfo *SAI = static_cast<ScopArrayInfo *>(ArrayId.get_user());
253
254 // No support for generation of indirect array accesses.
255 if (SAI->getBasePtrOriginSAI())
256 return isl::stat::ok; // continue
257
258 // Determine whether this map contains all wanted values.
259 isl::set MapDom = Map.domain();
260 if (!Domain.is_subset(MapDom).is_true())
261 return isl::stat::ok; // continue
262
263 // There might be multiple array elements that contain the same value, but
264 // choose only one of them. lexmin is used because it returns a one-value
265 // mapping, we do not care about which one.
266 // TODO: Get the simplest access function.
267 Result = Map.lexmin();
268 return isl::stat::error; // break
269 });
270
271 return Result;
272 }
273
274public:
Michael Kruse89972e22017-09-19 22:53:20 +0000275 ForwardOpTreeImpl(Scop *S, LoopInfo *LI, IslMaxOperationsGuard &MaxOpGuard)
276 : ZoneAlgorithm("polly-optree", S, LI), MaxOpGuard(MaxOpGuard) {}
Eugene Zelenko9248fde2017-08-24 21:22:41 +0000277
Michael Kruse70af4f52017-08-07 18:40:29 +0000278 /// Compute the zones of known array element contents.
279 ///
280 /// @return True if the computed #Known is usable.
281 bool computeKnownValues() {
282 isl::union_map MustKnown, KnownFromLoad, KnownFromInit;
283
284 // Check that nothing strange occurs.
Michael Kruse47281842017-08-28 20:39:07 +0000285 collectCompatibleElts();
Michael Kruse70af4f52017-08-07 18:40:29 +0000286
Michael Kruse70af4f52017-08-07 18:40:29 +0000287 {
Michael Kruse89972e22017-09-19 22:53:20 +0000288 IslQuotaScope QuotaScope = MaxOpGuard.enter();
Michael Kruse70af4f52017-08-07 18:40:29 +0000289
290 computeCommon();
Michael Kruse68821a82017-10-31 16:11:46 +0000291 if (NormalizePHIs)
292 computeNormalizedPHIs();
Michael Kruse70af4f52017-08-07 18:40:29 +0000293 Known = computeKnown(true, true);
Michael Kruse70af4f52017-08-07 18:40:29 +0000294
295 // Preexisting ValInsts use the known content analysis of themselves.
296 Translator = makeIdentityMap(Known.range(), false);
297 }
298
Michael Kruse68821a82017-10-31 16:11:46 +0000299 if (!Known || !Translator || !NormalizeMap) {
Michael Kruse70af4f52017-08-07 18:40:29 +0000300 assert(isl_ctx_last_error(IslCtx.get()) == isl_error_quota);
Michael Kruse70af4f52017-08-07 18:40:29 +0000301 Known = nullptr;
302 Translator = nullptr;
Michael Kruse68821a82017-10-31 16:11:46 +0000303 NormalizeMap = nullptr;
Nicola Zaghen349506a2018-05-15 13:37:17 +0000304 LLVM_DEBUG(dbgs() << "Known analysis exceeded max_operations\n");
Michael Kruse70af4f52017-08-07 18:40:29 +0000305 return false;
306 }
307
308 KnownAnalyzed++;
Nicola Zaghen349506a2018-05-15 13:37:17 +0000309 LLVM_DEBUG(dbgs() << "All known: " << Known << "\n");
Michael Kruse70af4f52017-08-07 18:40:29 +0000310
311 return true;
312 }
313
Michael Krusea6b2de32017-07-22 14:02:47 +0000314 void printStatistics(raw_ostream &OS, int Indent = 0) {
315 OS.indent(Indent) << "Statistics {\n";
316 OS.indent(Indent + 4) << "Instructions copied: " << NumInstructionsCopied
317 << '\n';
Michael Kruse70af4f52017-08-07 18:40:29 +0000318 OS.indent(Indent + 4) << "Known loads forwarded: " << NumKnownLoadsForwarded
319 << '\n';
Michael Krusecc6ea8e2017-10-27 14:48:34 +0000320 OS.indent(Indent + 4) << "Reloads: " << NumReloads << '\n';
Michael Kruse07e8c362017-07-24 12:43:27 +0000321 OS.indent(Indent + 4) << "Read-only accesses copied: " << NumReadOnlyCopied
322 << '\n';
Michael Krusea6b2de32017-07-22 14:02:47 +0000323 OS.indent(Indent + 4) << "Operand trees forwarded: " << NumForwardedTrees
324 << '\n';
325 OS.indent(Indent + 4) << "Statements with forwarded operand trees: "
326 << NumModifiedStmts << '\n';
327 OS.indent(Indent) << "}\n";
328 }
329
Eugene Zelenko9248fde2017-08-24 21:22:41 +0000330 void printStatements(raw_ostream &OS, int Indent = 0) const {
Michael Krusea6b2de32017-07-22 14:02:47 +0000331 OS.indent(Indent) << "After statements {\n";
332 for (auto &Stmt : *S) {
333 OS.indent(Indent + 4) << Stmt.getBaseName() << "\n";
334 for (auto *MA : Stmt)
335 MA->print(OS);
336
337 OS.indent(Indent + 12);
338 Stmt.printInstructions(OS);
339 }
340 OS.indent(Indent) << "}\n";
341 }
342
Michael Kruse70af4f52017-08-07 18:40:29 +0000343 /// Create a new MemoryAccess of type read and MemoryKind::Array.
344 ///
345 /// @param Stmt The statement in which the access occurs.
346 /// @param LI The instruction that does the access.
347 /// @param AccessRelation The array element that each statement instance
348 /// accesses.
349 ///
350 /// @param The newly created access.
351 MemoryAccess *makeReadArrayAccess(ScopStmt *Stmt, LoadInst *LI,
352 isl::map AccessRelation) {
353 isl::id ArrayId = AccessRelation.get_tuple_id(isl::dim::out);
354 ScopArrayInfo *SAI = reinterpret_cast<ScopArrayInfo *>(ArrayId.get_user());
355
356 // Create a dummy SCEV access, to be replaced anyway.
357 SmallVector<const SCEV *, 4> Sizes;
358 Sizes.reserve(SAI->getNumberOfDimensions());
359 SmallVector<const SCEV *, 4> Subscripts;
360 Subscripts.reserve(SAI->getNumberOfDimensions());
361 for (unsigned i = 0; i < SAI->getNumberOfDimensions(); i += 1) {
362 Sizes.push_back(SAI->getDimensionSize(i));
363 Subscripts.push_back(nullptr);
364 }
365
366 MemoryAccess *Access =
367 new MemoryAccess(Stmt, LI, MemoryAccess::READ, SAI->getBasePtr(),
368 LI->getType(), true, {}, Sizes, LI, MemoryKind::Array);
369 S->addAccessFunction(Access);
370 Stmt->addAccess(Access, true);
371
372 Access->setNewAccessRelation(AccessRelation);
373
374 return Access;
375 }
376
377 /// For an llvm::Value defined in @p DefStmt, compute the RAW dependency for a
378 /// use in every instance of @p UseStmt.
379 ///
380 /// @param UseStmt Statement a scalar is used in.
381 /// @param DefStmt Statement a scalar is defined in.
382 ///
383 /// @return { DomainUse[] -> DomainDef[] }
384 isl::map computeUseToDefFlowDependency(ScopStmt *UseStmt, ScopStmt *DefStmt) {
385 // { DomainUse[] -> Scatter[] }
386 isl::map UseScatter = getScatterFor(UseStmt);
387
388 // { Zone[] -> DomainDef[] }
389 isl::map ReachDefZone = getScalarReachingDefinition(DefStmt);
390
391 // { Scatter[] -> DomainDef[] }
392 isl::map ReachDefTimepoints =
393 convertZoneToTimepoints(ReachDefZone, isl::dim::in, false, true);
394
395 // { DomainUse[] -> DomainDef[] }
396 return UseScatter.apply_range(ReachDefTimepoints);
397 }
398
Michael Krused3ce8992018-05-29 15:19:17 +0000399 /// Get a domain translation map from a (scalar) definition to the statement
400 /// where the definition is being moved to.
401 ///
402 /// @p TargetStmt can also be seen an llvm::Use of an llvm::Value in
403 /// @p DefStmt. In addition, we allow transitive uses:
404 ///
405 /// DefStmt -> MiddleStmt -> TargetStmt
406 ///
407 /// where an operand tree of instructions in DefStmt and MiddleStmt are to be
408 /// moved to TargetStmt. To be generally correct, we also need to know all the
409 /// intermediate statements. However, we make use of the fact that we
410 /// currently do not support a move from a loop body across its header such
411 /// that only the first definition and the target statement are relevant.
412 ///
413 /// @param DefStmt Statement from where a definition might be moved from.
414 /// @param TargetStmt Statement where the definition is potentially being
415 /// moved to (should contain a use of that definition).
416 ///
417 /// @return { DomainDef[] -> DomainTarget[] }
418 isl::map getDefToTarget(ScopStmt *DefStmt, ScopStmt *TargetStmt) {
419 // No translation required if the definition is already at the target.
420 if (TargetStmt == DefStmt)
421 return isl::map::identity(
422 getDomainFor(TargetStmt).get_space().map_from_set());
423
424 isl::map &Result = DefToTargetCache[std::make_pair(TargetStmt, DefStmt)];
425 if (!Result) {
426 // { DomainDef[] -> DomainTarget[] }
427 Result = computeUseToDefFlowDependency(TargetStmt, DefStmt).reverse();
428 simplify(Result);
429 }
430
431 return Result;
432 }
433
Michael Kruse70af4f52017-08-07 18:40:29 +0000434 /// Forward a load by reading from an array element that contains the same
435 /// value. Typically the location it was loaded from.
436 ///
437 /// @param TargetStmt The statement the operand tree will be copied to.
438 /// @param Inst The (possibly speculatable) instruction to forward.
439 /// @param UseStmt The statement that uses @p Inst.
440 /// @param UseLoop The loop @p Inst is used in.
Michael Kruse70af4f52017-08-07 18:40:29 +0000441 /// @param DefStmt The statement @p Inst is defined in.
442 /// @param DefLoop The loop which contains @p Inst.
Michael Kruse70af4f52017-08-07 18:40:29 +0000443 /// @param DoIt If false, only determine whether an operand tree can be
444 /// forwarded. If true, carry out the forwarding. Do not
445 /// use DoIt==true if an operand tree is not known to be
446 /// forwardable.
447 ///
Michael Kruse822dfe22017-10-27 14:26:14 +0000448 /// @return FD_NotApplicable if @p Inst cannot be forwarded by creating a new
449 /// load.
450 /// FD_CannotForward if the pointer operand cannot be forwarded.
451 /// FD_CanForwardProfitably if @p Inst is forwardable.
452 /// FD_DidForwardTree if @p DoIt was true.
Michael Kruse70af4f52017-08-07 18:40:29 +0000453 ForwardingDecision forwardKnownLoad(ScopStmt *TargetStmt, Instruction *Inst,
454 ScopStmt *UseStmt, Loop *UseLoop,
Michael Krused3ce8992018-05-29 15:19:17 +0000455 ScopStmt *DefStmt, Loop *DefLoop,
Michael Kruse70af4f52017-08-07 18:40:29 +0000456 bool DoIt) {
457 // Cannot do anything without successful known analysis.
Michael Krused3ce8992018-05-29 15:19:17 +0000458 if (Known.is_null() || Translator.is_null() ||
459 MaxOpGuard.hasQuotaExceeded())
Michael Kruse70af4f52017-08-07 18:40:29 +0000460 return FD_NotApplicable;
461
462 LoadInst *LI = dyn_cast<LoadInst>(Inst);
463 if (!LI)
464 return FD_NotApplicable;
465
Michael Kruse7954a222017-09-03 16:09:38 +0000466 // If the load is already in the statement, no forwarding is necessary.
Michael Kruse70af4f52017-08-07 18:40:29 +0000467 // However, it might happen that the LoadInst is already present in the
468 // statement's instruction list. In that case we do as follows:
469 // - For the evaluation (DoIt==false), we can trivially forward it as it is
470 // benefit of forwarding an already present instruction.
Michael Kruse7954a222017-09-03 16:09:38 +0000471 // - For the execution (DoIt==true), prepend the instruction (to make it
Michael Kruse70af4f52017-08-07 18:40:29 +0000472 // available to all instructions following in the instruction list), but
473 // do not add another MemoryAccess.
474 MemoryAccess *Access = TargetStmt->getArrayAccessOrNULLFor(LI);
475 if (Access && !DoIt)
Michael Kruse822dfe22017-10-27 14:26:14 +0000476 return FD_CanForwardProfitably;
Michael Kruse70af4f52017-08-07 18:40:29 +0000477
Michael Krused3ce8992018-05-29 15:19:17 +0000478 ForwardingDecision OpDecision = forwardTree(
479 TargetStmt, LI->getPointerOperand(), DefStmt, DefLoop, DoIt);
Michael Kruse70af4f52017-08-07 18:40:29 +0000480 switch (OpDecision) {
481 case FD_CannotForward:
482 assert(!DoIt);
483 return OpDecision;
484
485 case FD_CanForwardLeaf:
Michael Kruse822dfe22017-10-27 14:26:14 +0000486 case FD_CanForwardProfitably:
Michael Kruse70af4f52017-08-07 18:40:29 +0000487 assert(!DoIt);
488 break;
489
Michael Kruse822dfe22017-10-27 14:26:14 +0000490 case FD_DidForwardLeaf:
491 case FD_DidForwardTree:
Michael Kruse70af4f52017-08-07 18:40:29 +0000492 assert(DoIt);
493 break;
494
495 default:
496 llvm_unreachable("Shouldn't return this");
497 }
498
Michael Kruse89972e22017-09-19 22:53:20 +0000499 IslQuotaScope QuotaScope = MaxOpGuard.enter(!DoIt);
500
Michael Kruse70af4f52017-08-07 18:40:29 +0000501 // { DomainDef[] -> ValInst[] }
502 isl::map ExpectedVal = makeValInst(Inst, UseStmt, UseLoop);
Michael Krused51fbfc2018-05-31 22:44:23 +0000503 assert(!isNormalized(ExpectedVal).is_false() &&
504 "LoadInsts are always normalized");
Michael Kruse70af4f52017-08-07 18:40:29 +0000505
Michael Krused3ce8992018-05-29 15:19:17 +0000506 // { DomainUse[] -> DomainTarget[] }
507 isl::map UseToTarget = getDefToTarget(UseStmt, TargetStmt);
508
Michael Kruse70af4f52017-08-07 18:40:29 +0000509 // { DomainTarget[] -> ValInst[] }
510 isl::map TargetExpectedVal = ExpectedVal.apply_domain(UseToTarget);
511 isl::union_map TranslatedExpectedVal =
512 isl::union_map(TargetExpectedVal).apply_range(Translator);
513
514 // { DomainTarget[] -> Element[] }
515 isl::union_map Candidates = findSameContentElements(TranslatedExpectedVal);
516
517 isl::map SameVal = singleLocation(Candidates, getDomainFor(TargetStmt));
518 if (!SameVal)
Michael Kruse822dfe22017-10-27 14:26:14 +0000519 return FD_NotApplicable;
520
521 if (DoIt)
522 TargetStmt->prependInstruction(LI);
Michael Kruse70af4f52017-08-07 18:40:29 +0000523
524 if (!DoIt)
Michael Kruse822dfe22017-10-27 14:26:14 +0000525 return FD_CanForwardProfitably;
Michael Kruse70af4f52017-08-07 18:40:29 +0000526
527 if (Access) {
Nicola Zaghen349506a2018-05-15 13:37:17 +0000528 LLVM_DEBUG(
529 dbgs() << " forwarded known load with preexisting MemoryAccess"
530 << Access << "\n");
Michael Kruse70af4f52017-08-07 18:40:29 +0000531 } else {
532 Access = makeReadArrayAccess(TargetStmt, LI, SameVal);
Nicola Zaghen349506a2018-05-15 13:37:17 +0000533 LLVM_DEBUG(dbgs() << " forwarded known load with new MemoryAccess"
534 << Access << "\n");
Michael Kruse70af4f52017-08-07 18:40:29 +0000535
536 // { ValInst[] }
537 isl::space ValInstSpace = ExpectedVal.get_space().range();
538
539 // After adding a new load to the SCoP, also update the Known content
540 // about it. The new load will have a known ValInst of
541 // { [DomainTarget[] -> Value[]] }
542 // but which -- because it is a copy of it -- has same value as the
543 // { [DomainDef[] -> Value[]] }
544 // that it replicates. Instead of cloning the known content of
545 // [DomainDef[] -> Value[]]
546 // for DomainTarget[], we add a 'translator' that maps
547 // [DomainTarget[] -> Value[]] to [DomainDef[] -> Value[]]
548 // before comparing to the known content.
549 // TODO: 'Translator' could also be used to map PHINodes to their incoming
550 // ValInsts.
551 if (ValInstSpace.is_wrapping()) {
552 // { DefDomain[] -> Value[] }
553 isl::map ValInsts = ExpectedVal.range().unwrap();
554
555 // { DefDomain[] }
556 isl::set DefDomain = ValInsts.domain();
557
558 // { Value[] }
559 isl::space ValSpace = ValInstSpace.unwrap().range();
560
561 // { Value[] -> Value[] }
562 isl::map ValToVal =
563 isl::map::identity(ValSpace.map_from_domain_and_range(ValSpace));
564
Michael Krused3ce8992018-05-29 15:19:17 +0000565 // { DomainDef[] -> DomainTarget[] }
566 isl::map DefToTarget = getDefToTarget(DefStmt, TargetStmt);
567
Michael Kruse70af4f52017-08-07 18:40:29 +0000568 // { [TargetDomain[] -> Value[]] -> [DefDomain[] -> Value] }
569 isl::map LocalTranslator = DefToTarget.reverse().product(ValToVal);
570
571 Translator = Translator.add_map(LocalTranslator);
Nicola Zaghen349506a2018-05-15 13:37:17 +0000572 LLVM_DEBUG(dbgs() << " local translator is " << LocalTranslator
573 << "\n");
Michael Kruse70af4f52017-08-07 18:40:29 +0000574 }
575 }
Nicola Zaghen349506a2018-05-15 13:37:17 +0000576 LLVM_DEBUG(dbgs() << " expected values where " << TargetExpectedVal
577 << "\n");
578 LLVM_DEBUG(dbgs() << " candidate elements where " << Candidates
579 << "\n");
Michael Kruse70af4f52017-08-07 18:40:29 +0000580 assert(Access);
581
582 NumKnownLoadsForwarded++;
583 TotalKnownLoadsForwarded++;
Michael Kruse822dfe22017-10-27 14:26:14 +0000584 return FD_DidForwardTree;
585 }
586
587 /// Forward a scalar by redirecting the access to an array element that stores
588 /// the same value.
589 ///
590 /// @param TargetStmt The statement the operand tree will be copied to.
591 /// @param Inst The scalar to forward.
592 /// @param UseStmt The statement that uses @p Inst.
593 /// @param UseLoop The loop @p Inst is used in.
Michael Kruse822dfe22017-10-27 14:26:14 +0000594 /// @param DefStmt The statement @p Inst is defined in.
595 /// @param DefLoop The loop which contains @p Inst.
Michael Kruse822dfe22017-10-27 14:26:14 +0000596 /// @param DoIt If false, only determine whether an operand tree can be
597 /// forwarded. If true, carry out the forwarding. Do not
598 /// use DoIt==true if an operand tree is not known to be
599 /// forwardable.
600 ///
601 /// @return FD_NotApplicable if @p Inst cannot be reloaded.
602 /// FD_CanForwardLeaf if @p Inst can be reloaded.
603 /// FD_CanForwardProfitably if @p Inst has been reloaded.
604 /// FD_DidForwardLeaf if @p DoIt was true.
605 ForwardingDecision reloadKnownContent(ScopStmt *TargetStmt, Instruction *Inst,
606 ScopStmt *UseStmt, Loop *UseLoop,
Michael Krused3ce8992018-05-29 15:19:17 +0000607 ScopStmt *DefStmt, Loop *DefLoop,
Michael Kruse822dfe22017-10-27 14:26:14 +0000608 bool DoIt) {
609 // Cannot do anything without successful known analysis.
Michael Krused3ce8992018-05-29 15:19:17 +0000610 if (Known.is_null() || Translator.is_null() ||
611 MaxOpGuard.hasQuotaExceeded())
Michael Kruse822dfe22017-10-27 14:26:14 +0000612 return FD_NotApplicable;
613
614 MemoryAccess *Access = TargetStmt->lookupInputAccessOf(Inst);
615 if (Access && Access->isLatestArrayKind()) {
616 if (DoIt)
617 return FD_DidForwardLeaf;
618 return FD_CanForwardLeaf;
619 }
620
Michael Kruse4d3f3c72017-11-06 17:48:14 +0000621 // Don't spend too much time analyzing whether it can be reloaded. When
622 // carrying-out the forwarding, we cannot bail-out in the middle of the
623 // transformation. It also shouldn't take as long because some results are
624 // cached.
625 IslQuotaScope QuotaScope = MaxOpGuard.enter(!DoIt);
626
Michael Kruse822dfe22017-10-27 14:26:14 +0000627 // { DomainDef[] -> ValInst[] }
Michael Kruse68821a82017-10-31 16:11:46 +0000628 isl::union_map ExpectedVal = makeNormalizedValInst(Inst, UseStmt, UseLoop);
Michael Kruse822dfe22017-10-27 14:26:14 +0000629
Michael Krused3ce8992018-05-29 15:19:17 +0000630 // { DomainUse[] -> DomainTarget[] }
631 isl::map UseToTarget = getDefToTarget(UseStmt, TargetStmt);
632
Michael Kruse822dfe22017-10-27 14:26:14 +0000633 // { DomainTarget[] -> ValInst[] }
634 isl::union_map TargetExpectedVal = ExpectedVal.apply_domain(UseToTarget);
635 isl::union_map TranslatedExpectedVal =
636 TargetExpectedVal.apply_range(Translator);
637
638 // { DomainTarget[] -> Element[] }
639 isl::union_map Candidates = findSameContentElements(TranslatedExpectedVal);
640
641 isl::map SameVal = singleLocation(Candidates, getDomainFor(TargetStmt));
642 if (!SameVal)
643 return FD_NotApplicable;
644
645 if (!DoIt)
646 return FD_CanForwardProfitably;
647
648 if (!Access)
649 Access = TargetStmt->ensureValueRead(Inst);
650
651 simplify(SameVal);
652 Access->setNewAccessRelation(SameVal);
653
654 TotalReloads++;
655 NumReloads++;
656 return FD_DidForwardLeaf;
Michael Kruse70af4f52017-08-07 18:40:29 +0000657 }
658
Michael Krusea9a70862017-08-04 12:28:42 +0000659 /// Forwards a speculatively executable instruction.
660 ///
Michael Kruse70af4f52017-08-07 18:40:29 +0000661 /// @param TargetStmt The statement the operand tree will be copied to.
662 /// @param UseInst The (possibly speculatable) instruction to forward.
663 /// @param DefStmt The statement @p UseInst is defined in.
664 /// @param DefLoop The loop which contains @p UseInst.
Michael Kruse70af4f52017-08-07 18:40:29 +0000665 /// @param DoIt If false, only determine whether an operand tree can be
666 /// forwarded. If true, carry out the forwarding. Do not
667 /// use DoIt==true if an operand tree is not known to be
668 /// forwardable.
Michael Krusea9a70862017-08-04 12:28:42 +0000669 ///
Michael Kruse70af4f52017-08-07 18:40:29 +0000670 /// @return FD_NotApplicable if @p UseInst is not speculatable.
671 /// FD_CannotForward if one of @p UseInst's operands is not
672 /// forwardable.
673 /// FD_CanForwardTree if @p UseInst is forwardable.
674 /// FD_DidForward if @p DoIt was true.
Michael Krusea9a70862017-08-04 12:28:42 +0000675 ForwardingDecision forwardSpeculatable(ScopStmt *TargetStmt,
676 Instruction *UseInst,
Michael Kruse70af4f52017-08-07 18:40:29 +0000677 ScopStmt *DefStmt, Loop *DefLoop,
Michael Krused3ce8992018-05-29 15:19:17 +0000678 bool DoIt) {
Michael Krusea9a70862017-08-04 12:28:42 +0000679 // PHIs, unless synthesizable, are not yet supported.
680 if (isa<PHINode>(UseInst))
681 return FD_NotApplicable;
682
683 // Compatible instructions must satisfy the following conditions:
684 // 1. Idempotent (instruction will be copied, not moved; although its
685 // original instance might be removed by simplification)
686 // 2. Not access memory (There might be memory writes between)
687 // 3. Not cause undefined behaviour (we might copy to a location when the
688 // original instruction was no executed; this is currently not possible
689 // because we do not forward PHINodes)
690 // 4. Not leak memory if executed multiple times (i.e. malloc)
691 //
692 // Instruction::mayHaveSideEffects is not sufficient because it considers
693 // malloc to not have side-effects. llvm::isSafeToSpeculativelyExecute is
694 // not sufficient because it allows memory accesses.
695 if (mayBeMemoryDependent(*UseInst))
696 return FD_NotApplicable;
697
Michael Krusea9a70862017-08-04 12:28:42 +0000698 if (DoIt) {
699 // To ensure the right order, prepend this instruction before its
700 // operands. This ensures that its operands are inserted before the
701 // instruction using them.
702 // TODO: The operand tree is not really a tree, but a DAG. We should be
703 // able to handle DAGs without duplication.
704 TargetStmt->prependInstruction(UseInst);
705 NumInstructionsCopied++;
706 TotalInstructionsCopied++;
707 }
708
709 for (Value *OpVal : UseInst->operand_values()) {
710 ForwardingDecision OpDecision =
Michael Krused3ce8992018-05-29 15:19:17 +0000711 forwardTree(TargetStmt, OpVal, DefStmt, DefLoop, DoIt);
Michael Krusea9a70862017-08-04 12:28:42 +0000712 switch (OpDecision) {
713 case FD_CannotForward:
714 assert(!DoIt);
715 return FD_CannotForward;
716
717 case FD_CanForwardLeaf:
Michael Kruse822dfe22017-10-27 14:26:14 +0000718 case FD_CanForwardProfitably:
Michael Krusea9a70862017-08-04 12:28:42 +0000719 assert(!DoIt);
720 break;
721
Michael Kruse822dfe22017-10-27 14:26:14 +0000722 case FD_DidForwardLeaf:
723 case FD_DidForwardTree:
Michael Krusea9a70862017-08-04 12:28:42 +0000724 assert(DoIt);
725 break;
726
727 case FD_NotApplicable:
728 llvm_unreachable("forwardTree should never return FD_NotApplicable");
729 }
730 }
731
732 if (DoIt)
Michael Kruse822dfe22017-10-27 14:26:14 +0000733 return FD_DidForwardTree;
734 return FD_CanForwardProfitably;
Michael Krusea9a70862017-08-04 12:28:42 +0000735 }
736
Michael Krusea6b2de32017-07-22 14:02:47 +0000737 /// Determines whether an operand tree can be forwarded or carries out a
738 /// forwarding, depending on the @p DoIt flag.
739 ///
Michael Kruse70af4f52017-08-07 18:40:29 +0000740 /// @param TargetStmt The statement the operand tree will be copied to.
741 /// @param UseVal The value (usually an instruction) which is root of an
742 /// operand tree.
743 /// @param UseStmt The statement that uses @p UseVal.
744 /// @param UseLoop The loop @p UseVal is used in.
Michael Kruse70af4f52017-08-07 18:40:29 +0000745 /// @param DoIt If false, only determine whether an operand tree can be
746 /// forwarded. If true, carry out the forwarding. Do not
747 /// use DoIt==true if an operand tree is not known to be
748 /// forwardable.
Michael Krusea6b2de32017-07-22 14:02:47 +0000749 ///
Michael Kruse5b8a9092017-07-24 12:39:46 +0000750 /// @return If DoIt==false, return whether the operand tree can be forwarded.
751 /// If DoIt==true, return FD_DidForward.
Eugene Zelenko9248fde2017-08-24 21:22:41 +0000752 ForwardingDecision forwardTree(ScopStmt *TargetStmt, Value *UseVal,
Michael Krused3ce8992018-05-29 15:19:17 +0000753 ScopStmt *UseStmt, Loop *UseLoop, bool DoIt) {
Michael Kruse70af4f52017-08-07 18:40:29 +0000754 ScopStmt *DefStmt = nullptr;
755 Loop *DefLoop = nullptr;
756
757 // { DefDomain[] -> TargetDomain[] }
758 isl::map DefToTarget;
759
Michael Krusea6b2de32017-07-22 14:02:47 +0000760 VirtualUse VUse = VirtualUse::create(UseStmt, UseLoop, UseVal, true);
761 switch (VUse.getKind()) {
762 case VirtualUse::Constant:
763 case VirtualUse::Block:
Michael Krusee5f47062017-07-22 14:30:02 +0000764 case VirtualUse::Hoisted:
Michael Krusea6b2de32017-07-22 14:02:47 +0000765 // These can be used anywhere without special considerations.
766 if (DoIt)
Michael Kruse822dfe22017-10-27 14:26:14 +0000767 return FD_DidForwardTree;
Michael Kruse67752072017-07-24 15:33:58 +0000768 return FD_CanForwardLeaf;
Michael Krusea6b2de32017-07-22 14:02:47 +0000769
Michael Kruse9f6e41c2017-07-31 19:46:21 +0000770 case VirtualUse::Synthesizable: {
771 // ScopExpander will take care for of generating the code at the new
772 // location.
773 if (DoIt)
Michael Kruse822dfe22017-10-27 14:26:14 +0000774 return FD_DidForwardTree;
Michael Kruse9f6e41c2017-07-31 19:46:21 +0000775
776 // Check if the value is synthesizable at the new location as well. This
777 // might be possible when leaving a loop for which ScalarEvolution is
778 // unable to derive the exit value for.
779 // TODO: If there is a LCSSA PHI at the loop exit, use that one.
780 // If the SCEV contains a SCEVAddRecExpr, we currently depend on that we
781 // do not forward past its loop header. This would require us to use a
782 // previous loop induction variable instead the current one. We currently
783 // do not allow forwarding PHI nodes, thus this should never occur (the
784 // only exception where no phi is necessary being an unreachable loop
785 // without edge from the outside).
786 VirtualUse TargetUse = VirtualUse::create(
787 S, TargetStmt, TargetStmt->getSurroundingLoop(), UseVal, true);
788 if (TargetUse.getKind() == VirtualUse::Synthesizable)
789 return FD_CanForwardLeaf;
790
Nicola Zaghen349506a2018-05-15 13:37:17 +0000791 LLVM_DEBUG(
792 dbgs() << " Synthesizable would not be synthesizable anymore: "
793 << *UseVal << "\n");
Michael Krusea6b2de32017-07-22 14:02:47 +0000794 return FD_CannotForward;
Michael Kruse9f6e41c2017-07-31 19:46:21 +0000795 }
Michael Krusea6b2de32017-07-22 14:02:47 +0000796
Michael Krusea6b2de32017-07-22 14:02:47 +0000797 case VirtualUse::ReadOnly:
Michael Krused85e3452017-07-24 15:33:53 +0000798 // Note that we cannot return FD_CanForwardTree here. With a operand tree
799 // depth of 0, UseVal is the use in TargetStmt that we try to replace.
800 // With -polly-analyze-read-only-scalars=true we would ensure the
801 // existence of a MemoryAccess (which already exists for a leaf) and be
802 // removed again by tryForwardTree because it's goal is to remove this
803 // scalar MemoryAccess. It interprets FD_CanForwardTree as the permission
804 // to do so.
Michael Kruse07e8c362017-07-24 12:43:27 +0000805 if (!DoIt)
Michael Kruse67752072017-07-24 15:33:58 +0000806 return FD_CanForwardLeaf;
Michael Kruse07e8c362017-07-24 12:43:27 +0000807
808 // If we model read-only scalars, we need to create a MemoryAccess for it.
809 if (ModelReadOnlyScalars)
810 TargetStmt->ensureValueRead(UseVal);
811
812 NumReadOnlyCopied++;
813 TotalReadOnlyCopied++;
Michael Kruse822dfe22017-10-27 14:26:14 +0000814 return FD_DidForwardLeaf;
Michael Krusea6b2de32017-07-22 14:02:47 +0000815
816 case VirtualUse::Intra:
Michael Kruse70af4f52017-08-07 18:40:29 +0000817 // Knowing that UseStmt and DefStmt are the same statement instance, just
818 // reuse the information about UseStmt for DefStmt
819 DefStmt = UseStmt;
Michael Krusea6b2de32017-07-22 14:02:47 +0000820
Michael Kruse70af4f52017-08-07 18:40:29 +0000821 LLVM_FALLTHROUGH;
822 case VirtualUse::Inter:
823 Instruction *Inst = cast<Instruction>(UseVal);
824
Michael Krusecd3b9fe2017-08-09 16:45:37 +0000825 if (!DefStmt) {
Michael Kruse70af4f52017-08-07 18:40:29 +0000826 DefStmt = S->getStmtFor(Inst);
Michael Krusecd3b9fe2017-08-09 16:45:37 +0000827 if (!DefStmt)
828 return FD_CannotForward;
829 }
830
Michael Kruse70af4f52017-08-07 18:40:29 +0000831 DefLoop = LI->getLoopFor(Inst->getParent());
832
Michael Krused3ce8992018-05-29 15:19:17 +0000833 ForwardingDecision SpeculativeResult =
834 forwardSpeculatable(TargetStmt, Inst, DefStmt, DefLoop, DoIt);
Michael Krusea9a70862017-08-04 12:28:42 +0000835 if (SpeculativeResult != FD_NotApplicable)
836 return SpeculativeResult;
Michael Kruse9f6e41c2017-07-31 19:46:21 +0000837
Michael Krused3ce8992018-05-29 15:19:17 +0000838 ForwardingDecision KnownResult = forwardKnownLoad(
839 TargetStmt, Inst, UseStmt, UseLoop, DefStmt, DefLoop, DoIt);
Michael Kruse70af4f52017-08-07 18:40:29 +0000840 if (KnownResult != FD_NotApplicable)
841 return KnownResult;
842
Michael Krused3ce8992018-05-29 15:19:17 +0000843 ForwardingDecision ReloadResult = reloadKnownContent(
844 TargetStmt, Inst, UseStmt, UseLoop, DefStmt, DefLoop, DoIt);
Michael Kruse822dfe22017-10-27 14:26:14 +0000845 if (ReloadResult != FD_NotApplicable)
846 return ReloadResult;
847
Michael Krusea9a70862017-08-04 12:28:42 +0000848 // When no method is found to forward the operand tree, we effectively
849 // cannot handle it.
Nicola Zaghen349506a2018-05-15 13:37:17 +0000850 LLVM_DEBUG(dbgs() << " Cannot forward instruction: " << *Inst << "\n");
Michael Krusea9a70862017-08-04 12:28:42 +0000851 return FD_CannotForward;
Michael Krusea6b2de32017-07-22 14:02:47 +0000852 }
853
854 llvm_unreachable("Case unhandled");
855 }
856
857 /// Try to forward an operand tree rooted in @p RA.
858 bool tryForwardTree(MemoryAccess *RA) {
859 assert(RA->isLatestScalarKind());
Nicola Zaghen349506a2018-05-15 13:37:17 +0000860 LLVM_DEBUG(dbgs() << "Trying to forward operand tree " << RA << "...\n");
Michael Krusea6b2de32017-07-22 14:02:47 +0000861
862 ScopStmt *Stmt = RA->getStatement();
863 Loop *InLoop = Stmt->getSurroundingLoop();
864
Michael Kruse70af4f52017-08-07 18:40:29 +0000865 isl::map TargetToUse;
866 if (!Known.is_null()) {
867 isl::space DomSpace = Stmt->getDomainSpace();
868 TargetToUse =
869 isl::map::identity(DomSpace.map_from_domain_and_range(DomSpace));
870 }
871
Michael Krused3ce8992018-05-29 15:19:17 +0000872 ForwardingDecision Assessment =
873 forwardTree(Stmt, RA->getAccessValue(), Stmt, InLoop, false);
Michael Kruse822dfe22017-10-27 14:26:14 +0000874 assert(Assessment != FD_DidForwardTree && Assessment != FD_DidForwardLeaf);
875 if (Assessment != FD_CanForwardProfitably)
Michael Krusea6b2de32017-07-22 14:02:47 +0000876 return false;
877
Michael Krused3ce8992018-05-29 15:19:17 +0000878 ForwardingDecision Execution =
879 forwardTree(Stmt, RA->getAccessValue(), Stmt, InLoop, true);
Michael Kruse822dfe22017-10-27 14:26:14 +0000880 assert(((Execution == FD_DidForwardTree) ||
881 (Execution == FD_DidForwardLeaf)) &&
Michael Krusefd350892017-08-01 22:15:04 +0000882 "A previous positive assessment must also be executable");
Michael Krusea6b2de32017-07-22 14:02:47 +0000883
Michael Kruse822dfe22017-10-27 14:26:14 +0000884 if (Execution == FD_DidForwardTree)
885 Stmt->removeSingleMemoryAccess(RA);
Michael Krusea6b2de32017-07-22 14:02:47 +0000886 return true;
887 }
888
Michael Krusea6b2de32017-07-22 14:02:47 +0000889 /// Return which SCoP this instance is processing.
890 Scop *getScop() const { return S; }
891
892 /// Run the algorithm: Use value read accesses as operand tree roots and try
893 /// to forward them into the statement.
894 bool forwardOperandTrees() {
895 for (ScopStmt &Stmt : *S) {
Michael Krusea6b2de32017-07-22 14:02:47 +0000896 bool StmtModified = false;
897
898 // Because we are modifying the MemoryAccess list, collect them first to
899 // avoid iterator invalidation.
900 SmallVector<MemoryAccess *, 16> Accs;
901 for (MemoryAccess *RA : Stmt) {
902 if (!RA->isRead())
903 continue;
904 if (!RA->isLatestScalarKind())
905 continue;
906
907 Accs.push_back(RA);
908 }
909
910 for (MemoryAccess *RA : Accs) {
911 if (tryForwardTree(RA)) {
912 Modified = true;
913 StmtModified = true;
914 NumForwardedTrees++;
915 TotalForwardedTrees++;
916 }
917 }
918
919 if (StmtModified) {
920 NumModifiedStmts++;
921 TotalModifiedStmts++;
922 }
923 }
924
925 if (Modified)
926 ScopsModified++;
927 return Modified;
928 }
929
930 /// Print the pass result, performed transformations and the SCoP after the
931 /// transformation.
Eugene Zelenko9248fde2017-08-24 21:22:41 +0000932 void print(raw_ostream &OS, int Indent = 0) {
Michael Krusea6b2de32017-07-22 14:02:47 +0000933 printStatistics(OS, Indent);
934
935 if (!Modified) {
936 // This line can easily be checked in regression tests.
937 OS << "ForwardOpTree executed, but did not modify anything\n";
938 return;
939 }
940
941 printStatements(OS, Indent);
942 }
943};
944
945/// Pass that redirects scalar reads to array elements that are known to contain
946/// the same value.
947///
948/// This reduces the number of scalar accesses and therefore potentially
949/// increases the freedom of the scheduler. In the ideal case, all reads of a
950/// scalar definition are redirected (We currently do not care about removing
951/// the write in this case). This is also useful for the main DeLICM pass as
952/// there are less scalars to be mapped.
953class ForwardOpTree : public ScopPass {
954private:
Michael Krusea6b2de32017-07-22 14:02:47 +0000955 /// The pass implementation, also holding per-scop data.
956 std::unique_ptr<ForwardOpTreeImpl> Impl;
957
958public:
959 static char ID;
960
961 explicit ForwardOpTree() : ScopPass(ID) {}
Eugene Zelenko9248fde2017-08-24 21:22:41 +0000962 ForwardOpTree(const ForwardOpTree &) = delete;
963 ForwardOpTree &operator=(const ForwardOpTree &) = delete;
Michael Krusea6b2de32017-07-22 14:02:47 +0000964
Eugene Zelenko9248fde2017-08-24 21:22:41 +0000965 void getAnalysisUsage(AnalysisUsage &AU) const override {
Michael Krusea6b2de32017-07-22 14:02:47 +0000966 AU.addRequiredTransitive<ScopInfoRegionPass>();
967 AU.addRequired<LoopInfoWrapperPass>();
968 AU.setPreservesAll();
969 }
970
Eugene Zelenko9248fde2017-08-24 21:22:41 +0000971 bool runOnScop(Scop &S) override {
Michael Krusea6b2de32017-07-22 14:02:47 +0000972 // Free resources for previous SCoP's computation, if not yet done.
973 releaseMemory();
974
975 LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
Michael Krusea6b2de32017-07-22 14:02:47 +0000976
Michael Kruse89972e22017-09-19 22:53:20 +0000977 {
Philip Pfaffe00fd43b2017-11-19 22:13:34 +0000978 IslMaxOperationsGuard MaxOpGuard(S.getIslCtx().get(), MaxOps, false);
Michael Kruse89972e22017-09-19 22:53:20 +0000979 Impl = llvm::make_unique<ForwardOpTreeImpl>(&S, &LI, MaxOpGuard);
980
981 if (AnalyzeKnown) {
Nicola Zaghen349506a2018-05-15 13:37:17 +0000982 LLVM_DEBUG(dbgs() << "Prepare forwarders...\n");
Michael Kruse89972e22017-09-19 22:53:20 +0000983 Impl->computeKnownValues();
984 }
985
Nicola Zaghen349506a2018-05-15 13:37:17 +0000986 LLVM_DEBUG(dbgs() << "Forwarding operand trees...\n");
Michael Kruse89972e22017-09-19 22:53:20 +0000987 Impl->forwardOperandTrees();
988
989 if (MaxOpGuard.hasQuotaExceeded()) {
Nicola Zaghen349506a2018-05-15 13:37:17 +0000990 LLVM_DEBUG(dbgs() << "Not all operations completed because of "
991 "max_operations exceeded\n");
Michael Kruse89972e22017-09-19 22:53:20 +0000992 KnownOutOfQuota++;
993 }
Michael Kruse70af4f52017-08-07 18:40:29 +0000994 }
995
Nicola Zaghen349506a2018-05-15 13:37:17 +0000996 LLVM_DEBUG(dbgs() << "\nFinal Scop:\n");
997 LLVM_DEBUG(dbgs() << S);
Michael Krusea6b2de32017-07-22 14:02:47 +0000998
Michael Kruse06ed5292017-08-23 13:50:30 +0000999 // Update statistics
1000 auto ScopStats = S.getStatistics();
1001 NumValueWrites += ScopStats.NumValueWrites;
1002 NumValueWritesInLoops += ScopStats.NumValueWritesInLoops;
1003 NumPHIWrites += ScopStats.NumPHIWrites;
1004 NumPHIWritesInLoops += ScopStats.NumPHIWritesInLoops;
1005 NumSingletonWrites += ScopStats.NumSingletonWrites;
1006 NumSingletonWritesInLoops += ScopStats.NumSingletonWritesInLoops;
1007
Michael Krusea6b2de32017-07-22 14:02:47 +00001008 return false;
1009 }
1010
Eugene Zelenko9248fde2017-08-24 21:22:41 +00001011 void printScop(raw_ostream &OS, Scop &S) const override {
Michael Krusea6b2de32017-07-22 14:02:47 +00001012 if (!Impl)
1013 return;
1014
1015 assert(Impl->getScop() == &S);
1016 Impl->print(OS);
1017 }
1018
Eugene Zelenko9248fde2017-08-24 21:22:41 +00001019 void releaseMemory() override { Impl.reset(); }
Michael Krusea6b2de32017-07-22 14:02:47 +00001020}; // class ForwardOpTree
1021
1022char ForwardOpTree::ID;
Eugene Zelenko9248fde2017-08-24 21:22:41 +00001023} // namespace
Michael Krusea6b2de32017-07-22 14:02:47 +00001024
1025ScopPass *polly::createForwardOpTreePass() { return new ForwardOpTree(); }
1026
1027INITIALIZE_PASS_BEGIN(ForwardOpTree, "polly-optree",
1028 "Polly - Forward operand tree", false, false)
1029INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
1030INITIALIZE_PASS_END(ForwardOpTree, "polly-optree",
1031 "Polly - Forward operand tree", false, false)