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