[AMDGPU] Test codegen'ing True16 additions.
[llvm-project.git] / polly / lib / Transform / Simplify.cpp
blob41a155a41de83d1071b0ff228031c39d5218513b
1 //===------ Simplify.cpp ----------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Simplify a SCoP by removing unnecessary statements and accesses.
11 //===----------------------------------------------------------------------===//
13 #include "polly/Simplify.h"
14 #include "polly/ScopInfo.h"
15 #include "polly/ScopPass.h"
16 #include "polly/Support/GICHelper.h"
17 #include "polly/Support/ISLOStream.h"
18 #include "polly/Support/ISLTools.h"
19 #include "polly/Support/VirtualInstruction.h"
20 #include "llvm/ADT/Statistic.h"
21 #include "llvm/InitializePasses.h"
22 #include "llvm/Support/Debug.h"
23 #include <optional>
25 #define DEBUG_TYPE "polly-simplify"
27 using namespace llvm;
28 using namespace polly;
30 namespace {
32 #define TWO_STATISTICS(VARNAME, DESC) \
33 static llvm::Statistic VARNAME[2] = { \
34 {DEBUG_TYPE, #VARNAME "0", DESC " (first)"}, \
35 {DEBUG_TYPE, #VARNAME "1", DESC " (second)"}}
37 /// Number of max disjuncts we allow in removeOverwrites(). This is to avoid
38 /// that the analysis of accesses in a statement is becoming too complex. Chosen
39 /// to be relatively small because all the common cases should access only few
40 /// array elements per statement.
41 static unsigned const SimplifyMaxDisjuncts = 4;
43 TWO_STATISTICS(ScopsProcessed, "Number of SCoPs processed");
44 TWO_STATISTICS(ScopsModified, "Number of SCoPs simplified");
46 TWO_STATISTICS(TotalEmptyDomainsRemoved,
47 "Number of statement with empty domains removed in any SCoP");
48 TWO_STATISTICS(TotalOverwritesRemoved, "Number of removed overwritten writes");
49 TWO_STATISTICS(TotalWritesCoalesced, "Number of writes coalesced with another");
50 TWO_STATISTICS(TotalRedundantWritesRemoved,
51 "Number of writes of same value removed in any SCoP");
52 TWO_STATISTICS(TotalEmptyPartialAccessesRemoved,
53 "Number of empty partial accesses removed");
54 TWO_STATISTICS(TotalDeadAccessesRemoved, "Number of dead accesses removed");
55 TWO_STATISTICS(TotalDeadInstructionsRemoved,
56 "Number of unused instructions removed");
57 TWO_STATISTICS(TotalStmtsRemoved, "Number of statements removed in any SCoP");
59 TWO_STATISTICS(NumValueWrites, "Number of scalar value writes after Simplify");
60 TWO_STATISTICS(
61 NumValueWritesInLoops,
62 "Number of scalar value writes nested in affine loops after Simplify");
63 TWO_STATISTICS(NumPHIWrites,
64 "Number of scalar phi writes after the first simplification");
65 TWO_STATISTICS(
66 NumPHIWritesInLoops,
67 "Number of scalar phi writes nested in affine loops after Simplify");
68 TWO_STATISTICS(NumSingletonWrites, "Number of singleton writes after Simplify");
69 TWO_STATISTICS(
70 NumSingletonWritesInLoops,
71 "Number of singleton writes nested in affine loops after Simplify");
73 static bool isImplicitRead(MemoryAccess *MA) {
74 return MA->isRead() && MA->isOriginalScalarKind();
77 static bool isExplicitAccess(MemoryAccess *MA) {
78 return MA->isOriginalArrayKind();
81 static bool isImplicitWrite(MemoryAccess *MA) {
82 return MA->isWrite() && MA->isOriginalScalarKind();
85 /// Like isl::union_map::unite, but may also return an underapproximated
86 /// result if getting too complex.
87 ///
88 /// This is implemented by adding disjuncts to the results until the limit is
89 /// reached.
90 static isl::union_map underapproximatedAddMap(isl::union_map UMap,
91 isl::map Map) {
92 if (UMap.is_null() || Map.is_null())
93 return {};
95 isl::map PrevMap = UMap.extract_map(Map.get_space());
97 // Fast path: If known that we cannot exceed the disjunct limit, just add
98 // them.
99 if (unsignedFromIslSize(PrevMap.n_basic_map()) +
100 unsignedFromIslSize(Map.n_basic_map()) <=
101 SimplifyMaxDisjuncts)
102 return UMap.unite(Map);
104 isl::map Result = isl::map::empty(PrevMap.get_space());
105 for (isl::basic_map BMap : PrevMap.get_basic_map_list()) {
106 if (unsignedFromIslSize(Result.n_basic_map()) > SimplifyMaxDisjuncts)
107 break;
108 Result = Result.unite(BMap);
110 for (isl::basic_map BMap : Map.get_basic_map_list()) {
111 if (unsignedFromIslSize(Result.n_basic_map()) > SimplifyMaxDisjuncts)
112 break;
113 Result = Result.unite(BMap);
116 isl::union_map UResult =
117 UMap.subtract(isl::map::universe(PrevMap.get_space()));
118 UResult.unite(Result);
120 return UResult;
123 class SimplifyImpl final {
124 private:
125 /// The invocation id (if there are multiple instances in the pass manager's
126 /// pipeline) to determine which statistics to update.
127 int CallNo;
129 /// The last/current SCoP that is/has been processed.
130 Scop *S = nullptr;
132 /// Number of statements with empty domains removed from the SCoP.
133 int EmptyDomainsRemoved = 0;
135 /// Number of writes that are overwritten anyway.
136 int OverwritesRemoved = 0;
138 /// Number of combined writes.
139 int WritesCoalesced = 0;
141 /// Number of redundant writes removed from this SCoP.
142 int RedundantWritesRemoved = 0;
144 /// Number of writes with empty access domain removed.
145 int EmptyPartialAccessesRemoved = 0;
147 /// Number of unused accesses removed from this SCoP.
148 int DeadAccessesRemoved = 0;
150 /// Number of unused instructions removed from this SCoP.
151 int DeadInstructionsRemoved = 0;
153 /// Number of unnecessary statements removed from the SCoP.
154 int StmtsRemoved = 0;
156 /// Remove statements that are never executed due to their domains being
157 /// empty.
159 /// In contrast to Scop::simplifySCoP, this removes based on the SCoP's
160 /// effective domain, i.e. including the SCoP's context as used by some other
161 /// simplification methods in this pass. This is necessary because the
162 /// analysis on empty domains is unreliable, e.g. remove a scalar value
163 /// definition MemoryAccesses, but not its use.
164 void removeEmptyDomainStmts();
166 /// Remove writes that are overwritten unconditionally later in the same
167 /// statement.
169 /// There must be no read of the same value between the write (that is to be
170 /// removed) and the overwrite.
171 void removeOverwrites();
173 /// Combine writes that write the same value if possible.
175 /// This function is able to combine:
176 /// - Partial writes with disjoint domain.
177 /// - Writes that write to the same array element.
179 /// In all cases, both writes must write the same values.
180 void coalesceWrites();
182 /// Remove writes that just write the same value already stored in the
183 /// element.
184 void removeRedundantWrites();
186 /// Remove statements without side effects.
187 void removeUnnecessaryStmts();
189 /// Remove accesses that have an empty domain.
190 void removeEmptyPartialAccesses();
192 /// Mark all reachable instructions and access, and sweep those that are not
193 /// reachable.
194 void markAndSweep(LoopInfo *LI);
196 /// Print simplification statistics to @p OS.
197 void printStatistics(llvm::raw_ostream &OS, int Indent = 0) const;
199 /// Print the current state of all MemoryAccesses to @p OS.
200 void printAccesses(llvm::raw_ostream &OS, int Indent = 0) const;
202 public:
203 explicit SimplifyImpl(int CallNo = 0) : CallNo(CallNo) {}
205 void run(Scop &S, LoopInfo *LI);
207 void printScop(raw_ostream &OS, Scop &S) const;
209 /// Return whether at least one simplification has been applied.
210 bool isModified() const;
213 /// Return whether at least one simplification has been applied.
214 bool SimplifyImpl::isModified() const {
215 return EmptyDomainsRemoved > 0 || OverwritesRemoved > 0 ||
216 WritesCoalesced > 0 || RedundantWritesRemoved > 0 ||
217 EmptyPartialAccessesRemoved > 0 || DeadAccessesRemoved > 0 ||
218 DeadInstructionsRemoved > 0 || StmtsRemoved > 0;
221 /// Remove statements that are never executed due to their domains being
222 /// empty.
224 /// In contrast to Scop::simplifySCoP, this removes based on the SCoP's
225 /// effective domain, i.e. including the SCoP's context as used by some other
226 /// simplification methods in this pass. This is necessary because the
227 /// analysis on empty domains is unreliable, e.g. remove a scalar value
228 /// definition MemoryAccesses, but not its use.
229 void SimplifyImpl::removeEmptyDomainStmts() {
230 size_t NumStmtsBefore = S->getSize();
232 S->removeStmts([](ScopStmt &Stmt) -> bool {
233 auto EffectiveDomain =
234 Stmt.getDomain().intersect_params(Stmt.getParent()->getContext());
235 return EffectiveDomain.is_empty();
238 assert(NumStmtsBefore >= S->getSize());
239 EmptyDomainsRemoved = NumStmtsBefore - S->getSize();
240 LLVM_DEBUG(dbgs() << "Removed " << EmptyDomainsRemoved << " (of "
241 << NumStmtsBefore << ") statements with empty domains \n");
242 TotalEmptyDomainsRemoved[CallNo] += EmptyDomainsRemoved;
245 /// Remove writes that are overwritten unconditionally later in the same
246 /// statement.
248 /// There must be no read of the same value between the write (that is to be
249 /// removed) and the overwrite.
250 void SimplifyImpl::removeOverwrites() {
251 for (auto &Stmt : *S) {
252 isl::set Domain = Stmt.getDomain();
253 isl::union_map WillBeOverwritten = isl::union_map::empty(S->getIslCtx());
255 SmallVector<MemoryAccess *, 32> Accesses(getAccessesInOrder(Stmt));
257 // Iterate in reverse order, so the overwrite comes before the write that
258 // is to be removed.
259 for (auto *MA : reverse(Accesses)) {
261 // In region statements, the explicit accesses can be in blocks that are
262 // can be executed in any order. We therefore process only the implicit
263 // writes and stop after that.
264 if (Stmt.isRegionStmt() && isExplicitAccess(MA))
265 break;
267 auto AccRel = MA->getAccessRelation();
268 AccRel = AccRel.intersect_domain(Domain);
269 AccRel = AccRel.intersect_params(S->getContext());
271 // If a value is read in-between, do not consider it as overwritten.
272 if (MA->isRead()) {
273 // Invalidate all overwrites for the array it accesses to avoid too
274 // complex isl sets.
275 isl::map AccRelUniv = isl::map::universe(AccRel.get_space());
276 WillBeOverwritten = WillBeOverwritten.subtract(AccRelUniv);
277 continue;
280 // If all of a write's elements are overwritten, remove it.
281 isl::union_map AccRelUnion = AccRel;
282 if (AccRelUnion.is_subset(WillBeOverwritten)) {
283 LLVM_DEBUG(dbgs() << "Removing " << MA
284 << " which will be overwritten anyway\n");
286 Stmt.removeSingleMemoryAccess(MA);
287 OverwritesRemoved++;
288 TotalOverwritesRemoved[CallNo]++;
291 // Unconditional writes overwrite other values.
292 if (MA->isMustWrite()) {
293 // Avoid too complex isl sets. If necessary, throw away some of the
294 // knowledge.
295 WillBeOverwritten = underapproximatedAddMap(WillBeOverwritten, AccRel);
301 /// Combine writes that write the same value if possible.
303 /// This function is able to combine:
304 /// - Partial writes with disjoint domain.
305 /// - Writes that write to the same array element.
307 /// In all cases, both writes must write the same values.
308 void SimplifyImpl::coalesceWrites() {
309 for (auto &Stmt : *S) {
310 isl::set Domain = Stmt.getDomain().intersect_params(S->getContext());
312 // We let isl do the lookup for the same-value condition. For this, we
313 // wrap llvm::Value into an isl::set such that isl can do the lookup in
314 // its hashtable implementation. llvm::Values are only compared within a
315 // ScopStmt, so the map can be local to this scope. TODO: Refactor with
316 // ZoneAlgorithm::makeValueSet()
317 SmallDenseMap<Value *, isl::set> ValueSets;
318 auto makeValueSet = [&ValueSets, this](Value *V) -> isl::set {
319 assert(V);
320 isl::set &Result = ValueSets[V];
321 if (Result.is_null()) {
322 isl::ctx Ctx = S->getIslCtx();
323 std::string Name = getIslCompatibleName(
324 "Val", V, ValueSets.size() - 1, std::string(), UseInstructionNames);
325 isl::id Id = isl::id::alloc(Ctx, Name, V);
326 Result = isl::set::universe(
327 isl::space(Ctx, 0, 0).set_tuple_id(isl::dim::set, Id));
329 return Result;
332 // List of all eligible (for coalescing) writes of the future.
333 // { [Domain[] -> Element[]] -> [Value[] -> MemoryAccess[]] }
334 isl::union_map FutureWrites = isl::union_map::empty(S->getIslCtx());
336 // Iterate over accesses from the last to the first.
337 SmallVector<MemoryAccess *, 32> Accesses(getAccessesInOrder(Stmt));
338 for (MemoryAccess *MA : reverse(Accesses)) {
339 // In region statements, the explicit accesses can be in blocks that can
340 // be executed in any order. We therefore process only the implicit
341 // writes and stop after that.
342 if (Stmt.isRegionStmt() && isExplicitAccess(MA))
343 break;
345 // { Domain[] -> Element[] }
346 isl::map AccRel = MA->getLatestAccessRelation().intersect_domain(Domain);
348 // { [Domain[] -> Element[]] }
349 isl::set AccRelWrapped = AccRel.wrap();
351 // { Value[] }
352 isl::set ValSet;
354 if (MA->isMustWrite() && (MA->isOriginalScalarKind() ||
355 isa<StoreInst>(MA->getAccessInstruction()))) {
356 // Normally, tryGetValueStored() should be used to determine which
357 // element is written, but it can return nullptr; For PHI accesses,
358 // getAccessValue() returns the PHI instead of the PHI's incoming
359 // value. In this case, where we only compare values of a single
360 // statement, this is fine, because within a statement, a PHI in a
361 // successor block has always the same value as the incoming write. We
362 // still preferably use the incoming value directly so we also catch
363 // direct uses of that.
364 Value *StoredVal = MA->tryGetValueStored();
365 if (!StoredVal)
366 StoredVal = MA->getAccessValue();
367 ValSet = makeValueSet(StoredVal);
369 // { Domain[] }
370 isl::set AccDomain = AccRel.domain();
372 // Parts of the statement's domain that is not written by this access.
373 isl::set UndefDomain = Domain.subtract(AccDomain);
375 // { Element[] }
376 isl::set ElementUniverse =
377 isl::set::universe(AccRel.get_space().range());
379 // { Domain[] -> Element[] }
380 isl::map UndefAnything =
381 isl::map::from_domain_and_range(UndefDomain, ElementUniverse);
383 // We are looking a compatible write access. The other write can
384 // access these elements...
385 isl::map AllowedAccesses = AccRel.unite(UndefAnything);
387 // ... and must write the same value.
388 // { [Domain[] -> Element[]] -> Value[] }
389 isl::map Filter =
390 isl::map::from_domain_and_range(AllowedAccesses.wrap(), ValSet);
392 // Lookup future write that fulfills these conditions.
393 // { [[Domain[] -> Element[]] -> Value[]] -> MemoryAccess[] }
394 isl::union_map Filtered =
395 FutureWrites.uncurry().intersect_domain(Filter.wrap());
397 // Iterate through the candidates.
398 for (isl::map Map : Filtered.get_map_list()) {
399 MemoryAccess *OtherMA = (MemoryAccess *)Map.get_space()
400 .get_tuple_id(isl::dim::out)
401 .get_user();
403 isl::map OtherAccRel =
404 OtherMA->getLatestAccessRelation().intersect_domain(Domain);
406 // The filter only guaranteed that some of OtherMA's accessed
407 // elements are allowed. Verify that it only accesses allowed
408 // elements. Otherwise, continue with the next candidate.
409 if (!OtherAccRel.is_subset(AllowedAccesses).is_true())
410 continue;
412 // The combined access relation.
413 // { Domain[] -> Element[] }
414 isl::map NewAccRel = AccRel.unite(OtherAccRel);
415 simplify(NewAccRel);
417 // Carry out the coalescing.
418 Stmt.removeSingleMemoryAccess(MA);
419 OtherMA->setNewAccessRelation(NewAccRel);
421 // We removed MA, OtherMA takes its role.
422 MA = OtherMA;
424 TotalWritesCoalesced[CallNo]++;
425 WritesCoalesced++;
427 // Don't look for more candidates.
428 break;
432 // Two writes cannot be coalesced if there is another access (to some of
433 // the written elements) between them. Remove all visited write accesses
434 // from the list of eligible writes. Don't just remove the accessed
435 // elements, but any MemoryAccess that touches any of the invalidated
436 // elements.
437 SmallPtrSet<MemoryAccess *, 2> TouchedAccesses;
438 for (isl::map Map :
439 FutureWrites.intersect_domain(AccRelWrapped).get_map_list()) {
440 MemoryAccess *MA = (MemoryAccess *)Map.get_space()
441 .range()
442 .unwrap()
443 .get_tuple_id(isl::dim::out)
444 .get_user();
445 TouchedAccesses.insert(MA);
447 isl::union_map NewFutureWrites =
448 isl::union_map::empty(FutureWrites.ctx());
449 for (isl::map FutureWrite : FutureWrites.get_map_list()) {
450 MemoryAccess *MA = (MemoryAccess *)FutureWrite.get_space()
451 .range()
452 .unwrap()
453 .get_tuple_id(isl::dim::out)
454 .get_user();
455 if (!TouchedAccesses.count(MA))
456 NewFutureWrites = NewFutureWrites.unite(FutureWrite);
458 FutureWrites = NewFutureWrites;
460 if (MA->isMustWrite() && !ValSet.is_null()) {
461 // { MemoryAccess[] }
462 auto AccSet =
463 isl::set::universe(isl::space(S->getIslCtx(), 0, 0)
464 .set_tuple_id(isl::dim::set, MA->getId()));
466 // { Val[] -> MemoryAccess[] }
467 isl::map ValAccSet = isl::map::from_domain_and_range(ValSet, AccSet);
469 // { [Domain[] -> Element[]] -> [Value[] -> MemoryAccess[]] }
470 isl::map AccRelValAcc =
471 isl::map::from_domain_and_range(AccRelWrapped, ValAccSet.wrap());
472 FutureWrites = FutureWrites.unite(AccRelValAcc);
478 /// Remove writes that just write the same value already stored in the
479 /// element.
480 void SimplifyImpl::removeRedundantWrites() {
481 for (auto &Stmt : *S) {
482 SmallDenseMap<Value *, isl::set> ValueSets;
483 auto makeValueSet = [&ValueSets, this](Value *V) -> isl::set {
484 assert(V);
485 isl::set &Result = ValueSets[V];
486 if (Result.is_null()) {
487 isl_ctx *Ctx = S->getIslCtx().get();
488 std::string Name = getIslCompatibleName(
489 "Val", V, ValueSets.size() - 1, std::string(), UseInstructionNames);
490 isl::id Id = isl::manage(isl_id_alloc(Ctx, Name.c_str(), V));
491 Result = isl::set::universe(
492 isl::space(Ctx, 0, 0).set_tuple_id(isl::dim::set, Id));
494 return Result;
497 isl::set Domain = Stmt.getDomain();
498 Domain = Domain.intersect_params(S->getContext());
500 // List of element reads that still have the same value while iterating
501 // through the MemoryAccesses.
502 // { [Domain[] -> Element[]] -> Val[] }
503 isl::union_map Known = isl::union_map::empty(S->getIslCtx());
505 SmallVector<MemoryAccess *, 32> Accesses(getAccessesInOrder(Stmt));
506 for (MemoryAccess *MA : Accesses) {
507 // Is the memory access in a defined order relative to the other
508 // accesses? In region statements, only the first and the last accesses
509 // have defined order. Execution of those in the middle may depend on
510 // runtime conditions an therefore cannot be modified.
511 bool IsOrdered =
512 Stmt.isBlockStmt() || MA->isOriginalScalarKind() ||
513 (!S->getBoxedLoops().size() && MA->getAccessInstruction() &&
514 Stmt.getEntryBlock() == MA->getAccessInstruction()->getParent());
516 isl::map AccRel = MA->getAccessRelation();
517 AccRel = AccRel.intersect_domain(Domain);
518 isl::set AccRelWrapped = AccRel.wrap();
520 // Determine whether a write is redundant (stores only values that are
521 // already present in the written array elements) and remove it if this
522 // is the case.
523 if (IsOrdered && MA->isMustWrite() &&
524 (isa<StoreInst>(MA->getAccessInstruction()) ||
525 MA->isOriginalScalarKind())) {
526 Value *StoredVal = MA->tryGetValueStored();
527 if (!StoredVal)
528 StoredVal = MA->getAccessValue();
530 if (StoredVal) {
531 // Lookup in the set of known values.
532 isl::map AccRelStoredVal = isl::map::from_domain_and_range(
533 AccRelWrapped, makeValueSet(StoredVal));
534 if (isl::union_map(AccRelStoredVal).is_subset(Known)) {
535 LLVM_DEBUG(dbgs() << "Cleanup of " << MA << ":\n");
536 LLVM_DEBUG(dbgs() << " Scalar: " << *StoredVal << "\n");
537 LLVM_DEBUG(dbgs() << " AccRel: " << AccRel << "\n");
539 Stmt.removeSingleMemoryAccess(MA);
541 RedundantWritesRemoved++;
542 TotalRedundantWritesRemoved[CallNo]++;
547 // Update the know values set.
548 if (MA->isRead()) {
549 // Loaded values are the currently known values of the array element
550 // it was loaded from.
551 Value *LoadedVal = MA->getAccessValue();
552 if (LoadedVal && IsOrdered) {
553 isl::map AccRelVal = isl::map::from_domain_and_range(
554 AccRelWrapped, makeValueSet(LoadedVal));
556 Known = Known.unite(AccRelVal);
558 } else if (MA->isWrite()) {
559 // Remove (possibly) overwritten values from the known elements set.
560 // We remove all elements of the accessed array to avoid too complex
561 // isl sets.
562 isl::set AccRelUniv = isl::set::universe(AccRelWrapped.get_space());
563 Known = Known.subtract_domain(AccRelUniv);
565 // At this point, we could add the written value of must-writes.
566 // However, writing same values is already handled by
567 // coalesceWrites().
573 /// Remove statements without side effects.
574 void SimplifyImpl::removeUnnecessaryStmts() {
575 auto NumStmtsBefore = S->getSize();
576 S->simplifySCoP(true);
577 assert(NumStmtsBefore >= S->getSize());
578 StmtsRemoved = NumStmtsBefore - S->getSize();
579 LLVM_DEBUG(dbgs() << "Removed " << StmtsRemoved << " (of " << NumStmtsBefore
580 << ") statements\n");
581 TotalStmtsRemoved[CallNo] += StmtsRemoved;
584 /// Remove accesses that have an empty domain.
585 void SimplifyImpl::removeEmptyPartialAccesses() {
586 for (ScopStmt &Stmt : *S) {
587 // Defer the actual removal to not invalidate iterators.
588 SmallVector<MemoryAccess *, 8> DeferredRemove;
590 for (MemoryAccess *MA : Stmt) {
591 if (!MA->isWrite())
592 continue;
594 isl::map AccRel = MA->getAccessRelation();
595 if (!AccRel.is_empty().is_true())
596 continue;
598 LLVM_DEBUG(
599 dbgs() << "Removing " << MA
600 << " because it's a partial access that never occurs\n");
601 DeferredRemove.push_back(MA);
604 for (MemoryAccess *MA : DeferredRemove) {
605 Stmt.removeSingleMemoryAccess(MA);
606 EmptyPartialAccessesRemoved++;
607 TotalEmptyPartialAccessesRemoved[CallNo]++;
612 /// Mark all reachable instructions and access, and sweep those that are not
613 /// reachable.
614 void SimplifyImpl::markAndSweep(LoopInfo *LI) {
615 DenseSet<MemoryAccess *> UsedMA;
616 DenseSet<VirtualInstruction> UsedInsts;
618 // Get all reachable instructions and accesses.
619 markReachable(S, LI, UsedInsts, UsedMA);
621 // Remove all non-reachable accesses.
622 // We need get all MemoryAccesses first, in order to not invalidate the
623 // iterators when removing them.
624 SmallVector<MemoryAccess *, 64> AllMAs;
625 for (ScopStmt &Stmt : *S)
626 AllMAs.append(Stmt.begin(), Stmt.end());
628 for (MemoryAccess *MA : AllMAs) {
629 if (UsedMA.count(MA))
630 continue;
631 LLVM_DEBUG(dbgs() << "Removing " << MA
632 << " because its value is not used\n");
633 ScopStmt *Stmt = MA->getStatement();
634 Stmt->removeSingleMemoryAccess(MA);
636 DeadAccessesRemoved++;
637 TotalDeadAccessesRemoved[CallNo]++;
640 // Remove all non-reachable instructions.
641 for (ScopStmt &Stmt : *S) {
642 // Note that for region statements, we can only remove the non-terminator
643 // instructions of the entry block. All other instructions are not in the
644 // instructions list, but implicitly always part of the statement.
646 SmallVector<Instruction *, 32> AllInsts(Stmt.insts_begin(),
647 Stmt.insts_end());
648 SmallVector<Instruction *, 32> RemainInsts;
650 for (Instruction *Inst : AllInsts) {
651 auto It = UsedInsts.find({&Stmt, Inst});
652 if (It == UsedInsts.end()) {
653 LLVM_DEBUG(dbgs() << "Removing "; Inst->print(dbgs());
654 dbgs() << " because it is not used\n");
655 DeadInstructionsRemoved++;
656 TotalDeadInstructionsRemoved[CallNo]++;
657 continue;
660 RemainInsts.push_back(Inst);
662 // If instructions appear multiple times, keep only the first.
663 UsedInsts.erase(It);
666 // Set the new instruction list to be only those we did not remove.
667 Stmt.setInstructions(RemainInsts);
671 /// Print simplification statistics to @p OS.
672 void SimplifyImpl::printStatistics(llvm::raw_ostream &OS, int Indent) const {
673 OS.indent(Indent) << "Statistics {\n";
674 OS.indent(Indent + 4) << "Empty domains removed: " << EmptyDomainsRemoved
675 << '\n';
676 OS.indent(Indent + 4) << "Overwrites removed: " << OverwritesRemoved << '\n';
677 OS.indent(Indent + 4) << "Partial writes coalesced: " << WritesCoalesced
678 << "\n";
679 OS.indent(Indent + 4) << "Redundant writes removed: "
680 << RedundantWritesRemoved << "\n";
681 OS.indent(Indent + 4) << "Accesses with empty domains removed: "
682 << EmptyPartialAccessesRemoved << "\n";
683 OS.indent(Indent + 4) << "Dead accesses removed: " << DeadAccessesRemoved
684 << '\n';
685 OS.indent(Indent + 4) << "Dead instructions removed: "
686 << DeadInstructionsRemoved << '\n';
687 OS.indent(Indent + 4) << "Stmts removed: " << StmtsRemoved << "\n";
688 OS.indent(Indent) << "}\n";
691 /// Print the current state of all MemoryAccesses to @p OS.
692 void SimplifyImpl::printAccesses(llvm::raw_ostream &OS, int Indent) const {
693 OS.indent(Indent) << "After accesses {\n";
694 for (auto &Stmt : *S) {
695 OS.indent(Indent + 4) << Stmt.getBaseName() << "\n";
696 for (auto *MA : Stmt)
697 MA->print(OS);
699 OS.indent(Indent) << "}\n";
702 void SimplifyImpl::run(Scop &S, LoopInfo *LI) {
703 // Must not have run before.
704 assert(!this->S);
705 assert(!isModified());
707 // Prepare processing of this SCoP.
708 this->S = &S;
709 ScopsProcessed[CallNo]++;
711 LLVM_DEBUG(dbgs() << "Removing statements that are never executed...\n");
712 removeEmptyDomainStmts();
714 LLVM_DEBUG(dbgs() << "Removing partial writes that never happen...\n");
715 removeEmptyPartialAccesses();
717 LLVM_DEBUG(dbgs() << "Removing overwrites...\n");
718 removeOverwrites();
720 LLVM_DEBUG(dbgs() << "Coalesce partial writes...\n");
721 coalesceWrites();
723 LLVM_DEBUG(dbgs() << "Removing redundant writes...\n");
724 removeRedundantWrites();
726 LLVM_DEBUG(dbgs() << "Cleanup unused accesses...\n");
727 markAndSweep(LI);
729 LLVM_DEBUG(dbgs() << "Removing statements without side effects...\n");
730 removeUnnecessaryStmts();
732 if (isModified())
733 ScopsModified[CallNo]++;
734 LLVM_DEBUG(dbgs() << "\nFinal Scop:\n");
735 LLVM_DEBUG(dbgs() << S);
737 auto ScopStats = S.getStatistics();
738 NumValueWrites[CallNo] += ScopStats.NumValueWrites;
739 NumValueWritesInLoops[CallNo] += ScopStats.NumValueWritesInLoops;
740 NumPHIWrites[CallNo] += ScopStats.NumPHIWrites;
741 NumPHIWritesInLoops[CallNo] += ScopStats.NumPHIWritesInLoops;
742 NumSingletonWrites[CallNo] += ScopStats.NumSingletonWrites;
743 NumSingletonWritesInLoops[CallNo] += ScopStats.NumSingletonWritesInLoops;
746 void SimplifyImpl::printScop(raw_ostream &OS, Scop &S) const {
747 assert(&S == this->S &&
748 "Can only print analysis for the last processed SCoP");
749 printStatistics(OS);
751 if (!isModified()) {
752 OS << "SCoP could not be simplified\n";
753 return;
755 printAccesses(OS);
758 class SimplifyWrapperPass final : public ScopPass {
759 public:
760 static char ID;
761 int CallNo;
762 std::optional<SimplifyImpl> Impl;
764 explicit SimplifyWrapperPass(int CallNo = 0) : ScopPass(ID), CallNo(CallNo) {}
766 void getAnalysisUsage(AnalysisUsage &AU) const override {
767 AU.addRequiredTransitive<ScopInfoRegionPass>();
768 AU.addRequired<LoopInfoWrapperPass>();
769 AU.setPreservesAll();
772 bool runOnScop(Scop &S) override {
773 LoopInfo *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
775 Impl.emplace(CallNo);
776 Impl->run(S, LI);
778 return false;
781 void printScop(raw_ostream &OS, Scop &S) const override {
782 if (Impl)
783 Impl->printScop(OS, S);
786 void releaseMemory() override { Impl.reset(); }
789 char SimplifyWrapperPass::ID;
791 static llvm::PreservedAnalyses
792 runSimplifyUsingNPM(Scop &S, ScopAnalysisManager &SAM,
793 ScopStandardAnalysisResults &SAR, SPMUpdater &U, int CallNo,
794 raw_ostream *OS) {
795 SimplifyImpl Impl(CallNo);
796 Impl.run(S, &SAR.LI);
797 if (OS) {
798 *OS << "Printing analysis 'Polly - Simplify' for region: '" << S.getName()
799 << "' in function '" << S.getFunction().getName() << "':\n";
800 Impl.printScop(*OS, S);
803 if (!Impl.isModified())
804 return llvm::PreservedAnalyses::all();
806 PreservedAnalyses PA;
807 PA.preserveSet<AllAnalysesOn<Module>>();
808 PA.preserveSet<AllAnalysesOn<Function>>();
809 PA.preserveSet<AllAnalysesOn<Loop>>();
810 return PA;
813 } // anonymous namespace
815 llvm::PreservedAnalyses SimplifyPass::run(Scop &S, ScopAnalysisManager &SAM,
816 ScopStandardAnalysisResults &SAR,
817 SPMUpdater &U) {
818 return runSimplifyUsingNPM(S, SAM, SAR, U, CallNo, nullptr);
821 llvm::PreservedAnalyses
822 SimplifyPrinterPass::run(Scop &S, ScopAnalysisManager &SAM,
823 ScopStandardAnalysisResults &SAR, SPMUpdater &U) {
824 return runSimplifyUsingNPM(S, SAM, SAR, U, CallNo, &OS);
827 SmallVector<MemoryAccess *, 32> polly::getAccessesInOrder(ScopStmt &Stmt) {
828 SmallVector<MemoryAccess *, 32> Accesses;
830 for (MemoryAccess *MemAcc : Stmt)
831 if (isImplicitRead(MemAcc))
832 Accesses.push_back(MemAcc);
834 for (MemoryAccess *MemAcc : Stmt)
835 if (isExplicitAccess(MemAcc))
836 Accesses.push_back(MemAcc);
838 for (MemoryAccess *MemAcc : Stmt)
839 if (isImplicitWrite(MemAcc))
840 Accesses.push_back(MemAcc);
842 return Accesses;
845 Pass *polly::createSimplifyWrapperPass(int CallNo) {
846 return new SimplifyWrapperPass(CallNo);
849 INITIALIZE_PASS_BEGIN(SimplifyWrapperPass, "polly-simplify", "Polly - Simplify",
850 false, false)
851 INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
852 INITIALIZE_PASS_END(SimplifyWrapperPass, "polly-simplify", "Polly - Simplify",
853 false, false)
855 //===----------------------------------------------------------------------===//
857 namespace {
858 /// Print result from SimplifyWrapperPass.
859 class SimplifyPrinterLegacyPass final : public ScopPass {
860 public:
861 static char ID;
863 SimplifyPrinterLegacyPass() : SimplifyPrinterLegacyPass(outs()) {}
864 explicit SimplifyPrinterLegacyPass(llvm::raw_ostream &OS)
865 : ScopPass(ID), OS(OS) {}
867 bool runOnScop(Scop &S) override {
868 SimplifyWrapperPass &P = getAnalysis<SimplifyWrapperPass>();
870 OS << "Printing analysis '" << P.getPassName() << "' for region: '"
871 << S.getRegion().getNameStr() << "' in function '"
872 << S.getFunction().getName() << "':\n";
873 P.printScop(OS, S);
875 return false;
878 void getAnalysisUsage(AnalysisUsage &AU) const override {
879 ScopPass::getAnalysisUsage(AU);
880 AU.addRequired<SimplifyWrapperPass>();
881 AU.setPreservesAll();
884 private:
885 llvm::raw_ostream &OS;
888 char SimplifyPrinterLegacyPass::ID = 0;
889 } // namespace
891 Pass *polly::createSimplifyPrinterLegacyPass(raw_ostream &OS) {
892 return new SimplifyPrinterLegacyPass(OS);
895 INITIALIZE_PASS_BEGIN(SimplifyPrinterLegacyPass, "polly-print-simplify",
896 "Polly - Print Simplify actions", false, false)
897 INITIALIZE_PASS_DEPENDENCY(SimplifyWrapperPass)
898 INITIALIZE_PASS_END(SimplifyPrinterLegacyPass, "polly-print-simplify",
899 "Polly - Print Simplify actions", false, false)