blob: 47d16525a2f8ffaa178e866edc0f295bc5a1c93e [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 Kruse70af4f52017-08-07 18:40:29 +000016#include "polly/Options.h"
17#include "polly/RegisterPasses.h"
Michael Kruse07e8c362017-07-24 12:43:27 +000018#include "polly/ScopBuilder.h"
Michael Krusea6b2de32017-07-22 14:02:47 +000019#include "polly/ScopInfo.h"
20#include "polly/ScopPass.h"
21#include "polly/Support/GICHelper.h"
Michael Kruse70af4f52017-08-07 18:40:29 +000022#include "polly/Support/ISLOStream.h"
23#include "polly/Support/ISLTools.h"
Michael Krusea6b2de32017-07-22 14:02:47 +000024#include "polly/Support/VirtualInstruction.h"
Michael Kruse70af4f52017-08-07 18:40:29 +000025#include "polly/ZoneAlgo.h"
Michael Krusea6b2de32017-07-22 14:02:47 +000026#include "llvm/Analysis/ValueTracking.h"
27
Michael Kruse36550ba2017-08-09 12:27:35 +000028#define DEBUG_TYPE "polly-optree"
Michael Krusea6b2de32017-07-22 14:02:47 +000029
30using namespace polly;
31using namespace llvm;
32
Michael Kruse70af4f52017-08-07 18:40:29 +000033static cl::opt<bool>
34 AnalyzeKnown("polly-optree-analyze-known",
35 cl::desc("Analyze array contents for load forwarding"),
36 cl::cat(PollyCategory), cl::init(true), cl::Hidden);
37
38static cl::opt<unsigned long>
39 MaxOps("polly-optree-max-ops",
40 cl::desc("Maximum number of ISL operations to invest for known "
41 "analysis; 0=no limit"),
42 cl::init(1000000), cl::cat(PollyCategory), cl::Hidden);
43
44STATISTIC(KnownAnalyzed, "Number of successfully analyzed SCoPs");
45STATISTIC(KnownOutOfQuota,
46 "Analyses aborted because max_operations was reached");
47STATISTIC(KnownIncompatible, "Number of SCoPs incompatible for analysis");
48
Michael Krusea6b2de32017-07-22 14:02:47 +000049STATISTIC(TotalInstructionsCopied, "Number of copied instructions");
Michael Kruse70af4f52017-08-07 18:40:29 +000050STATISTIC(TotalKnownLoadsForwarded,
51 "Number of forwarded loads because their value was known");
Michael Kruse07e8c362017-07-24 12:43:27 +000052STATISTIC(TotalReadOnlyCopied, "Number of copied read-only accesses");
Michael Krusea6b2de32017-07-22 14:02:47 +000053STATISTIC(TotalForwardedTrees, "Number of forwarded operand trees");
54STATISTIC(TotalModifiedStmts,
55 "Number of statements with at least one forwarded tree");
56
57STATISTIC(ScopsModified, "Number of SCoPs with at least one forwarded tree");
58
Michael Kruse06ed5292017-08-23 13:50:30 +000059STATISTIC(NumValueWrites, "Number of scalar value writes after OpTree");
60STATISTIC(NumValueWritesInLoops,
61 "Number of scalar value writes nested in affine loops after OpTree");
62STATISTIC(NumPHIWrites, "Number of scalar phi writes after OpTree");
63STATISTIC(NumPHIWritesInLoops,
64 "Number of scalar phi writes nested in affine loops after OpTree");
65STATISTIC(NumSingletonWrites, "Number of singleton writes after OpTree");
66STATISTIC(NumSingletonWritesInLoops,
67 "Number of singleton writes nested in affine loops after OpTree");
68
Michael Krusea6b2de32017-07-22 14:02:47 +000069namespace {
70
71/// The state of whether an operand tree was/can be forwarded.
Michael Krused85e3452017-07-24 15:33:53 +000072///
73/// The items apply to an instructions and its operand tree with the instruction
74/// as the root element. If the value in question is not an instruction in the
75/// SCoP, it can be a leaf of an instruction's operand tree.
Michael Krusea6b2de32017-07-22 14:02:47 +000076enum ForwardingDecision {
Michael Krused85e3452017-07-24 15:33:53 +000077 /// The root instruction or value cannot be forwarded at all.
Michael Krusea6b2de32017-07-22 14:02:47 +000078 FD_CannotForward,
Michael Krused85e3452017-07-24 15:33:53 +000079
80 /// The root instruction or value can be forwarded as a leaf of a larger
81 /// operand tree.
82 /// It does not make sense to move the value itself, it would just replace it
83 /// by a use of itself. For instance, a constant "5" used in a statement can
84 /// be forwarded, but it would just replace it by the same constant "5".
85 /// However, it makes sense to move as an operand of
86 ///
87 /// %add = add 5, 5
88 ///
89 /// where "5" is moved as part of a larger operand tree. "5" would be placed
90 /// (disregarding for a moment that literal constants don't have a location
91 /// and can be used anywhere) into the same statement as %add would.
Michael Kruse67752072017-07-24 15:33:58 +000092 FD_CanForwardLeaf,
Michael Krused85e3452017-07-24 15:33:53 +000093
94 /// The root instruction can be forwarded in a non-trivial way. This requires
95 /// the operand tree root to be an instruction in some statement.
Michael Kruse07e8c362017-07-24 12:43:27 +000096 FD_CanForwardTree,
Michael Krused85e3452017-07-24 15:33:53 +000097
98 /// Used to indicate that a forwarding has be carried out successfully.
Michael Krusea6b2de32017-07-22 14:02:47 +000099 FD_DidForward,
Michael Krusea9a70862017-08-04 12:28:42 +0000100
101 /// A forwarding method cannot be applied to the operand tree.
102 /// The difference to FD_CannotForward is that there might be other methods
103 /// that can handle it.
104 /// The conditions that make an operand tree applicable must be checked even
105 /// with DoIt==true because a method following the one that returned
106 /// FD_NotApplicable might have returned FD_CanForwardTree.
107 FD_NotApplicable
Michael Krusea6b2de32017-07-22 14:02:47 +0000108};
109
110/// Implementation of operand tree forwarding for a specific SCoP.
111///
112/// For a statement that requires a scalar value (through a value read
113/// MemoryAccess), see if its operand can be moved into the statement. If so,
114/// the MemoryAccess is removed and the all the operand tree instructions are
115/// moved into the statement. All original instructions are left in the source
116/// statements. The simplification pass can clean these up.
Michael Kruse70af4f52017-08-07 18:40:29 +0000117class ForwardOpTreeImpl : ZoneAlgorithm {
Michael Krusea6b2de32017-07-22 14:02:47 +0000118private:
Michael Krusea6b2de32017-07-22 14:02:47 +0000119 /// How many instructions have been copied to other statements.
120 int NumInstructionsCopied = 0;
121
Michael Kruse70af4f52017-08-07 18:40:29 +0000122 /// Number of loads forwarded because their value was known.
123 int NumKnownLoadsForwarded = 0;
124
Michael Kruse07e8c362017-07-24 12:43:27 +0000125 /// How many read-only accesses have been copied.
126 int NumReadOnlyCopied = 0;
127
Michael Krusea6b2de32017-07-22 14:02:47 +0000128 /// How many operand trees have been forwarded.
129 int NumForwardedTrees = 0;
130
131 /// Number of statements with at least one forwarded operand tree.
132 int NumModifiedStmts = 0;
133
134 /// Whether we carried out at least one change to the SCoP.
135 bool Modified = false;
136
Michael Kruse70af4f52017-08-07 18:40:29 +0000137 /// Contains the zones where array elements are known to contain a specific
138 /// value.
139 /// { [Element[] -> Zone[]] -> ValInst[] }
140 /// @see computeKnown()
141 isl::union_map Known;
142
143 /// Translator for newly introduced ValInsts to already existing ValInsts such
144 /// that new introduced load instructions can reuse the Known analysis of its
145 /// original load. { ValInst[] -> ValInst[] }
146 isl::union_map Translator;
147
148 /// Get list of array elements that do contain the same ValInst[] at Domain[].
149 ///
150 /// @param ValInst { Domain[] -> ValInst[] }
151 /// The values for which we search for alternative locations,
152 /// per statement instance.
153 ///
154 /// @return { Domain[] -> Element[] }
155 /// For each statement instance, the array elements that contain the
156 /// same ValInst.
157 isl::union_map findSameContentElements(isl::union_map ValInst) {
158 assert(ValInst.is_single_valued().is_true());
159
160 // { Domain[] }
161 isl::union_set Domain = ValInst.domain();
162
163 // { Domain[] -> Scatter[] }
164 isl::union_map Schedule = getScatterFor(Domain);
165
166 // { Element[] -> [Scatter[] -> ValInst[]] }
167 isl::union_map MustKnownCurried =
168 convertZoneToTimepoints(Known, isl::dim::in, false, true).curry();
169
170 // { [Domain[] -> ValInst[]] -> Scatter[] }
171 isl::union_map DomValSched = ValInst.domain_map().apply_range(Schedule);
172
173 // { [Scatter[] -> ValInst[]] -> [Domain[] -> ValInst[]] }
174 isl::union_map SchedValDomVal =
175 DomValSched.range_product(ValInst.range_map()).reverse();
176
177 // { Element[] -> [Domain[] -> ValInst[]] }
178 isl::union_map MustKnownInst = MustKnownCurried.apply_range(SchedValDomVal);
179
180 // { Domain[] -> Element[] }
181 isl::union_map MustKnownMap =
182 MustKnownInst.uncurry().domain().unwrap().reverse();
183 simplify(MustKnownMap);
184
185 return MustKnownMap;
186 }
187
188 /// Find a single array element for each statement instance, within a single
189 /// array.
190 ///
191 /// @param MustKnown { Domain[] -> Element[] }
192 /// Set of candidate array elements.
193 /// @param Domain { Domain[] }
194 /// The statement instance for which we need elements for.
195 ///
196 /// @return { Domain[] -> Element[] }
197 /// For each statement instance, an array element out of @p MustKnown.
198 /// All array elements must be in the same array (Polly does not yet
199 /// support reading from different accesses using the same
200 /// MemoryAccess). If no mapping for all of @p Domain exists, returns
201 /// null.
202 isl::map singleLocation(isl::union_map MustKnown, isl::set Domain) {
203 // { Domain[] -> Element[] }
204 isl::map Result;
205
206 // MemoryAccesses can read only elements from a single array
207 // (i.e. not: { Dom[0] -> A[0]; Dom[1] -> B[1] }).
208 // Look through all spaces until we find one that contains at least the
209 // wanted statement instance.s
Reid Kleckner8d719a22017-08-10 21:46:22 +0000210 MustKnown.foreach_map([&](isl::map Map) -> isl::stat {
Michael Kruse70af4f52017-08-07 18:40:29 +0000211 // Get the array this is accessing.
212 isl::id ArrayId = Map.get_tuple_id(isl::dim::out);
213 ScopArrayInfo *SAI = static_cast<ScopArrayInfo *>(ArrayId.get_user());
214
215 // No support for generation of indirect array accesses.
216 if (SAI->getBasePtrOriginSAI())
217 return isl::stat::ok; // continue
218
219 // Determine whether this map contains all wanted values.
220 isl::set MapDom = Map.domain();
221 if (!Domain.is_subset(MapDom).is_true())
222 return isl::stat::ok; // continue
223
224 // There might be multiple array elements that contain the same value, but
225 // choose only one of them. lexmin is used because it returns a one-value
226 // mapping, we do not care about which one.
227 // TODO: Get the simplest access function.
228 Result = Map.lexmin();
229 return isl::stat::error; // break
230 });
231
232 return Result;
233 }
234
235public:
236 /// Compute the zones of known array element contents.
237 ///
238 /// @return True if the computed #Known is usable.
239 bool computeKnownValues() {
240 isl::union_map MustKnown, KnownFromLoad, KnownFromInit;
241
242 // Check that nothing strange occurs.
243 if (!isCompatibleScop()) {
244 KnownIncompatible++;
245 return false;
246 }
247
248 isl_ctx_reset_error(IslCtx.get());
249 {
250 IslMaxOperationsGuard MaxOpGuard(IslCtx.get(), MaxOps);
251
252 computeCommon();
253 Known = computeKnown(true, true);
254 simplify(Known);
255
256 // Preexisting ValInsts use the known content analysis of themselves.
257 Translator = makeIdentityMap(Known.range(), false);
258 }
259
260 if (!Known || !Translator) {
261 assert(isl_ctx_last_error(IslCtx.get()) == isl_error_quota);
262 KnownOutOfQuota++;
263 Known = nullptr;
264 Translator = nullptr;
265 DEBUG(dbgs() << "Known analysis exceeded max_operations\n");
266 return false;
267 }
268
269 KnownAnalyzed++;
270 DEBUG(dbgs() << "All known: " << Known << "\n");
271
272 return true;
273 }
274
Michael Krusea6b2de32017-07-22 14:02:47 +0000275 void printStatistics(raw_ostream &OS, int Indent = 0) {
276 OS.indent(Indent) << "Statistics {\n";
277 OS.indent(Indent + 4) << "Instructions copied: " << NumInstructionsCopied
278 << '\n';
Michael Kruse70af4f52017-08-07 18:40:29 +0000279 OS.indent(Indent + 4) << "Known loads forwarded: " << NumKnownLoadsForwarded
280 << '\n';
Michael Kruse07e8c362017-07-24 12:43:27 +0000281 OS.indent(Indent + 4) << "Read-only accesses copied: " << NumReadOnlyCopied
282 << '\n';
Michael Krusea6b2de32017-07-22 14:02:47 +0000283 OS.indent(Indent + 4) << "Operand trees forwarded: " << NumForwardedTrees
284 << '\n';
285 OS.indent(Indent + 4) << "Statements with forwarded operand trees: "
286 << NumModifiedStmts << '\n';
287 OS.indent(Indent) << "}\n";
288 }
289
290 void printStatements(llvm::raw_ostream &OS, int Indent = 0) const {
291 OS.indent(Indent) << "After statements {\n";
292 for (auto &Stmt : *S) {
293 OS.indent(Indent + 4) << Stmt.getBaseName() << "\n";
294 for (auto *MA : Stmt)
295 MA->print(OS);
296
297 OS.indent(Indent + 12);
298 Stmt.printInstructions(OS);
299 }
300 OS.indent(Indent) << "}\n";
301 }
302
Michael Kruse70af4f52017-08-07 18:40:29 +0000303 /// Create a new MemoryAccess of type read and MemoryKind::Array.
304 ///
305 /// @param Stmt The statement in which the access occurs.
306 /// @param LI The instruction that does the access.
307 /// @param AccessRelation The array element that each statement instance
308 /// accesses.
309 ///
310 /// @param The newly created access.
311 MemoryAccess *makeReadArrayAccess(ScopStmt *Stmt, LoadInst *LI,
312 isl::map AccessRelation) {
313 isl::id ArrayId = AccessRelation.get_tuple_id(isl::dim::out);
314 ScopArrayInfo *SAI = reinterpret_cast<ScopArrayInfo *>(ArrayId.get_user());
315
316 // Create a dummy SCEV access, to be replaced anyway.
317 SmallVector<const SCEV *, 4> Sizes;
318 Sizes.reserve(SAI->getNumberOfDimensions());
319 SmallVector<const SCEV *, 4> Subscripts;
320 Subscripts.reserve(SAI->getNumberOfDimensions());
321 for (unsigned i = 0; i < SAI->getNumberOfDimensions(); i += 1) {
322 Sizes.push_back(SAI->getDimensionSize(i));
323 Subscripts.push_back(nullptr);
324 }
325
326 MemoryAccess *Access =
327 new MemoryAccess(Stmt, LI, MemoryAccess::READ, SAI->getBasePtr(),
328 LI->getType(), true, {}, Sizes, LI, MemoryKind::Array);
329 S->addAccessFunction(Access);
330 Stmt->addAccess(Access, true);
331
332 Access->setNewAccessRelation(AccessRelation);
333
334 return Access;
335 }
336
337 /// For an llvm::Value defined in @p DefStmt, compute the RAW dependency for a
338 /// use in every instance of @p UseStmt.
339 ///
340 /// @param UseStmt Statement a scalar is used in.
341 /// @param DefStmt Statement a scalar is defined in.
342 ///
343 /// @return { DomainUse[] -> DomainDef[] }
344 isl::map computeUseToDefFlowDependency(ScopStmt *UseStmt, ScopStmt *DefStmt) {
345 // { DomainUse[] -> Scatter[] }
346 isl::map UseScatter = getScatterFor(UseStmt);
347
348 // { Zone[] -> DomainDef[] }
349 isl::map ReachDefZone = getScalarReachingDefinition(DefStmt);
350
351 // { Scatter[] -> DomainDef[] }
352 isl::map ReachDefTimepoints =
353 convertZoneToTimepoints(ReachDefZone, isl::dim::in, false, true);
354
355 // { DomainUse[] -> DomainDef[] }
356 return UseScatter.apply_range(ReachDefTimepoints);
357 }
358
359 /// Forward a load by reading from an array element that contains the same
360 /// value. Typically the location it was loaded from.
361 ///
362 /// @param TargetStmt The statement the operand tree will be copied to.
363 /// @param Inst The (possibly speculatable) instruction to forward.
364 /// @param UseStmt The statement that uses @p Inst.
365 /// @param UseLoop The loop @p Inst is used in.
366 /// @param UseToTarget { DomainUse[] -> DomainTarget[] }
367 /// A mapping from the statement instance @p Inst is used
368 /// to the statement instance it is forwarded to.
369 /// @param DefStmt The statement @p Inst is defined in.
370 /// @param DefLoop The loop which contains @p Inst.
371 /// @param DefToTarget { DomainDef[] -> DomainTarget[] }
372 /// A mapping from the statement instance @p Inst is
373 /// defined to the statement instance it is forwarded to.
374 /// @param DoIt If false, only determine whether an operand tree can be
375 /// forwarded. If true, carry out the forwarding. Do not
376 /// use DoIt==true if an operand tree is not known to be
377 /// forwardable.
378 ///
379 /// @return FD_NotApplicable if @p Inst is not a LoadInst.
380 /// FD_CannotForward if no array element to load from was found.
381 /// FD_CanForwardLeaf if the load is already in the target statement
382 /// instance.
383 /// FD_CanForwardTree if @p Inst is forwardable.
384 /// FD_DidForward if @p DoIt was true.
385 ForwardingDecision forwardKnownLoad(ScopStmt *TargetStmt, Instruction *Inst,
386 ScopStmt *UseStmt, Loop *UseLoop,
387 isl::map UseToTarget, ScopStmt *DefStmt,
388 Loop *DefLoop, isl::map DefToTarget,
389 bool DoIt) {
390 // Cannot do anything without successful known analysis.
391 if (Known.is_null())
392 return FD_NotApplicable;
393
394 LoadInst *LI = dyn_cast<LoadInst>(Inst);
395 if (!LI)
396 return FD_NotApplicable;
397
398 // If the load is already in the statement, not forwarding is necessary.
399 // However, it might happen that the LoadInst is already present in the
400 // statement's instruction list. In that case we do as follows:
401 // - For the evaluation (DoIt==false), we can trivially forward it as it is
402 // benefit of forwarding an already present instruction.
403 // - For the execution (DoIt==false), prepend the instruction (to make it
404 // available to all instructions following in the instruction list), but
405 // do not add another MemoryAccess.
406 MemoryAccess *Access = TargetStmt->getArrayAccessOrNULLFor(LI);
407 if (Access && !DoIt)
408 return FD_CanForwardLeaf;
409
410 if (DoIt)
411 TargetStmt->prependInstruction(LI);
412
413 ForwardingDecision OpDecision =
414 forwardTree(TargetStmt, LI->getPointerOperand(), DefStmt, DefLoop,
415 DefToTarget, DoIt);
416 switch (OpDecision) {
417 case FD_CannotForward:
418 assert(!DoIt);
419 return OpDecision;
420
421 case FD_CanForwardLeaf:
422 case FD_CanForwardTree:
423 assert(!DoIt);
424 break;
425
426 case FD_DidForward:
427 assert(DoIt);
428 break;
429
430 default:
431 llvm_unreachable("Shouldn't return this");
432 }
433
434 // { DomainDef[] -> ValInst[] }
435 isl::map ExpectedVal = makeValInst(Inst, UseStmt, UseLoop);
436
437 // { DomainTarget[] -> ValInst[] }
438 isl::map TargetExpectedVal = ExpectedVal.apply_domain(UseToTarget);
439 isl::union_map TranslatedExpectedVal =
440 isl::union_map(TargetExpectedVal).apply_range(Translator);
441
442 // { DomainTarget[] -> Element[] }
443 isl::union_map Candidates = findSameContentElements(TranslatedExpectedVal);
444
445 isl::map SameVal = singleLocation(Candidates, getDomainFor(TargetStmt));
446 if (!SameVal)
447 return FD_CannotForward;
448
449 if (!DoIt)
450 return FD_CanForwardTree;
451
452 if (Access) {
453 DEBUG(dbgs() << " forwarded known load with preexisting MemoryAccess"
454 << Access << "\n");
455 } else {
456 Access = makeReadArrayAccess(TargetStmt, LI, SameVal);
457 DEBUG(dbgs() << " forwarded known load with new MemoryAccess" << Access
458 << "\n");
459
460 // { ValInst[] }
461 isl::space ValInstSpace = ExpectedVal.get_space().range();
462
463 // After adding a new load to the SCoP, also update the Known content
464 // about it. The new load will have a known ValInst of
465 // { [DomainTarget[] -> Value[]] }
466 // but which -- because it is a copy of it -- has same value as the
467 // { [DomainDef[] -> Value[]] }
468 // that it replicates. Instead of cloning the known content of
469 // [DomainDef[] -> Value[]]
470 // for DomainTarget[], we add a 'translator' that maps
471 // [DomainTarget[] -> Value[]] to [DomainDef[] -> Value[]]
472 // before comparing to the known content.
473 // TODO: 'Translator' could also be used to map PHINodes to their incoming
474 // ValInsts.
475 if (ValInstSpace.is_wrapping()) {
476 // { DefDomain[] -> Value[] }
477 isl::map ValInsts = ExpectedVal.range().unwrap();
478
479 // { DefDomain[] }
480 isl::set DefDomain = ValInsts.domain();
481
482 // { Value[] }
483 isl::space ValSpace = ValInstSpace.unwrap().range();
484
485 // { Value[] -> Value[] }
486 isl::map ValToVal =
487 isl::map::identity(ValSpace.map_from_domain_and_range(ValSpace));
488
489 // { [TargetDomain[] -> Value[]] -> [DefDomain[] -> Value] }
490 isl::map LocalTranslator = DefToTarget.reverse().product(ValToVal);
491
492 Translator = Translator.add_map(LocalTranslator);
493 DEBUG(dbgs() << " local translator is " << LocalTranslator
494 << "\n");
495 }
496 }
497 DEBUG(dbgs() << " expected values where " << TargetExpectedVal
498 << "\n");
499 DEBUG(dbgs() << " candidate elements where " << Candidates << "\n");
500 assert(Access);
501
502 NumKnownLoadsForwarded++;
503 TotalKnownLoadsForwarded++;
504 return FD_DidForward;
505 }
506
Michael Krusea9a70862017-08-04 12:28:42 +0000507 /// Forwards a speculatively executable instruction.
508 ///
Michael Kruse70af4f52017-08-07 18:40:29 +0000509 /// @param TargetStmt The statement the operand tree will be copied to.
510 /// @param UseInst The (possibly speculatable) instruction to forward.
511 /// @param DefStmt The statement @p UseInst is defined in.
512 /// @param DefLoop The loop which contains @p UseInst.
513 /// @param DefToTarget { DomainDef[] -> DomainTarget[] }
514 /// A mapping from the statement instance @p UseInst is
515 /// defined to the statement instance it is forwarded to.
516 /// @param DoIt If false, only determine whether an operand tree can be
517 /// forwarded. If true, carry out the forwarding. Do not
518 /// use DoIt==true if an operand tree is not known to be
519 /// forwardable.
Michael Krusea9a70862017-08-04 12:28:42 +0000520 ///
Michael Kruse70af4f52017-08-07 18:40:29 +0000521 /// @return FD_NotApplicable if @p UseInst is not speculatable.
522 /// FD_CannotForward if one of @p UseInst's operands is not
523 /// forwardable.
524 /// FD_CanForwardTree if @p UseInst is forwardable.
525 /// FD_DidForward if @p DoIt was true.
Michael Krusea9a70862017-08-04 12:28:42 +0000526 ForwardingDecision forwardSpeculatable(ScopStmt *TargetStmt,
527 Instruction *UseInst,
Michael Kruse70af4f52017-08-07 18:40:29 +0000528 ScopStmt *DefStmt, Loop *DefLoop,
529 isl::map DefToTarget, bool DoIt) {
Michael Krusea9a70862017-08-04 12:28:42 +0000530 // PHIs, unless synthesizable, are not yet supported.
531 if (isa<PHINode>(UseInst))
532 return FD_NotApplicable;
533
534 // Compatible instructions must satisfy the following conditions:
535 // 1. Idempotent (instruction will be copied, not moved; although its
536 // original instance might be removed by simplification)
537 // 2. Not access memory (There might be memory writes between)
538 // 3. Not cause undefined behaviour (we might copy to a location when the
539 // original instruction was no executed; this is currently not possible
540 // because we do not forward PHINodes)
541 // 4. Not leak memory if executed multiple times (i.e. malloc)
542 //
543 // Instruction::mayHaveSideEffects is not sufficient because it considers
544 // malloc to not have side-effects. llvm::isSafeToSpeculativelyExecute is
545 // not sufficient because it allows memory accesses.
546 if (mayBeMemoryDependent(*UseInst))
547 return FD_NotApplicable;
548
Michael Krusea9a70862017-08-04 12:28:42 +0000549 if (DoIt) {
550 // To ensure the right order, prepend this instruction before its
551 // operands. This ensures that its operands are inserted before the
552 // instruction using them.
553 // TODO: The operand tree is not really a tree, but a DAG. We should be
554 // able to handle DAGs without duplication.
555 TargetStmt->prependInstruction(UseInst);
556 NumInstructionsCopied++;
557 TotalInstructionsCopied++;
558 }
559
560 for (Value *OpVal : UseInst->operand_values()) {
561 ForwardingDecision OpDecision =
Michael Kruse70af4f52017-08-07 18:40:29 +0000562 forwardTree(TargetStmt, OpVal, DefStmt, DefLoop, DefToTarget, DoIt);
Michael Krusea9a70862017-08-04 12:28:42 +0000563 switch (OpDecision) {
564 case FD_CannotForward:
565 assert(!DoIt);
566 return FD_CannotForward;
567
568 case FD_CanForwardLeaf:
569 case FD_CanForwardTree:
570 assert(!DoIt);
571 break;
572
573 case FD_DidForward:
574 assert(DoIt);
575 break;
576
577 case FD_NotApplicable:
578 llvm_unreachable("forwardTree should never return FD_NotApplicable");
579 }
580 }
581
582 if (DoIt)
583 return FD_DidForward;
584 return FD_CanForwardTree;
585 }
586
Michael Krusea6b2de32017-07-22 14:02:47 +0000587 /// Determines whether an operand tree can be forwarded or carries out a
588 /// forwarding, depending on the @p DoIt flag.
589 ///
Michael Kruse70af4f52017-08-07 18:40:29 +0000590 /// @param TargetStmt The statement the operand tree will be copied to.
591 /// @param UseVal The value (usually an instruction) which is root of an
592 /// operand tree.
593 /// @param UseStmt The statement that uses @p UseVal.
594 /// @param UseLoop The loop @p UseVal is used in.
595 /// @param UseToTarget { DomainUse[] -> DomainTarget[] }
596 /// A mapping from the statement instance @p UseVal is used
597 /// to the statement instance it is forwarded to.
598 /// @param DoIt If false, only determine whether an operand tree can be
599 /// forwarded. If true, carry out the forwarding. Do not
600 /// use DoIt==true if an operand tree is not known to be
601 /// forwardable.
Michael Krusea6b2de32017-07-22 14:02:47 +0000602 ///
Michael Kruse5b8a9092017-07-24 12:39:46 +0000603 /// @return If DoIt==false, return whether the operand tree can be forwarded.
604 /// If DoIt==true, return FD_DidForward.
Michael Kruse70af4f52017-08-07 18:40:29 +0000605 ForwardingDecision forwardTree(ScopStmt *TargetStmt, llvm::Value *UseVal,
606 ScopStmt *UseStmt, llvm::Loop *UseLoop,
607 isl::map UseToTarget, bool DoIt) {
608 ScopStmt *DefStmt = nullptr;
609 Loop *DefLoop = nullptr;
610
611 // { DefDomain[] -> TargetDomain[] }
612 isl::map DefToTarget;
613
Michael Krusea6b2de32017-07-22 14:02:47 +0000614 VirtualUse VUse = VirtualUse::create(UseStmt, UseLoop, UseVal, true);
615 switch (VUse.getKind()) {
616 case VirtualUse::Constant:
617 case VirtualUse::Block:
Michael Krusee5f47062017-07-22 14:30:02 +0000618 case VirtualUse::Hoisted:
Michael Krusea6b2de32017-07-22 14:02:47 +0000619 // These can be used anywhere without special considerations.
620 if (DoIt)
621 return FD_DidForward;
Michael Kruse67752072017-07-24 15:33:58 +0000622 return FD_CanForwardLeaf;
Michael Krusea6b2de32017-07-22 14:02:47 +0000623
Michael Kruse9f6e41c2017-07-31 19:46:21 +0000624 case VirtualUse::Synthesizable: {
625 // ScopExpander will take care for of generating the code at the new
626 // location.
627 if (DoIt)
628 return FD_DidForward;
629
630 // Check if the value is synthesizable at the new location as well. This
631 // might be possible when leaving a loop for which ScalarEvolution is
632 // unable to derive the exit value for.
633 // TODO: If there is a LCSSA PHI at the loop exit, use that one.
634 // If the SCEV contains a SCEVAddRecExpr, we currently depend on that we
635 // do not forward past its loop header. This would require us to use a
636 // previous loop induction variable instead the current one. We currently
637 // do not allow forwarding PHI nodes, thus this should never occur (the
638 // only exception where no phi is necessary being an unreachable loop
639 // without edge from the outside).
640 VirtualUse TargetUse = VirtualUse::create(
641 S, TargetStmt, TargetStmt->getSurroundingLoop(), UseVal, true);
642 if (TargetUse.getKind() == VirtualUse::Synthesizable)
643 return FD_CanForwardLeaf;
644
645 DEBUG(dbgs() << " Synthesizable would not be synthesizable anymore: "
646 << *UseVal << "\n");
Michael Krusea6b2de32017-07-22 14:02:47 +0000647 return FD_CannotForward;
Michael Kruse9f6e41c2017-07-31 19:46:21 +0000648 }
Michael Krusea6b2de32017-07-22 14:02:47 +0000649
Michael Krusea6b2de32017-07-22 14:02:47 +0000650 case VirtualUse::ReadOnly:
Michael Krused85e3452017-07-24 15:33:53 +0000651 // Note that we cannot return FD_CanForwardTree here. With a operand tree
652 // depth of 0, UseVal is the use in TargetStmt that we try to replace.
653 // With -polly-analyze-read-only-scalars=true we would ensure the
654 // existence of a MemoryAccess (which already exists for a leaf) and be
655 // removed again by tryForwardTree because it's goal is to remove this
656 // scalar MemoryAccess. It interprets FD_CanForwardTree as the permission
657 // to do so.
Michael Kruse07e8c362017-07-24 12:43:27 +0000658 if (!DoIt)
Michael Kruse67752072017-07-24 15:33:58 +0000659 return FD_CanForwardLeaf;
Michael Kruse07e8c362017-07-24 12:43:27 +0000660
661 // If we model read-only scalars, we need to create a MemoryAccess for it.
662 if (ModelReadOnlyScalars)
663 TargetStmt->ensureValueRead(UseVal);
664
665 NumReadOnlyCopied++;
666 TotalReadOnlyCopied++;
667 return FD_DidForward;
Michael Krusea6b2de32017-07-22 14:02:47 +0000668
669 case VirtualUse::Intra:
Michael Kruse70af4f52017-08-07 18:40:29 +0000670 // Knowing that UseStmt and DefStmt are the same statement instance, just
671 // reuse the information about UseStmt for DefStmt
672 DefStmt = UseStmt;
673 DefToTarget = UseToTarget;
Michael Krusea6b2de32017-07-22 14:02:47 +0000674
Michael Kruse70af4f52017-08-07 18:40:29 +0000675 LLVM_FALLTHROUGH;
676 case VirtualUse::Inter:
677 Instruction *Inst = cast<Instruction>(UseVal);
678
Michael Krusecd3b9fe2017-08-09 16:45:37 +0000679 if (!DefStmt) {
Michael Kruse70af4f52017-08-07 18:40:29 +0000680 DefStmt = S->getStmtFor(Inst);
Michael Krusecd3b9fe2017-08-09 16:45:37 +0000681 if (!DefStmt)
682 return FD_CannotForward;
683 }
684
Michael Kruse70af4f52017-08-07 18:40:29 +0000685 DefLoop = LI->getLoopFor(Inst->getParent());
686
687 if (DefToTarget.is_null() && !Known.is_null()) {
688 // { UseDomain[] -> DefDomain[] }
689 isl::map UseToDef = computeUseToDefFlowDependency(UseStmt, DefStmt);
690
691 // { DefDomain[] -> UseDomain[] -> TargetDomain[] } shortened to
692 // { DefDomain[] -> TargetDomain[] }
693 DefToTarget = UseToTarget.apply_domain(UseToDef);
694 simplify(DefToTarget);
695 }
696
697 ForwardingDecision SpeculativeResult = forwardSpeculatable(
698 TargetStmt, Inst, DefStmt, DefLoop, DefToTarget, DoIt);
Michael Krusea9a70862017-08-04 12:28:42 +0000699 if (SpeculativeResult != FD_NotApplicable)
700 return SpeculativeResult;
Michael Kruse9f6e41c2017-07-31 19:46:21 +0000701
Michael Kruse70af4f52017-08-07 18:40:29 +0000702 ForwardingDecision KnownResult =
703 forwardKnownLoad(TargetStmt, Inst, UseStmt, UseLoop, UseToTarget,
704 DefStmt, DefLoop, DefToTarget, DoIt);
705 if (KnownResult != FD_NotApplicable)
706 return KnownResult;
707
Michael Krusea9a70862017-08-04 12:28:42 +0000708 // When no method is found to forward the operand tree, we effectively
709 // cannot handle it.
710 DEBUG(dbgs() << " Cannot forward instruction: " << *Inst << "\n");
711 return FD_CannotForward;
Michael Krusea6b2de32017-07-22 14:02:47 +0000712 }
713
714 llvm_unreachable("Case unhandled");
715 }
716
717 /// Try to forward an operand tree rooted in @p RA.
718 bool tryForwardTree(MemoryAccess *RA) {
719 assert(RA->isLatestScalarKind());
720 DEBUG(dbgs() << "Trying to forward operand tree " << RA << "...\n");
721
722 ScopStmt *Stmt = RA->getStatement();
723 Loop *InLoop = Stmt->getSurroundingLoop();
724
Michael Kruse70af4f52017-08-07 18:40:29 +0000725 isl::map TargetToUse;
726 if (!Known.is_null()) {
727 isl::space DomSpace = Stmt->getDomainSpace();
728 TargetToUse =
729 isl::map::identity(DomSpace.map_from_domain_and_range(DomSpace));
730 }
731
732 ForwardingDecision Assessment = forwardTree(
733 Stmt, RA->getAccessValue(), Stmt, InLoop, TargetToUse, false);
Michael Krusea6b2de32017-07-22 14:02:47 +0000734 assert(Assessment != FD_DidForward);
Michael Kruse07e8c362017-07-24 12:43:27 +0000735 if (Assessment != FD_CanForwardTree)
Michael Krusea6b2de32017-07-22 14:02:47 +0000736 return false;
737
Michael Kruse70af4f52017-08-07 18:40:29 +0000738 ForwardingDecision Execution = forwardTree(Stmt, RA->getAccessValue(), Stmt,
739 InLoop, TargetToUse, true);
Michael Krusefd350892017-08-01 22:15:04 +0000740 assert(Execution == FD_DidForward &&
741 "A previous positive assessment must also be executable");
742 (void)Execution;
Michael Krusea6b2de32017-07-22 14:02:47 +0000743
744 Stmt->removeSingleMemoryAccess(RA);
745 return true;
746 }
747
748public:
Michael Kruse70af4f52017-08-07 18:40:29 +0000749 ForwardOpTreeImpl(Scop *S, LoopInfo *LI)
750 : ZoneAlgorithm("polly-optree", S, LI) {}
Michael Krusea6b2de32017-07-22 14:02:47 +0000751
752 /// Return which SCoP this instance is processing.
753 Scop *getScop() const { return S; }
754
755 /// Run the algorithm: Use value read accesses as operand tree roots and try
756 /// to forward them into the statement.
757 bool forwardOperandTrees() {
758 for (ScopStmt &Stmt : *S) {
759 // Currently we cannot modify the instruction list of region statements.
760 if (!Stmt.isBlockStmt())
761 continue;
762
763 bool StmtModified = false;
764
765 // Because we are modifying the MemoryAccess list, collect them first to
766 // avoid iterator invalidation.
767 SmallVector<MemoryAccess *, 16> Accs;
768 for (MemoryAccess *RA : Stmt) {
769 if (!RA->isRead())
770 continue;
771 if (!RA->isLatestScalarKind())
772 continue;
773
774 Accs.push_back(RA);
775 }
776
777 for (MemoryAccess *RA : Accs) {
778 if (tryForwardTree(RA)) {
779 Modified = true;
780 StmtModified = true;
781 NumForwardedTrees++;
782 TotalForwardedTrees++;
783 }
784 }
785
786 if (StmtModified) {
787 NumModifiedStmts++;
788 TotalModifiedStmts++;
789 }
790 }
791
792 if (Modified)
793 ScopsModified++;
794 return Modified;
795 }
796
797 /// Print the pass result, performed transformations and the SCoP after the
798 /// transformation.
799 void print(llvm::raw_ostream &OS, int Indent = 0) {
800 printStatistics(OS, Indent);
801
802 if (!Modified) {
803 // This line can easily be checked in regression tests.
804 OS << "ForwardOpTree executed, but did not modify anything\n";
805 return;
806 }
807
808 printStatements(OS, Indent);
809 }
810};
811
812/// Pass that redirects scalar reads to array elements that are known to contain
813/// the same value.
814///
815/// This reduces the number of scalar accesses and therefore potentially
816/// increases the freedom of the scheduler. In the ideal case, all reads of a
817/// scalar definition are redirected (We currently do not care about removing
818/// the write in this case). This is also useful for the main DeLICM pass as
819/// there are less scalars to be mapped.
820class ForwardOpTree : public ScopPass {
821private:
822 ForwardOpTree(const ForwardOpTree &) = delete;
823 const ForwardOpTree &operator=(const ForwardOpTree &) = delete;
824
825 /// The pass implementation, also holding per-scop data.
826 std::unique_ptr<ForwardOpTreeImpl> Impl;
827
828public:
829 static char ID;
830
831 explicit ForwardOpTree() : ScopPass(ID) {}
832
833 virtual void getAnalysisUsage(AnalysisUsage &AU) const override {
834 AU.addRequiredTransitive<ScopInfoRegionPass>();
835 AU.addRequired<LoopInfoWrapperPass>();
836 AU.setPreservesAll();
837 }
838
839 virtual bool runOnScop(Scop &S) override {
840 // Free resources for previous SCoP's computation, if not yet done.
841 releaseMemory();
842
843 LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
844 Impl = make_unique<ForwardOpTreeImpl>(&S, &LI);
845
Michael Kruse70af4f52017-08-07 18:40:29 +0000846 if (AnalyzeKnown) {
847 DEBUG(dbgs() << "Prepare forwarders...\n");
848 Impl->computeKnownValues();
849 }
850
Michael Krusea6b2de32017-07-22 14:02:47 +0000851 DEBUG(dbgs() << "Forwarding operand trees...\n");
852 Impl->forwardOperandTrees();
853
854 DEBUG(dbgs() << "\nFinal Scop:\n");
855 DEBUG(dbgs() << S);
856
Michael Kruse06ed5292017-08-23 13:50:30 +0000857 // Update statistics
858 auto ScopStats = S.getStatistics();
859 NumValueWrites += ScopStats.NumValueWrites;
860 NumValueWritesInLoops += ScopStats.NumValueWritesInLoops;
861 NumPHIWrites += ScopStats.NumPHIWrites;
862 NumPHIWritesInLoops += ScopStats.NumPHIWritesInLoops;
863 NumSingletonWrites += ScopStats.NumSingletonWrites;
864 NumSingletonWritesInLoops += ScopStats.NumSingletonWritesInLoops;
865
Michael Krusea6b2de32017-07-22 14:02:47 +0000866 return false;
867 }
868
869 virtual void printScop(raw_ostream &OS, Scop &S) const override {
870 if (!Impl)
871 return;
872
873 assert(Impl->getScop() == &S);
874 Impl->print(OS);
875 }
876
877 virtual void releaseMemory() override { Impl.reset(); }
878
879}; // class ForwardOpTree
880
881char ForwardOpTree::ID;
882} // anonymous namespace
883
884ScopPass *polly::createForwardOpTreePass() { return new ForwardOpTree(); }
885
886INITIALIZE_PASS_BEGIN(ForwardOpTree, "polly-optree",
887 "Polly - Forward operand tree", false, false)
888INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
889INITIALIZE_PASS_END(ForwardOpTree, "polly-optree",
890 "Polly - Forward operand tree", false, false)