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.
10 //
11 //===----------------------------------------------------------------------===//
12 
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 #define DEBUG_TYPE "polly-simplify"
24 
25 using namespace llvm;
26 using namespace polly;
27 
28 namespace {
29 
30 #define TWO_STATISTICS(VARNAME, DESC)                                          \
31   static llvm::Statistic VARNAME[2] = {                                        \
32       {DEBUG_TYPE, #VARNAME "0", DESC " (first)"},                             \
33       {DEBUG_TYPE, #VARNAME "1", DESC " (second)"}}
34 
35 /// Number of max disjuncts we allow in removeOverwrites(). This is to avoid
36 /// that the analysis of accesses in a statement is becoming too complex. Chosen
37 /// to be relatively small because all the common cases should access only few
38 /// array elements per statement.
39 static int const SimplifyMaxDisjuncts = 4;
40 
41 TWO_STATISTICS(ScopsProcessed, "Number of SCoPs processed");
42 TWO_STATISTICS(ScopsModified, "Number of SCoPs simplified");
43 
44 TWO_STATISTICS(TotalEmptyDomainsRemoved,
45                "Number of statement with empty domains removed in any SCoP");
46 TWO_STATISTICS(TotalOverwritesRemoved, "Number of removed overwritten writes");
47 TWO_STATISTICS(TotalWritesCoalesced, "Number of writes coalesced with another");
48 TWO_STATISTICS(TotalRedundantWritesRemoved,
49                "Number of writes of same value removed in any SCoP");
50 TWO_STATISTICS(TotalEmptyPartialAccessesRemoved,
51                "Number of empty partial accesses removed");
52 TWO_STATISTICS(TotalDeadAccessesRemoved, "Number of dead accesses removed");
53 TWO_STATISTICS(TotalDeadInstructionsRemoved,
54                "Number of unused instructions removed");
55 TWO_STATISTICS(TotalStmtsRemoved, "Number of statements removed in any SCoP");
56 
57 TWO_STATISTICS(NumValueWrites, "Number of scalar value writes after Simplify");
58 TWO_STATISTICS(
59     NumValueWritesInLoops,
60     "Number of scalar value writes nested in affine loops after Simplify");
61 TWO_STATISTICS(NumPHIWrites,
62                "Number of scalar phi writes after the first simplification");
63 TWO_STATISTICS(
64     NumPHIWritesInLoops,
65     "Number of scalar phi writes nested in affine loops after Simplify");
66 TWO_STATISTICS(NumSingletonWrites, "Number of singleton writes after Simplify");
67 TWO_STATISTICS(
68     NumSingletonWritesInLoops,
69     "Number of singleton writes nested in affine loops after Simplify");
70 
71 static bool isImplicitRead(MemoryAccess *MA) {
72   return MA->isRead() && MA->isOriginalScalarKind();
73 }
74 
75 static bool isExplicitAccess(MemoryAccess *MA) {
76   return MA->isOriginalArrayKind();
77 }
78 
79 static bool isImplicitWrite(MemoryAccess *MA) {
80   return MA->isWrite() && MA->isOriginalScalarKind();
81 }
82 
83 /// Like isl::union_map::add_map, but may also return an underapproximated
84 /// result if getting too complex.
85 ///
86 /// This is implemented by adding disjuncts to the results until the limit is
87 /// reached.
88 static isl::union_map underapproximatedAddMap(isl::union_map UMap,
89                                               isl::map Map) {
90   if (UMap.is_null() || Map.is_null())
91     return {};
92 
93   isl::map PrevMap = UMap.extract_map(Map.get_space());
94 
95   // Fast path: If known that we cannot exceed the disjunct limit, just add
96   // them.
97   if (isl_map_n_basic_map(PrevMap.get()) + isl_map_n_basic_map(Map.get()) <=
98       SimplifyMaxDisjuncts)
99     return UMap.add_map(Map);
100 
101   isl::map Result = isl::map::empty(PrevMap.get_space());
102   for (isl::basic_map BMap : PrevMap.get_basic_map_list()) {
103     if (Result.n_basic_map() > SimplifyMaxDisjuncts)
104       break;
105     Result = Result.unite(BMap);
106   }
107   for (isl::basic_map BMap : Map.get_basic_map_list()) {
108     if (isl_map_n_basic_map(Result.get()) > SimplifyMaxDisjuncts)
109       break;
110     Result = Result.unite(BMap);
111   }
112 
113   isl::union_map UResult =
114       UMap.subtract(isl::map::universe(PrevMap.get_space()));
115   UResult.add_map(Result);
116 
117   return UResult;
118 }
119 
120 class Simplify : public ScopPass {
121 private:
122   /// The invocation id (if there are multiple instances in the pass manager's
123   /// pipeline) to determine which statistics to update.
124   int CallNo;
125 
126   /// The last/current SCoP that is/has been processed.
127   Scop *S;
128 
129   /// Number of statements with empty domains removed from the SCoP.
130   int EmptyDomainsRemoved = 0;
131 
132   /// Number of writes that are overwritten anyway.
133   int OverwritesRemoved = 0;
134 
135   /// Number of combined writes.
136   int WritesCoalesced = 0;
137 
138   /// Number of redundant writes removed from this SCoP.
139   int RedundantWritesRemoved = 0;
140 
141   /// Number of writes with empty access domain removed.
142   int EmptyPartialAccessesRemoved = 0;
143 
144   /// Number of unused accesses removed from this SCoP.
145   int DeadAccessesRemoved = 0;
146 
147   /// Number of unused instructions removed from this SCoP.
148   int DeadInstructionsRemoved = 0;
149 
150   /// Number of unnecessary statements removed from the SCoP.
151   int StmtsRemoved = 0;
152 
153   /// Return whether at least one simplification has been applied.
154   bool isModified() const {
155     return EmptyDomainsRemoved > 0 || OverwritesRemoved > 0 ||
156            WritesCoalesced > 0 || RedundantWritesRemoved > 0 ||
157            EmptyPartialAccessesRemoved > 0 || DeadAccessesRemoved > 0 ||
158            DeadInstructionsRemoved > 0 || StmtsRemoved > 0;
159   }
160 
161   /// Remove statements that are never executed due to their domains being
162   /// empty.
163   ///
164   /// In contrast to Scop::simplifySCoP, this removes based on the SCoP's
165   /// effective domain, i.e. including the SCoP's context as used by some other
166   /// simplification methods in this pass. This is necessary because the
167   /// analysis on empty domains is unreliable, e.g. remove a scalar value
168   /// definition MemoryAccesses, but not its use.
169   void removeEmptyDomainStmts() {
170     size_t NumStmtsBefore = S->getSize();
171 
172     auto ShouldDelete = [](ScopStmt &Stmt) -> bool {
173       auto EffectiveDomain =
174           Stmt.getDomain().intersect_params(Stmt.getParent()->getContext());
175       return EffectiveDomain.is_empty();
176     };
177     S->removeStmts(ShouldDelete);
178 
179     assert(NumStmtsBefore >= S->getSize());
180     EmptyDomainsRemoved = NumStmtsBefore - S->getSize();
181     LLVM_DEBUG(dbgs() << "Removed " << EmptyDomainsRemoved << " (of "
182                       << NumStmtsBefore
183                       << ") statements with empty domains \n");
184     TotalEmptyDomainsRemoved[CallNo] += EmptyDomainsRemoved;
185   }
186 
187   /// Remove writes that are overwritten unconditionally later in the same
188   /// statement.
189   ///
190   /// There must be no read of the same value between the write (that is to be
191   /// removed) and the overwrite.
192   void removeOverwrites() {
193     for (auto &Stmt : *S) {
194       isl::set Domain = Stmt.getDomain();
195       isl::union_map WillBeOverwritten =
196           isl::union_map::empty(S->getParamSpace());
197 
198       SmallVector<MemoryAccess *, 32> Accesses(getAccessesInOrder(Stmt));
199 
200       // Iterate in reverse order, so the overwrite comes before the write that
201       // is to be removed.
202       for (auto *MA : reverse(Accesses)) {
203 
204         // In region statements, the explicit accesses can be in blocks that are
205         // can be executed in any order. We therefore process only the implicit
206         // writes and stop after that.
207         if (Stmt.isRegionStmt() && isExplicitAccess(MA))
208           break;
209 
210         auto AccRel = MA->getAccessRelation();
211         AccRel = AccRel.intersect_domain(Domain);
212         AccRel = AccRel.intersect_params(S->getContext());
213 
214         // If a value is read in-between, do not consider it as overwritten.
215         if (MA->isRead()) {
216           // Invalidate all overwrites for the array it accesses to avoid too
217           // complex isl sets.
218           isl::map AccRelUniv = isl::map::universe(AccRel.get_space());
219           WillBeOverwritten = WillBeOverwritten.subtract(AccRelUniv);
220           continue;
221         }
222 
223         // If all of a write's elements are overwritten, remove it.
224         isl::union_map AccRelUnion = AccRel;
225         if (AccRelUnion.is_subset(WillBeOverwritten)) {
226           LLVM_DEBUG(dbgs() << "Removing " << MA
227                             << " which will be overwritten anyway\n");
228 
229           Stmt.removeSingleMemoryAccess(MA);
230           OverwritesRemoved++;
231           TotalOverwritesRemoved[CallNo]++;
232         }
233 
234         // Unconditional writes overwrite other values.
235         if (MA->isMustWrite()) {
236           // Avoid too complex isl sets. If necessary, throw away some of the
237           // knowledge.
238           WillBeOverwritten =
239               underapproximatedAddMap(WillBeOverwritten, AccRel);
240         }
241       }
242     }
243   }
244 
245   /// Combine writes that write the same value if possible.
246   ///
247   /// This function is able to combine:
248   /// - Partial writes with disjoint domain.
249   /// - Writes that write to the same array element.
250   ///
251   /// In all cases, both writes must write the same values.
252   void coalesceWrites() {
253     for (auto &Stmt : *S) {
254       isl::set Domain = Stmt.getDomain().intersect_params(S->getContext());
255 
256       // We let isl do the lookup for the same-value condition. For this, we
257       // wrap llvm::Value into an isl::set such that isl can do the lookup in
258       // its hashtable implementation. llvm::Values are only compared within a
259       // ScopStmt, so the map can be local to this scope. TODO: Refactor with
260       // ZoneAlgorithm::makeValueSet()
261       SmallDenseMap<Value *, isl::set> ValueSets;
262       auto makeValueSet = [&ValueSets, this](Value *V) -> isl::set {
263         assert(V);
264         isl::set &Result = ValueSets[V];
265         if (Result.is_null()) {
266           isl::ctx Ctx = S->getIslCtx();
267           std::string Name =
268               getIslCompatibleName("Val", V, ValueSets.size() - 1,
269                                    std::string(), UseInstructionNames);
270           isl::id Id = isl::id::alloc(Ctx, Name, V);
271           Result = isl::set::universe(
272               isl::space(Ctx, 0, 0).set_tuple_id(isl::dim::set, Id));
273         }
274         return Result;
275       };
276 
277       // List of all eligible (for coalescing) writes of the future.
278       // { [Domain[] -> Element[]] -> [Value[] -> MemoryAccess[]] }
279       isl::union_map FutureWrites = isl::union_map::empty(S->getParamSpace());
280 
281       // Iterate over accesses from the last to the first.
282       SmallVector<MemoryAccess *, 32> Accesses(getAccessesInOrder(Stmt));
283       for (MemoryAccess *MA : reverse(Accesses)) {
284         // In region statements, the explicit accesses can be in blocks that can
285         // be executed in any order. We therefore process only the implicit
286         // writes and stop after that.
287         if (Stmt.isRegionStmt() && isExplicitAccess(MA))
288           break;
289 
290         // { Domain[] -> Element[] }
291         isl::map AccRel =
292             MA->getLatestAccessRelation().intersect_domain(Domain);
293 
294         // { [Domain[] -> Element[]] }
295         isl::set AccRelWrapped = AccRel.wrap();
296 
297         // { Value[] }
298         isl::set ValSet;
299 
300         if (MA->isMustWrite() && (MA->isOriginalScalarKind() ||
301                                   isa<StoreInst>(MA->getAccessInstruction()))) {
302           // Normally, tryGetValueStored() should be used to determine which
303           // element is written, but it can return nullptr; For PHI accesses,
304           // getAccessValue() returns the PHI instead of the PHI's incoming
305           // value. In this case, where we only compare values of a single
306           // statement, this is fine, because within a statement, a PHI in a
307           // successor block has always the same value as the incoming write. We
308           // still preferably use the incoming value directly so we also catch
309           // direct uses of that.
310           Value *StoredVal = MA->tryGetValueStored();
311           if (!StoredVal)
312             StoredVal = MA->getAccessValue();
313           ValSet = makeValueSet(StoredVal);
314 
315           // { Domain[] }
316           isl::set AccDomain = AccRel.domain();
317 
318           // Parts of the statement's domain that is not written by this access.
319           isl::set UndefDomain = Domain.subtract(AccDomain);
320 
321           // { Element[] }
322           isl::set ElementUniverse =
323               isl::set::universe(AccRel.get_space().range());
324 
325           // { Domain[] -> Element[] }
326           isl::map UndefAnything =
327               isl::map::from_domain_and_range(UndefDomain, ElementUniverse);
328 
329           // We are looking a compatible write access. The other write can
330           // access these elements...
331           isl::map AllowedAccesses = AccRel.unite(UndefAnything);
332 
333           // ... and must write the same value.
334           // { [Domain[] -> Element[]] -> Value[] }
335           isl::map Filter =
336               isl::map::from_domain_and_range(AllowedAccesses.wrap(), ValSet);
337 
338           // Lookup future write that fulfills these conditions.
339           // { [[Domain[] -> Element[]] -> Value[]] -> MemoryAccess[] }
340           isl::union_map Filtered =
341               FutureWrites.uncurry().intersect_domain(Filter.wrap());
342 
343           // Iterate through the candidates.
344           for (isl::map Map : Filtered.get_map_list()) {
345             MemoryAccess *OtherMA = (MemoryAccess *)Map.get_space()
346                                         .get_tuple_id(isl::dim::out)
347                                         .get_user();
348 
349             isl::map OtherAccRel =
350                 OtherMA->getLatestAccessRelation().intersect_domain(Domain);
351 
352             // The filter only guaranteed that some of OtherMA's accessed
353             // elements are allowed. Verify that it only accesses allowed
354             // elements. Otherwise, continue with the next candidate.
355             if (!OtherAccRel.is_subset(AllowedAccesses).is_true())
356               continue;
357 
358             // The combined access relation.
359             // { Domain[] -> Element[] }
360             isl::map NewAccRel = AccRel.unite(OtherAccRel);
361             simplify(NewAccRel);
362 
363             // Carry out the coalescing.
364             Stmt.removeSingleMemoryAccess(MA);
365             OtherMA->setNewAccessRelation(NewAccRel);
366 
367             // We removed MA, OtherMA takes its role.
368             MA = OtherMA;
369 
370             TotalWritesCoalesced[CallNo]++;
371             WritesCoalesced++;
372 
373             // Don't look for more candidates.
374             break;
375           }
376         }
377 
378         // Two writes cannot be coalesced if there is another access (to some of
379         // the written elements) between them. Remove all visited write accesses
380         // from the list of eligible writes. Don't just remove the accessed
381         // elements, but any MemoryAccess that touches any of the invalidated
382         // elements.
383         SmallPtrSet<MemoryAccess *, 2> TouchedAccesses;
384         for (isl::map Map :
385              FutureWrites.intersect_domain(AccRelWrapped).get_map_list()) {
386           MemoryAccess *MA = (MemoryAccess *)Map.get_space()
387                                  .range()
388                                  .unwrap()
389                                  .get_tuple_id(isl::dim::out)
390                                  .get_user();
391           TouchedAccesses.insert(MA);
392         }
393         isl::union_map NewFutureWrites =
394             isl::union_map::empty(FutureWrites.get_space());
395         for (isl::map FutureWrite : FutureWrites.get_map_list()) {
396           MemoryAccess *MA = (MemoryAccess *)FutureWrite.get_space()
397                                  .range()
398                                  .unwrap()
399                                  .get_tuple_id(isl::dim::out)
400                                  .get_user();
401           if (!TouchedAccesses.count(MA))
402             NewFutureWrites = NewFutureWrites.add_map(FutureWrite);
403         }
404         FutureWrites = NewFutureWrites;
405 
406         if (MA->isMustWrite() && !ValSet.is_null()) {
407           // { MemoryAccess[] }
408           auto AccSet =
409               isl::set::universe(isl::space(S->getIslCtx(), 0, 0)
410                                      .set_tuple_id(isl::dim::set, MA->getId()));
411 
412           // { Val[] -> MemoryAccess[] }
413           isl::map ValAccSet = isl::map::from_domain_and_range(ValSet, AccSet);
414 
415           // { [Domain[] -> Element[]] -> [Value[] -> MemoryAccess[]] }
416           isl::map AccRelValAcc =
417               isl::map::from_domain_and_range(AccRelWrapped, ValAccSet.wrap());
418           FutureWrites = FutureWrites.add_map(AccRelValAcc);
419         }
420       }
421     }
422   }
423 
424   /// Remove writes that just write the same value already stored in the
425   /// element.
426   void removeRedundantWrites() {
427     for (auto &Stmt : *S) {
428       SmallDenseMap<Value *, isl::set> ValueSets;
429       auto makeValueSet = [&ValueSets, this](Value *V) -> isl::set {
430         assert(V);
431         isl::set &Result = ValueSets[V];
432         if (Result.is_null()) {
433           isl_ctx *Ctx = S->getIslCtx().get();
434           std::string Name =
435               getIslCompatibleName("Val", V, ValueSets.size() - 1,
436                                    std::string(), UseInstructionNames);
437           isl::id Id = isl::manage(isl_id_alloc(Ctx, Name.c_str(), V));
438           Result = isl::set::universe(
439               isl::space(Ctx, 0, 0).set_tuple_id(isl::dim::set, Id));
440         }
441         return Result;
442       };
443 
444       isl::set Domain = Stmt.getDomain();
445       Domain = Domain.intersect_params(S->getContext());
446 
447       // List of element reads that still have the same value while iterating
448       // through the MemoryAccesses.
449       // { [Domain[] -> Element[]] -> Val[] }
450       isl::union_map Known = isl::union_map::empty(S->getParamSpace());
451 
452       SmallVector<MemoryAccess *, 32> Accesses(getAccessesInOrder(Stmt));
453       for (MemoryAccess *MA : Accesses) {
454         // Is the memory access in a defined order relative to the other
455         // accesses? In region statements, only the first and the last accesses
456         // have defined order. Execution of those in the middle may depend on
457         // runtime conditions an therefore cannot be modified.
458         bool IsOrdered =
459             Stmt.isBlockStmt() || MA->isOriginalScalarKind() ||
460             (!S->getBoxedLoops().size() && MA->getAccessInstruction() &&
461              Stmt.getEntryBlock() == MA->getAccessInstruction()->getParent());
462 
463         isl::map AccRel = MA->getAccessRelation();
464         AccRel = AccRel.intersect_domain(Domain);
465         isl::set AccRelWrapped = AccRel.wrap();
466 
467         // Determine whether a write is redundant (stores only values that are
468         // already present in the written array elements) and remove it if this
469         // is the case.
470         if (IsOrdered && MA->isMustWrite() &&
471             (isa<StoreInst>(MA->getAccessInstruction()) ||
472              MA->isOriginalScalarKind())) {
473           Value *StoredVal = MA->tryGetValueStored();
474           if (!StoredVal)
475             StoredVal = MA->getAccessValue();
476 
477           if (StoredVal) {
478             // Lookup in the set of known values.
479             isl::map AccRelStoredVal = isl::map::from_domain_and_range(
480                 AccRelWrapped, makeValueSet(StoredVal));
481             if (isl::union_map(AccRelStoredVal).is_subset(Known)) {
482               LLVM_DEBUG(dbgs() << "Cleanup of " << MA << ":\n");
483               LLVM_DEBUG(dbgs() << "      Scalar: " << *StoredVal << "\n");
484               LLVM_DEBUG(dbgs() << "      AccRel: " << AccRel << "\n");
485 
486               Stmt.removeSingleMemoryAccess(MA);
487 
488               RedundantWritesRemoved++;
489               TotalRedundantWritesRemoved[CallNo]++;
490             }
491           }
492         }
493 
494         // Update the know values set.
495         if (MA->isRead()) {
496           // Loaded values are the currently known values of the array element
497           // it was loaded from.
498           Value *LoadedVal = MA->getAccessValue();
499           if (LoadedVal && IsOrdered) {
500             isl::map AccRelVal = isl::map::from_domain_and_range(
501                 AccRelWrapped, makeValueSet(LoadedVal));
502 
503             Known = Known.add_map(AccRelVal);
504           }
505         } else if (MA->isWrite()) {
506           // Remove (possibly) overwritten values from the known elements set.
507           // We remove all elements of the accessed array to avoid too complex
508           // isl sets.
509           isl::set AccRelUniv = isl::set::universe(AccRelWrapped.get_space());
510           Known = Known.subtract_domain(AccRelUniv);
511 
512           // At this point, we could add the written value of must-writes.
513           // However, writing same values is already handled by
514           // coalesceWrites().
515         }
516       }
517     }
518   }
519 
520   /// Remove statements without side effects.
521   void removeUnnecessaryStmts() {
522     auto NumStmtsBefore = S->getSize();
523     S->simplifySCoP(true);
524     assert(NumStmtsBefore >= S->getSize());
525     StmtsRemoved = NumStmtsBefore - S->getSize();
526     LLVM_DEBUG(dbgs() << "Removed " << StmtsRemoved << " (of " << NumStmtsBefore
527                       << ") statements\n");
528     TotalStmtsRemoved[CallNo] += StmtsRemoved;
529   }
530 
531   /// Remove accesses that have an empty domain.
532   void removeEmptyPartialAccesses() {
533     for (ScopStmt &Stmt : *S) {
534       // Defer the actual removal to not invalidate iterators.
535       SmallVector<MemoryAccess *, 8> DeferredRemove;
536 
537       for (MemoryAccess *MA : Stmt) {
538         if (!MA->isWrite())
539           continue;
540 
541         isl::map AccRel = MA->getAccessRelation();
542         if (!AccRel.is_empty().is_true())
543           continue;
544 
545         LLVM_DEBUG(
546             dbgs() << "Removing " << MA
547                    << " because it's a partial access that never occurs\n");
548         DeferredRemove.push_back(MA);
549       }
550 
551       for (MemoryAccess *MA : DeferredRemove) {
552         Stmt.removeSingleMemoryAccess(MA);
553         EmptyPartialAccessesRemoved++;
554         TotalEmptyPartialAccessesRemoved[CallNo]++;
555       }
556     }
557   }
558 
559   /// Mark all reachable instructions and access, and sweep those that are not
560   /// reachable.
561   void markAndSweep(LoopInfo *LI) {
562     DenseSet<MemoryAccess *> UsedMA;
563     DenseSet<VirtualInstruction> UsedInsts;
564 
565     // Get all reachable instructions and accesses.
566     markReachable(S, LI, UsedInsts, UsedMA);
567 
568     // Remove all non-reachable accesses.
569     // We need get all MemoryAccesses first, in order to not invalidate the
570     // iterators when removing them.
571     SmallVector<MemoryAccess *, 64> AllMAs;
572     for (ScopStmt &Stmt : *S)
573       AllMAs.append(Stmt.begin(), Stmt.end());
574 
575     for (MemoryAccess *MA : AllMAs) {
576       if (UsedMA.count(MA))
577         continue;
578       LLVM_DEBUG(dbgs() << "Removing " << MA
579                         << " because its value is not used\n");
580       ScopStmt *Stmt = MA->getStatement();
581       Stmt->removeSingleMemoryAccess(MA);
582 
583       DeadAccessesRemoved++;
584       TotalDeadAccessesRemoved[CallNo]++;
585     }
586 
587     // Remove all non-reachable instructions.
588     for (ScopStmt &Stmt : *S) {
589       // Note that for region statements, we can only remove the non-terminator
590       // instructions of the entry block. All other instructions are not in the
591       // instructions list, but implicitly always part of the statement.
592 
593       SmallVector<Instruction *, 32> AllInsts(Stmt.insts_begin(),
594                                               Stmt.insts_end());
595       SmallVector<Instruction *, 32> RemainInsts;
596 
597       for (Instruction *Inst : AllInsts) {
598         auto It = UsedInsts.find({&Stmt, Inst});
599         if (It == UsedInsts.end()) {
600           LLVM_DEBUG(dbgs() << "Removing "; Inst->print(dbgs());
601                      dbgs() << " because it is not used\n");
602           DeadInstructionsRemoved++;
603           TotalDeadInstructionsRemoved[CallNo]++;
604           continue;
605         }
606 
607         RemainInsts.push_back(Inst);
608 
609         // If instructions appear multiple times, keep only the first.
610         UsedInsts.erase(It);
611       }
612 
613       // Set the new instruction list to be only those we did not remove.
614       Stmt.setInstructions(RemainInsts);
615     }
616   }
617 
618   /// Print simplification statistics to @p OS.
619   void printStatistics(llvm::raw_ostream &OS, int Indent = 0) const {
620     OS.indent(Indent) << "Statistics {\n";
621     OS.indent(Indent + 4) << "Empty domains removed: " << EmptyDomainsRemoved
622                           << '\n';
623     OS.indent(Indent + 4) << "Overwrites removed: " << OverwritesRemoved
624                           << '\n';
625     OS.indent(Indent + 4) << "Partial writes coalesced: " << WritesCoalesced
626                           << "\n";
627     OS.indent(Indent + 4) << "Redundant writes removed: "
628                           << RedundantWritesRemoved << "\n";
629     OS.indent(Indent + 4) << "Accesses with empty domains removed: "
630                           << EmptyPartialAccessesRemoved << "\n";
631     OS.indent(Indent + 4) << "Dead accesses removed: " << DeadAccessesRemoved
632                           << '\n';
633     OS.indent(Indent + 4) << "Dead instructions removed: "
634                           << DeadInstructionsRemoved << '\n';
635     OS.indent(Indent + 4) << "Stmts removed: " << StmtsRemoved << "\n";
636     OS.indent(Indent) << "}\n";
637   }
638 
639   /// Print the current state of all MemoryAccesses to @p OS.
640   void printAccesses(llvm::raw_ostream &OS, int Indent = 0) const {
641     OS.indent(Indent) << "After accesses {\n";
642     for (auto &Stmt : *S) {
643       OS.indent(Indent + 4) << Stmt.getBaseName() << "\n";
644       for (auto *MA : Stmt)
645         MA->print(OS);
646     }
647     OS.indent(Indent) << "}\n";
648   }
649 
650 public:
651   static char ID;
652   explicit Simplify(int CallNo = 0) : ScopPass(ID), CallNo(CallNo) {}
653 
654   virtual void getAnalysisUsage(AnalysisUsage &AU) const override {
655     AU.addRequiredTransitive<ScopInfoRegionPass>();
656     AU.addRequired<LoopInfoWrapperPass>();
657     AU.setPreservesAll();
658   }
659 
660   virtual bool runOnScop(Scop &S) override {
661     // Reset statistics of last processed SCoP.
662     releaseMemory();
663     assert(!isModified());
664 
665     // Prepare processing of this SCoP.
666     this->S = &S;
667     ScopsProcessed[CallNo]++;
668 
669     LLVM_DEBUG(dbgs() << "Removing statements that are never executed...\n");
670     removeEmptyDomainStmts();
671 
672     LLVM_DEBUG(dbgs() << "Removing partial writes that never happen...\n");
673     removeEmptyPartialAccesses();
674 
675     LLVM_DEBUG(dbgs() << "Removing overwrites...\n");
676     removeOverwrites();
677 
678     LLVM_DEBUG(dbgs() << "Coalesce partial writes...\n");
679     coalesceWrites();
680 
681     LLVM_DEBUG(dbgs() << "Removing redundant writes...\n");
682     removeRedundantWrites();
683 
684     LLVM_DEBUG(dbgs() << "Cleanup unused accesses...\n");
685     LoopInfo *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
686     markAndSweep(LI);
687 
688     LLVM_DEBUG(dbgs() << "Removing statements without side effects...\n");
689     removeUnnecessaryStmts();
690 
691     if (isModified())
692       ScopsModified[CallNo]++;
693     LLVM_DEBUG(dbgs() << "\nFinal Scop:\n");
694     LLVM_DEBUG(dbgs() << S);
695 
696     auto ScopStats = S.getStatistics();
697     NumValueWrites[CallNo] += ScopStats.NumValueWrites;
698     NumValueWritesInLoops[CallNo] += ScopStats.NumValueWritesInLoops;
699     NumPHIWrites[CallNo] += ScopStats.NumPHIWrites;
700     NumPHIWritesInLoops[CallNo] += ScopStats.NumPHIWritesInLoops;
701     NumSingletonWrites[CallNo] += ScopStats.NumSingletonWrites;
702     NumSingletonWritesInLoops[CallNo] += ScopStats.NumSingletonWritesInLoops;
703 
704     return false;
705   }
706 
707   virtual void printScop(raw_ostream &OS, Scop &S) const override {
708     assert(&S == this->S &&
709            "Can only print analysis for the last processed SCoP");
710     printStatistics(OS);
711 
712     if (!isModified()) {
713       OS << "SCoP could not be simplified\n";
714       return;
715     }
716     printAccesses(OS);
717   }
718 
719   virtual void releaseMemory() override {
720     S = nullptr;
721 
722     EmptyDomainsRemoved = 0;
723     OverwritesRemoved = 0;
724     WritesCoalesced = 0;
725     RedundantWritesRemoved = 0;
726     EmptyPartialAccessesRemoved = 0;
727     DeadAccessesRemoved = 0;
728     DeadInstructionsRemoved = 0;
729     StmtsRemoved = 0;
730   }
731 };
732 
733 char Simplify::ID;
734 } // anonymous namespace
735 
736 namespace polly {
737 SmallVector<MemoryAccess *, 32> getAccessesInOrder(ScopStmt &Stmt) {
738 
739   SmallVector<MemoryAccess *, 32> Accesses;
740 
741   for (MemoryAccess *MemAcc : Stmt)
742     if (isImplicitRead(MemAcc))
743       Accesses.push_back(MemAcc);
744 
745   for (MemoryAccess *MemAcc : Stmt)
746     if (isExplicitAccess(MemAcc))
747       Accesses.push_back(MemAcc);
748 
749   for (MemoryAccess *MemAcc : Stmt)
750     if (isImplicitWrite(MemAcc))
751       Accesses.push_back(MemAcc);
752 
753   return Accesses;
754 }
755 } // namespace polly
756 
757 Pass *polly::createSimplifyPass(int CallNo) { return new Simplify(CallNo); }
758 
759 INITIALIZE_PASS_BEGIN(Simplify, "polly-simplify", "Polly - Simplify", false,
760                       false)
761 INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
762 INITIALIZE_PASS_END(Simplify, "polly-simplify", "Polly - Simplify", false,
763                     false)
764