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