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