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