1 //===------ DeLICM.cpp -----------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // Undo the effect of Loop Invariant Code Motion (LICM) and
11 // GVN Partial Redundancy Elimination (PRE) on SCoP-level.
12 //
13 // Namely, remove register/scalar dependencies by mapping them back to array
14 // elements.
15 //
16 // The algorithms here work on the scatter space - the image space of the
17 // schedule returned by Scop::getSchedule(). We call an element in that space a
18 // "timepoint". Timepoints are lexicographically ordered such that we can
19 // defined ranges in the scatter space. We use two flavors of such ranges:
20 // Timepoint sets and zones. A timepoint set is simply a subset of the scatter
21 // space and is directly stored as isl_set.
22 //
23 // Zones are used to describe the space between timepoints as open sets, i.e.
24 // they do not contain the extrema. Using isl rational sets to express these
25 // would be overkill. We also cannot store them as the integer timepoints they
26 // contain; the (nonempty) zone between 1 and 2 would be empty and
27 // indistinguishable from e.g. the zone between 3 and 4. Also, we cannot store
28 // the integer set including the extrema; the set ]1,2[ + ]3,4[ could be
29 // coalesced to ]1,3[, although we defined the range [2,3] to be not in the set.
30 // Instead, we store the "half-open" integer extrema, including the lower bound,
31 // but excluding the upper bound. Examples:
32 //
33 // * The set { [i] : 1 <= i <= 3 } represents the zone ]0,3[ (which contains the
34 //   integer points 1 and 2, but not 0 or 3)
35 //
36 // * { [1] } represents the zone ]0,1[
37 //
38 // * { [i] : i = 1 or i = 3 } represents the zone ]0,1[ + ]2,3[
39 //
40 // Therefore, an integer i in the set represents the zone ]i-1,i[, i.e. strictly
41 // speaking the integer points never belong to the zone. However, depending an
42 // the interpretation, one might want to include them. Part of the
43 // interpretation may not be known when the zone is constructed.
44 //
45 // Reads are assumed to always take place before writes, hence we can think of
46 // reads taking place at the beginning of a timepoint and writes at the end.
47 //
48 // Let's assume that the zone represents the lifetime of a variable. That is,
49 // the zone begins with a write that defines the value during its lifetime and
50 // ends with the last read of that value. In the following we consider whether a
51 // read/write at the beginning/ending of the lifetime zone should be within the
52 // zone or outside of it.
53 //
54 // * A read at the timepoint that starts the live-range loads the previous
55 //   value. Hence, exclude the timepoint starting the zone.
56 //
57 // * A write at the timepoint that starts the live-range is not defined whether
58 //   it occurs before or after the write that starts the lifetime. We do not
59 //   allow this situation to occur. Hence, we include the timepoint starting the
60 //   zone to determine whether they are conflicting.
61 //
62 // * A read at the timepoint that ends the live-range reads the same variable.
63 //   We include the timepoint at the end of the zone to include that read into
64 //   the live-range. Doing otherwise would mean that the two reads access
65 //   different values, which would mean that the value they read are both alive
66 //   at the same time but occupy the same variable.
67 //
68 // * A write at the timepoint that ends the live-range starts a new live-range.
69 //   It must not be included in the live-range of the previous definition.
70 //
71 // All combinations of reads and writes at the endpoints are possible, but most
72 // of the time only the write->read (for instance, a live-range from definition
73 // to last use) and read->write (for instance, an unused range from last use to
74 // overwrite) and combinations are interesting (half-open ranges). write->write
75 // zones might be useful as well in some context to represent
76 // output-dependencies.
77 //
78 // @see convertZoneToTimepoints
79 //
80 //
81 // The code makes use of maps and sets in many different spaces. To not loose
82 // track in which space a set or map is expected to be in, variables holding an
83 // isl reference are usually annotated in the comments. They roughly follow isl
84 // syntax for spaces, but only the tuples, not the dimensions. The tuples have a
85 // meaning as follows:
86 //
87 // * Space[] - An unspecified tuple. Used for function parameters such that the
88 //             function caller can use it for anything they like.
89 //
90 // * Domain[] - A statement instance as returned by ScopStmt::getDomain()
91 //     isl_id_get_name: Stmt_<NameOfBasicBlock>
92 //     isl_id_get_user: Pointer to ScopStmt
93 //
94 // * Element[] - An array element as in the range part of
95 //               MemoryAccess::getAccessRelation()
96 //     isl_id_get_name: MemRef_<NameOfArrayVariable>
97 //     isl_id_get_user: Pointer to ScopArrayInfo
98 //
99 // * Scatter[] - Scatter space or space of timepoints
100 //     Has no tuple id
101 //
102 // * Zone[] - Range between timepoints as described above
103 //     Has no tuple id
104 //
105 // * ValInst[] - An llvm::Value as defined at a specific timepoint.
106 //
107 //     A ValInst[] itself can be structured as one of:
108 //
109 //     * [] - An unknown value.
110 //         Always zero dimensions
111 //         Has no tuple id
112 //
113 //     * Value[] - An llvm::Value that is read-only in the SCoP, i.e. its
114 //                 runtime content does not depend on the timepoint.
115 //         Always zero dimensions
116 //         isl_id_get_name: Val_<NameOfValue>
117 //         isl_id_get_user: A pointer to an llvm::Value
118 //
119 //     * SCEV[...] - A synthesizable llvm::SCEV Expression.
120 //         In contrast to a Value[] is has at least one dimension per
121 //         SCEVAddRecExpr in the SCEV.
122 //
123 //     * [Domain[] -> Value[]] - An llvm::Value that may change during the
124 //                               Scop's execution.
125 //         The tuple itself has no id, but it wraps a map space holding a
126 //         statement instance which defines the llvm::Value as the map's domain
127 //         and llvm::Value itself as range.
128 //
129 // @see makeValInst()
130 //
131 // An annotation "{ Domain[] -> Scatter[] }" therefore means: A map from a
132 // statement instance to a timepoint, aka a schedule. There is only one scatter
133 // space, but most of the time multiple statements are processed in one set.
134 // This is why most of the time isl_union_map has to be used.
135 //
136 // The basic algorithm works as follows:
137 // At first we verify that the SCoP is compatible with this technique. For
138 // instance, two writes cannot write to the same location at the same statement
139 // instance because we cannot determine within the polyhedral model which one
140 // comes first. Once this was verified, we compute zones at which an array
141 // element is unused. This computation can fail if it takes too long. Then the
142 // main algorithm is executed. Because every store potentially trails an unused
143 // zone, we start at stores. We search for a scalar (MemoryKind::Value or
144 // MemoryKind::PHI) that we can map to the array element overwritten by the
145 // store, preferably one that is used by the store or at least the ScopStmt.
146 // When it does not conflict with the lifetime of the values in the array
147 // element, the map is applied and the unused zone updated as it is now used. We
148 // continue to try to map scalars to the array element until there are no more
149 // candidates to map. The algorithm is greedy in the sense that the first scalar
150 // not conflicting will be mapped. Other scalars processed later that could have
151 // fit the same unused zone will be rejected. As such the result depends on the
152 // processing order.
153 //
154 //===----------------------------------------------------------------------===//
155 
156 #include "polly/DeLICM.h"
157 #include "polly/Options.h"
158 #include "polly/ScopInfo.h"
159 #include "polly/ScopPass.h"
160 #include "polly/Support/ISLOStream.h"
161 #include "polly/Support/ISLTools.h"
162 #include "polly/Support/VirtualInstruction.h"
163 #include "llvm/ADT/Statistic.h"
164 #define DEBUG_TYPE "polly-delicm"
165 
166 using namespace polly;
167 using namespace llvm;
168 
169 namespace {
170 
171 cl::opt<int>
172     DelicmMaxOps("polly-delicm-max-ops",
173                  cl::desc("Maximum number of isl operations to invest for "
174                           "lifetime analysis; 0=no limit"),
175                  cl::init(1000000), cl::cat(PollyCategory));
176 
177 cl::opt<bool> DelicmOverapproximateWrites(
178     "polly-delicm-overapproximate-writes",
179     cl::desc(
180         "Do more PHI writes than necessary in order to avoid partial accesses"),
181     cl::init(false), cl::Hidden, cl::cat(PollyCategory));
182 
183 cl::opt<bool> DelicmPartialWrites("polly-delicm-partial-writes",
184                                   cl::desc("Allow partial writes"),
185                                   cl::init(false), cl::Hidden,
186                                   cl::cat(PollyCategory));
187 
188 cl::opt<bool>
189     DelicmComputeKnown("polly-delicm-compute-known",
190                        cl::desc("Compute known content of array elements"),
191                        cl::init(true), cl::Hidden, cl::cat(PollyCategory));
192 
193 STATISTIC(DeLICMAnalyzed, "Number of successfully analyzed SCoPs");
194 STATISTIC(DeLICMOutOfQuota,
195           "Analyses aborted because max_operations was reached");
196 STATISTIC(DeLICMIncompatible, "Number of SCoPs incompatible for analysis");
197 STATISTIC(MappedValueScalars, "Number of mapped Value scalars");
198 STATISTIC(MappedPHIScalars, "Number of mapped PHI scalars");
199 STATISTIC(TargetsMapped, "Number of stores used for at least one mapping");
200 STATISTIC(DeLICMScopsModified, "Number of SCoPs optimized");
201 
202 /// Class for keeping track of scalar def-use chains in the polyhedral
203 /// representation.
204 ///
205 /// MemoryKind::Value:
206 /// There is one definition per llvm::Value or zero (read-only values defined
207 /// before the SCoP) and an arbitrary number of reads.
208 ///
209 /// MemoryKind::PHI, MemoryKind::ExitPHI:
210 /// There is at least one write (the incoming blocks/stmts) and one
211 /// (MemoryKind::PHI) or zero (MemoryKind::ExitPHI) reads per llvm::PHINode.
212 class ScalarDefUseChains {
213 private:
214   /// The definitions (i.e. write MemoryAccess) of a MemoryKind::Value scalar.
215   DenseMap<const ScopArrayInfo *, MemoryAccess *> ValueDefAccs;
216 
217   /// List of all uses (i.e. read MemoryAccesses) for a MemoryKind::Value
218   /// scalar.
219   DenseMap<const ScopArrayInfo *, SmallVector<MemoryAccess *, 4>> ValueUseAccs;
220 
221   /// The receiving part (i.e. read MemoryAccess) of a MemoryKind::PHI scalar.
222   DenseMap<const ScopArrayInfo *, MemoryAccess *> PHIReadAccs;
223 
224   /// List of all incoming values (write MemoryAccess) of a MemoryKind::PHI or
225   /// MemoryKind::ExitPHI scalar.
226   DenseMap<const ScopArrayInfo *, SmallVector<MemoryAccess *, 4>>
227       PHIIncomingAccs;
228 
229 public:
230   /// Find the MemoryAccesses that access the ScopArrayInfo-represented memory.
231   ///
232   /// @param S The SCoP to analyze.
233   void compute(Scop *S) {
234     // Purge any previous result.
235     reset();
236 
237     for (auto &Stmt : *S) {
238       for (auto *MA : Stmt) {
239         if (MA->isOriginalValueKind() && MA->isWrite()) {
240           auto *SAI = MA->getScopArrayInfo();
241           assert(!ValueDefAccs.count(SAI) &&
242                  "There can be at most one "
243                  "definition per MemoryKind::Value scalar");
244           ValueDefAccs[SAI] = MA;
245         }
246 
247         if (MA->isOriginalValueKind() && MA->isRead())
248           ValueUseAccs[MA->getScopArrayInfo()].push_back(MA);
249 
250         if (MA->isOriginalAnyPHIKind() && MA->isRead()) {
251           auto *SAI = MA->getScopArrayInfo();
252           assert(!PHIReadAccs.count(SAI) &&
253                  "There must be exactly one read "
254                  "per PHI (that's where the PHINode is)");
255           PHIReadAccs[SAI] = MA;
256         }
257 
258         if (MA->isOriginalAnyPHIKind() && MA->isWrite())
259           PHIIncomingAccs[MA->getScopArrayInfo()].push_back(MA);
260       }
261     }
262   }
263 
264   /// Free all memory used by the analysis.
265   void reset() {
266     ValueDefAccs.clear();
267     ValueUseAccs.clear();
268     PHIReadAccs.clear();
269     PHIIncomingAccs.clear();
270   }
271 
272   MemoryAccess *getValueDef(const ScopArrayInfo *SAI) const {
273     return ValueDefAccs.lookup(SAI);
274   }
275 
276   ArrayRef<MemoryAccess *> getValueUses(const ScopArrayInfo *SAI) const {
277     auto It = ValueUseAccs.find(SAI);
278     if (It == ValueUseAccs.end())
279       return {};
280     return It->second;
281   }
282 
283   MemoryAccess *getPHIRead(const ScopArrayInfo *SAI) const {
284     return PHIReadAccs.lookup(SAI);
285   }
286 
287   ArrayRef<MemoryAccess *> getPHIIncomings(const ScopArrayInfo *SAI) const {
288     auto It = PHIIncomingAccs.find(SAI);
289     if (It == PHIIncomingAccs.end())
290       return {};
291     return It->second;
292   }
293 };
294 
295 isl::union_map computeReachingDefinition(isl::union_map Schedule,
296                                          isl::union_map Writes, bool InclDef,
297                                          bool InclRedef) {
298   return computeReachingWrite(Schedule, Writes, false, InclDef, InclRedef);
299 }
300 
301 isl::union_map computeReachingOverwrite(isl::union_map Schedule,
302                                         isl::union_map Writes,
303                                         bool InclPrevWrite,
304                                         bool InclOverwrite) {
305   return computeReachingWrite(Schedule, Writes, true, InclPrevWrite,
306                               InclOverwrite);
307 }
308 
309 /// Compute the next overwrite for a scalar.
310 ///
311 /// @param Schedule      { DomainWrite[] -> Scatter[] }
312 ///                      Schedule of (at least) all writes. Instances not in @p
313 ///                      Writes are ignored.
314 /// @param Writes        { DomainWrite[] }
315 ///                      The element instances that write to the scalar.
316 /// @param InclPrevWrite Whether to extend the timepoints to include
317 ///                      the timepoint where the previous write happens.
318 /// @param InclOverwrite Whether the reaching overwrite includes the timepoint
319 ///                      of the overwrite itself.
320 ///
321 /// @return { Scatter[] -> DomainDef[] }
322 isl::union_map computeScalarReachingOverwrite(isl::union_map Schedule,
323                                               isl::union_set Writes,
324                                               bool InclPrevWrite,
325                                               bool InclOverwrite) {
326 
327   // { DomainWrite[] }
328   auto WritesMap = give(isl_union_map_from_domain(Writes.take()));
329 
330   // { [Element[] -> Scatter[]] -> DomainWrite[] }
331   auto Result = computeReachingOverwrite(
332       std::move(Schedule), std::move(WritesMap), InclPrevWrite, InclOverwrite);
333 
334   return give(isl_union_map_domain_factor_range(Result.take()));
335 }
336 
337 /// Overload of computeScalarReachingOverwrite, with only one writing statement.
338 /// Consequently, the result consists of only one map space.
339 ///
340 /// @param Schedule      { DomainWrite[] -> Scatter[] }
341 /// @param Writes        { DomainWrite[] }
342 /// @param InclPrevWrite Include the previous write to result.
343 /// @param InclOverwrite Include the overwrite to the result.
344 ///
345 /// @return { Scatter[] -> DomainWrite[] }
346 isl::map computeScalarReachingOverwrite(isl::union_map Schedule,
347                                         isl::set Writes, bool InclPrevWrite,
348                                         bool InclOverwrite) {
349   auto ScatterSpace = getScatterSpace(Schedule);
350   auto DomSpace = give(isl_set_get_space(Writes.keep()));
351 
352   auto ReachOverwrite = computeScalarReachingOverwrite(
353       Schedule, give(isl_union_set_from_set(Writes.take())), InclPrevWrite,
354       InclOverwrite);
355 
356   auto ResultSpace = give(isl_space_map_from_domain_and_range(
357       ScatterSpace.take(), DomSpace.take()));
358   return singleton(std::move(ReachOverwrite), ResultSpace);
359 }
360 
361 /// Compute the reaching definition of a scalar.
362 ///
363 /// Compared to computeReachingDefinition, there is just one element which is
364 /// accessed and therefore only a set if instances that accesses that element is
365 /// required.
366 ///
367 /// @param Schedule  { DomainWrite[] -> Scatter[] }
368 /// @param Writes    { DomainWrite[] }
369 /// @param InclDef   Include the timepoint of the definition to the result.
370 /// @param InclRedef Include the timepoint of the overwrite into the result.
371 ///
372 /// @return { Scatter[] -> DomainWrite[] }
373 isl::union_map computeScalarReachingDefinition(isl::union_map Schedule,
374                                                isl::union_set Writes,
375                                                bool InclDef, bool InclRedef) {
376 
377   // { DomainWrite[] -> Element[] }
378   auto Defs = give(isl_union_map_from_domain(Writes.take()));
379 
380   // { [Element[] -> Scatter[]] -> DomainWrite[] }
381   auto ReachDefs =
382       computeReachingDefinition(Schedule, Defs, InclDef, InclRedef);
383 
384   // { Scatter[] -> DomainWrite[] }
385   return give(isl_union_set_unwrap(
386       isl_union_map_range(isl_union_map_curry(ReachDefs.take()))));
387 }
388 
389 /// Compute the reaching definition of a scalar.
390 ///
391 /// This overload accepts only a single writing statement as an isl_map,
392 /// consequently the result also is only a single isl_map.
393 ///
394 /// @param Schedule  { DomainWrite[] -> Scatter[] }
395 /// @param Writes    { DomainWrite[] }
396 /// @param InclDef   Include the timepoint of the definition to the result.
397 /// @param InclRedef Include the timepoint of the overwrite into the result.
398 ///
399 /// @return { Scatter[] -> DomainWrite[] }
400 isl::map computeScalarReachingDefinition( // { Domain[] -> Zone[] }
401     isl::union_map Schedule, isl::set Writes, bool InclDef, bool InclRedef) {
402   auto DomainSpace = give(isl_set_get_space(Writes.keep()));
403   auto ScatterSpace = getScatterSpace(Schedule);
404 
405   //  { Scatter[] -> DomainWrite[] }
406   auto UMap = computeScalarReachingDefinition(
407       Schedule, give(isl_union_set_from_set(Writes.take())), InclDef,
408       InclRedef);
409 
410   auto ResultSpace = give(isl_space_map_from_domain_and_range(
411       ScatterSpace.take(), DomainSpace.take()));
412   return singleton(UMap, ResultSpace);
413 }
414 
415 /// Create a domain-to-unknown value mapping.
416 ///
417 /// Value instances that do not represent a specific value are represented by an
418 /// unnamed tuple of 0 dimensions. Its meaning depends on the context. It can
419 /// either mean a specific but unknown value which cannot be represented by
420 /// other means. It conflicts with itself because those two unknown ValInsts may
421 /// have different concrete values at runtime.
422 ///
423 /// The other meaning is an arbitrary or wildcard value that can be chosen
424 /// freely, like LLVM's undef. If matched with an unknown ValInst, there is no
425 /// conflict.
426 ///
427 /// @param Domain { Domain[] }
428 ///
429 /// @return { Domain[] -> ValInst[] }
430 isl::union_map makeUnknownForDomain(isl::union_set Domain) {
431   return give(isl_union_map_from_domain(Domain.take()));
432 }
433 
434 /// Create a domain-to-unknown value mapping.
435 ///
436 /// @see makeUnknownForDomain(isl::union_set)
437 ///
438 /// @param Domain { Domain[] }
439 ///
440 /// @return { Domain[] -> ValInst[] }
441 isl::map makeUnknownForDomain(isl::set Domain) {
442   return give(isl_map_from_domain(Domain.take()));
443 }
444 
445 /// Return whether @p Map maps to an unknown value.
446 ///
447 /// @param { [] -> ValInst[] }
448 bool isMapToUnknown(const isl::map &Map) {
449   auto Space = give(isl_space_range(isl_map_get_space(Map.keep())));
450   return !isl_map_has_tuple_id(Map.keep(), isl_dim_set) &&
451          !isl_space_is_wrapping(Space.keep()) &&
452          isl_map_dim(Map.keep(), isl_dim_out) == 0;
453 }
454 
455 /// Return only the mappings that map to known values.
456 ///
457 /// @param UMap { [] -> ValInst[] }
458 ///
459 /// @return { [] -> ValInst[] }
460 isl::union_map filterKnownValInst(const isl::union_map &UMap) {
461   auto Result = give(isl_union_map_empty(isl_union_map_get_space(UMap.keep())));
462   UMap.foreach_map([=, &Result](isl::map Map) -> isl::stat {
463     if (!isMapToUnknown(Map))
464       Result = give(isl_union_map_add_map(Result.take(), Map.take()));
465     return isl::stat::ok;
466   });
467   return Result;
468 }
469 
470 /// Try to find a 'natural' extension of a mapped to elements outside its
471 /// domain.
472 ///
473 /// @param Relevant The map with mapping that may not be modified.
474 /// @param Universe The domain to which @p Relevant needs to be extended.
475 ///
476 /// @return A map with that associates the domain elements of @p Relevant to the
477 ///         same elements and in addition the elements of @p Universe to some
478 ///         undefined elements. The function prefers to return simple maps.
479 isl::union_map expandMapping(isl::union_map Relevant, isl::union_set Universe) {
480   Relevant = give(isl_union_map_coalesce(Relevant.take()));
481   auto RelevantDomain = give(isl_union_map_domain(Relevant.copy()));
482   auto Simplified =
483       give(isl_union_map_gist_domain(Relevant.take(), RelevantDomain.take()));
484   Simplified = give(isl_union_map_coalesce(Simplified.take()));
485   return give(
486       isl_union_map_intersect_domain(Simplified.take(), Universe.take()));
487 }
488 
489 /// Represent the knowledge of the contents of any array elements in any zone or
490 /// the knowledge we would add when mapping a scalar to an array element.
491 ///
492 /// Every array element at every zone unit has one of two states:
493 ///
494 /// - Unused: Not occupied by any value so a transformation can change it to
495 ///   other values.
496 ///
497 /// - Occupied: The element contains a value that is still needed.
498 ///
499 /// The union of Unused and Unknown zones forms the universe, the set of all
500 /// elements at every timepoint. The universe can easily be derived from the
501 /// array elements that are accessed someway. Arrays that are never accessed
502 /// also never play a role in any computation and can hence be ignored. With a
503 /// given universe, only one of the sets needs to stored implicitly. Computing
504 /// the complement is also an expensive operation, hence this class has been
505 /// designed that only one of sets is needed while the other is assumed to be
506 /// implicit. It can still be given, but is mostly ignored.
507 ///
508 /// There are two use cases for the Knowledge class:
509 ///
510 /// 1) To represent the knowledge of the current state of ScopInfo. The unused
511 ///    state means that an element is currently unused: there is no read of it
512 ///    before the next overwrite. Also called 'Existing'.
513 ///
514 /// 2) To represent the requirements for mapping a scalar to array elements. The
515 ///    unused state means that there is no change/requirement. Also called
516 ///    'Proposed'.
517 ///
518 /// In addition to these states at unit zones, Knowledge needs to know when
519 /// values are written. This is because written values may have no lifetime (one
520 /// reason is that the value is never read). Such writes would therefore never
521 /// conflict, but overwrite values that might still be required. Another source
522 /// of problems are multiple writes to the same element at the same timepoint,
523 /// because their order is undefined.
524 class Knowledge {
525 private:
526   /// { [Element[] -> Zone[]] }
527   /// Set of array elements and when they are alive.
528   /// Can contain a nullptr; in this case the set is implicitly defined as the
529   /// complement of #Unused.
530   ///
531   /// The set of alive array elements is represented as zone, as the set of live
532   /// values can differ depending on how the elements are interpreted.
533   /// Assuming a value X is written at timestep [0] and read at timestep [1]
534   /// without being used at any later point, then the value is alive in the
535   /// interval ]0,1[. This interval cannot be represented by an integer set, as
536   /// it does not contain any integer point. Zones allow us to represent this
537   /// interval and can be converted to sets of timepoints when needed (e.g., in
538   /// isConflicting when comparing to the write sets).
539   /// @see convertZoneToTimepoints and this file's comment for more details.
540   isl::union_set Occupied;
541 
542   /// { [Element[] -> Zone[]] }
543   /// Set of array elements when they are not alive, i.e. their memory can be
544   /// used for other purposed. Can contain a nullptr; in this case the set is
545   /// implicitly defined as the complement of #Occupied.
546   isl::union_set Unused;
547 
548   /// { [Element[] -> Zone[]] -> ValInst[] }
549   /// Maps to the known content for each array element at any interval.
550   ///
551   /// Any element/interval can map to multiple known elements. This is due to
552   /// multiple llvm::Value referring to the same content. Examples are
553   ///
554   /// - A value stored and loaded again. The LoadInst represents the same value
555   /// as the StoreInst's value operand.
556   ///
557   /// - A PHINode is equal to any one of the incoming values. In case of
558   /// LCSSA-form, it is always equal to its single incoming value.
559   ///
560   /// Two Knowledges are considered not conflicting if at least one of the known
561   /// values match. Not known values are not stored as an unnamed tuple (as
562   /// #Written does), but maps to nothing.
563   ///
564   ///  Known values are usually just defined for #Occupied elements. Knowing
565   ///  #Unused contents has no advantage as it can be overwritten.
566   isl::union_map Known;
567 
568   /// { [Element[] -> Scatter[]] -> ValInst[] }
569   /// The write actions currently in the scop or that would be added when
570   /// mapping a scalar. Maps to the value that is written.
571   ///
572   /// Written values that cannot be identified are represented by an unknown
573   /// ValInst[] (an unnamed tuple of 0 dimension). It conflicts with itself.
574   isl::union_map Written;
575 
576   /// Check whether this Knowledge object is well-formed.
577   void checkConsistency() const {
578 #ifndef NDEBUG
579     // Default-initialized object
580     if (!Occupied && !Unused && !Known && !Written)
581       return;
582 
583     assert(Occupied || Unused);
584     assert(Known);
585     assert(Written);
586 
587     // If not all fields are defined, we cannot derived the universe.
588     if (!Occupied || !Unused)
589       return;
590 
591     assert(isl_union_set_is_disjoint(Occupied.keep(), Unused.keep()) ==
592            isl_bool_true);
593     auto Universe = give(isl_union_set_union(Occupied.copy(), Unused.copy()));
594 
595     assert(!Known.domain().is_subset(Universe).is_false());
596     assert(!Written.domain().is_subset(Universe).is_false());
597 #endif
598   }
599 
600 public:
601   /// Initialize a nullptr-Knowledge. This is only provided for convenience; do
602   /// not use such an object.
603   Knowledge() {}
604 
605   /// Create a new object with the given members.
606   Knowledge(isl::union_set Occupied, isl::union_set Unused,
607             isl::union_map Known, isl::union_map Written)
608       : Occupied(std::move(Occupied)), Unused(std::move(Unused)),
609         Known(std::move(Known)), Written(std::move(Written)) {
610     checkConsistency();
611   }
612 
613   /// Return whether this object was not default-constructed.
614   bool isUsable() const { return (Occupied || Unused) && Known && Written; }
615 
616   /// Print the content of this object to @p OS.
617   void print(llvm::raw_ostream &OS, unsigned Indent = 0) const {
618     if (isUsable()) {
619       if (Occupied)
620         OS.indent(Indent) << "Occupied: " << Occupied << "\n";
621       else
622         OS.indent(Indent) << "Occupied: <Everything else not in Unused>\n";
623       if (Unused)
624         OS.indent(Indent) << "Unused:   " << Unused << "\n";
625       else
626         OS.indent(Indent) << "Unused:   <Everything else not in Occupied>\n";
627       OS.indent(Indent) << "Known:    " << Known << "\n";
628       OS.indent(Indent) << "Written : " << Written << '\n';
629     } else {
630       OS.indent(Indent) << "Invalid knowledge\n";
631     }
632   }
633 
634   /// Combine two knowledges, this and @p That.
635   void learnFrom(Knowledge That) {
636     assert(!isConflicting(*this, That));
637     assert(Unused && That.Occupied);
638     assert(
639         !That.Unused &&
640         "This function is only prepared to learn occupied elements from That");
641     assert(!Occupied && "This function does not implement "
642                         "`this->Occupied = "
643                         "give(isl_union_set_union(this->Occupied.take(), "
644                         "That.Occupied.copy()));`");
645 
646     Unused = give(isl_union_set_subtract(Unused.take(), That.Occupied.copy()));
647     Known = give(isl_union_map_union(Known.take(), That.Known.copy()));
648     Written = give(isl_union_map_union(Written.take(), That.Written.take()));
649 
650     checkConsistency();
651   }
652 
653   /// Determine whether two Knowledges conflict with each other.
654   ///
655   /// In theory @p Existing and @p Proposed are symmetric, but the
656   /// implementation is constrained by the implicit interpretation. That is, @p
657   /// Existing must have #Unused defined (use case 1) and @p Proposed must have
658   /// #Occupied defined (use case 1).
659   ///
660   /// A conflict is defined as non-preserved semantics when they are merged. For
661   /// instance, when for the same array and zone they assume different
662   /// llvm::Values.
663   ///
664   /// @param Existing One of the knowledges with #Unused defined.
665   /// @param Proposed One of the knowledges with #Occupied defined.
666   /// @param OS       Dump the conflict reason to this output stream; use
667   ///                 nullptr to not output anything.
668   /// @param Indent   Indention for the conflict reason.
669   ///
670   /// @return True, iff the two knowledges are conflicting.
671   static bool isConflicting(const Knowledge &Existing,
672                             const Knowledge &Proposed,
673                             llvm::raw_ostream *OS = nullptr,
674                             unsigned Indent = 0) {
675     assert(Existing.Unused);
676     assert(Proposed.Occupied);
677 
678 #ifndef NDEBUG
679     if (Existing.Occupied && Proposed.Unused) {
680       auto ExistingUniverse = give(isl_union_set_union(Existing.Occupied.copy(),
681                                                        Existing.Unused.copy()));
682       auto ProposedUniverse = give(isl_union_set_union(Proposed.Occupied.copy(),
683                                                        Proposed.Unused.copy()));
684       assert(isl_union_set_is_equal(ExistingUniverse.keep(),
685                                     ProposedUniverse.keep()) == isl_bool_true &&
686              "Both inputs' Knowledges must be over the same universe");
687     }
688 #endif
689 
690     // Do the Existing and Proposed lifetimes conflict?
691     //
692     // Lifetimes are described as the cross-product of array elements and zone
693     // intervals in which they are alive (the space { [Element[] -> Zone[]] }).
694     // In the following we call this "element/lifetime interval".
695     //
696     // In order to not conflict, one of the following conditions must apply for
697     // each element/lifetime interval:
698     //
699     // 1. If occupied in one of the knowledges, it is unused in the other.
700     //
701     //   - or -
702     //
703     // 2. Both contain the same value.
704     //
705     // Instead of partitioning the element/lifetime intervals into a part that
706     // both Knowledges occupy (which requires an expensive subtraction) and for
707     // these to check whether they are known to be the same value, we check only
708     // the second condition and ensure that it also applies when then first
709     // condition is true. This is done by adding a wildcard value to
710     // Proposed.Known and Existing.Unused such that they match as a common known
711     // value. We use the "unknown ValInst" for this purpose. Every
712     // Existing.Unused may match with an unknown Proposed.Occupied because these
713     // never are in conflict with each other.
714     auto ProposedOccupiedAnyVal = makeUnknownForDomain(Proposed.Occupied);
715     auto ProposedValues = Proposed.Known.unite(ProposedOccupiedAnyVal);
716 
717     auto ExistingUnusedAnyVal = makeUnknownForDomain(Existing.Unused);
718     auto ExistingValues = Existing.Known.unite(ExistingUnusedAnyVal);
719 
720     auto MatchingVals = ExistingValues.intersect(ProposedValues);
721     auto Matches = MatchingVals.domain();
722 
723     // Any Proposed.Occupied must either have a match between the known values
724     // of Existing and Occupied, or be in Existing.Unused. In the latter case,
725     // the previously added "AnyVal" will match each other.
726     if (!Proposed.Occupied.is_subset(Matches)) {
727       if (OS) {
728         auto Conflicting = Proposed.Occupied.subtract(Matches);
729         auto ExistingConflictingKnown =
730             Existing.Known.intersect_domain(Conflicting);
731         auto ProposedConflictingKnown =
732             Proposed.Known.intersect_domain(Conflicting);
733 
734         OS->indent(Indent) << "Proposed lifetime conflicting with Existing's\n";
735         OS->indent(Indent) << "Conflicting occupied: " << Conflicting << "\n";
736         if (!ExistingConflictingKnown.is_empty())
737           OS->indent(Indent)
738               << "Existing Known:       " << ExistingConflictingKnown << "\n";
739         if (!ProposedConflictingKnown.is_empty())
740           OS->indent(Indent)
741               << "Proposed Known:       " << ProposedConflictingKnown << "\n";
742       }
743       return true;
744     }
745 
746     // Do the writes in Existing conflict with occupied values in Proposed?
747     //
748     // In order to not conflict, it must either write to unused lifetime or
749     // write the same value. To check, we remove the writes that write into
750     // Proposed.Unused (they never conflict) and then see whether the written
751     // value is already in Proposed.Known. If there are multiple known values
752     // and a written value is known under different names, it is enough when one
753     // of the written values (assuming that they are the same value under
754     // different names, e.g. a PHINode and one of the incoming values) matches
755     // one of the known names.
756     //
757     // We convert here the set of lifetimes to actual timepoints. A lifetime is
758     // in conflict with a set of write timepoints, if either a live timepoint is
759     // clearly within the lifetime or if a write happens at the beginning of the
760     // lifetime (where it would conflict with the value that actually writes the
761     // value alive). There is no conflict at the end of a lifetime, as the alive
762     // value will always be read, before it is overwritten again. The last
763     // property holds in Polly for all scalar values and we expect all users of
764     // Knowledge to check this property also for accesses to MemoryKind::Array.
765     auto ProposedFixedDefs =
766         convertZoneToTimepoints(Proposed.Occupied, true, false);
767     auto ProposedFixedKnown =
768         convertZoneToTimepoints(Proposed.Known, isl::dim::in, true, false);
769 
770     auto ExistingConflictingWrites =
771         Existing.Written.intersect_domain(ProposedFixedDefs);
772     auto ExistingConflictingWritesDomain = ExistingConflictingWrites.domain();
773 
774     auto CommonWrittenVal =
775         ProposedFixedKnown.intersect(ExistingConflictingWrites);
776     auto CommonWrittenValDomain = CommonWrittenVal.domain();
777 
778     if (!ExistingConflictingWritesDomain.is_subset(CommonWrittenValDomain)) {
779       if (OS) {
780         auto ExistingConflictingWritten =
781             ExistingConflictingWrites.subtract_domain(CommonWrittenValDomain);
782         auto ProposedConflictingKnown = ProposedFixedKnown.subtract_domain(
783             ExistingConflictingWritten.domain());
784 
785         OS->indent(Indent)
786             << "Proposed a lifetime where there is an Existing write into it\n";
787         OS->indent(Indent) << "Existing conflicting writes: "
788                            << ExistingConflictingWritten << "\n";
789         if (!ProposedConflictingKnown.is_empty())
790           OS->indent(Indent)
791               << "Proposed conflicting known:  " << ProposedConflictingKnown
792               << "\n";
793       }
794       return true;
795     }
796 
797     // Do the writes in Proposed conflict with occupied values in Existing?
798     auto ExistingAvailableDefs =
799         convertZoneToTimepoints(Existing.Unused, true, false);
800     auto ExistingKnownDefs =
801         convertZoneToTimepoints(Existing.Known, isl::dim::in, true, false);
802 
803     auto ProposedWrittenDomain = Proposed.Written.domain();
804     auto KnownIdentical = ExistingKnownDefs.intersect(Proposed.Written);
805     auto IdenticalOrUnused =
806         ExistingAvailableDefs.unite(KnownIdentical.domain());
807     if (!ProposedWrittenDomain.is_subset(IdenticalOrUnused)) {
808       if (OS) {
809         auto Conflicting = ProposedWrittenDomain.subtract(IdenticalOrUnused);
810         auto ExistingConflictingKnown =
811             ExistingKnownDefs.intersect_domain(Conflicting);
812         auto ProposedConflictingWritten =
813             Proposed.Written.intersect_domain(Conflicting);
814 
815         OS->indent(Indent) << "Proposed writes into range used by Existing\n";
816         OS->indent(Indent) << "Proposed conflicting writes: "
817                            << ProposedConflictingWritten << "\n";
818         if (!ExistingConflictingKnown.is_empty())
819           OS->indent(Indent)
820               << "Existing conflicting known: " << ExistingConflictingKnown
821               << "\n";
822       }
823       return true;
824     }
825 
826     // Does Proposed write at the same time as Existing already does (order of
827     // writes is undefined)? Writing the same value is permitted.
828     auto ExistingWrittenDomain =
829         isl::manage(isl_union_map_domain(Existing.Written.copy()));
830     auto BothWritten =
831         Existing.Written.domain().intersect(Proposed.Written.domain());
832     auto ExistingKnownWritten = filterKnownValInst(Existing.Written);
833     auto ProposedKnownWritten = filterKnownValInst(Proposed.Written);
834     auto CommonWritten =
835         ExistingKnownWritten.intersect(ProposedKnownWritten).domain();
836 
837     if (!BothWritten.is_subset(CommonWritten)) {
838       if (OS) {
839         auto Conflicting = BothWritten.subtract(CommonWritten);
840         auto ExistingConflictingWritten =
841             Existing.Written.intersect_domain(Conflicting);
842         auto ProposedConflictingWritten =
843             Proposed.Written.intersect_domain(Conflicting);
844 
845         OS->indent(Indent) << "Proposed writes at the same time as an already "
846                               "Existing write\n";
847         OS->indent(Indent) << "Conflicting writes: " << Conflicting << "\n";
848         if (!ExistingConflictingWritten.is_empty())
849           OS->indent(Indent)
850               << "Exiting write:      " << ExistingConflictingWritten << "\n";
851         if (!ProposedConflictingWritten.is_empty())
852           OS->indent(Indent)
853               << "Proposed write:     " << ProposedConflictingWritten << "\n";
854       }
855       return true;
856     }
857 
858     return false;
859   }
860 };
861 
862 std::string printIntruction(Instruction *Instr, bool IsForDebug = false) {
863   std::string Result;
864   raw_string_ostream OS(Result);
865   Instr->print(OS, IsForDebug);
866   OS.flush();
867   size_t i = 0;
868   while (i < Result.size() && Result[i] == ' ')
869     i += 1;
870   return Result.substr(i);
871 }
872 
873 /// Base class for algorithms based on zones, like DeLICM.
874 class ZoneAlgorithm {
875 protected:
876   /// Hold a reference to the isl_ctx to avoid it being freed before we released
877   /// all of the isl objects.
878   ///
879   /// This must be declared before any other member that holds an isl object.
880   /// This guarantees that the shared_ptr and its isl_ctx is destructed last,
881   /// after all other members free'd the isl objects they were holding.
882   std::shared_ptr<isl_ctx> IslCtx;
883 
884   /// Cached reaching definitions for each ScopStmt.
885   ///
886   /// Use getScalarReachingDefinition() to get its contents.
887   DenseMap<ScopStmt *, isl::map> ScalarReachDefZone;
888 
889   /// The analyzed Scop.
890   Scop *S;
891 
892   /// LoopInfo analysis used to determine whether values are synthesizable.
893   LoopInfo *LI;
894 
895   /// Parameter space that does not need realignment.
896   isl::space ParamSpace;
897 
898   /// Space the schedule maps to.
899   isl::space ScatterSpace;
900 
901   /// Cached version of the schedule and domains.
902   isl::union_map Schedule;
903 
904   /// Combined access relations of all MemoryKind::Array READ accesses.
905   /// { DomainRead[] -> Element[] }
906   isl::union_map AllReads;
907 
908   /// Combined access relations of all MemoryKind::Array, MAY_WRITE accesses.
909   /// { DomainMayWrite[] -> Element[] }
910   isl::union_map AllMayWrites;
911 
912   /// Combined access relations of all MemoryKind::Array, MUST_WRITE accesses.
913   /// { DomainMustWrite[] -> Element[] }
914   isl::union_map AllMustWrites;
915 
916   /// The value instances written to array elements of all write accesses.
917   /// { [Element[] -> DomainWrite[]] -> ValInst[] }
918   isl::union_map AllWriteValInst;
919 
920   /// All reaching definitions for  MemoryKind::Array writes.
921   /// { [Element[] -> Zone[]] -> DomainWrite[] }
922   isl::union_map WriteReachDefZone;
923 
924   /// Map llvm::Values to an isl identifier.
925   /// Used with -polly-use-llvm-names=false as an alternative method to get
926   /// unique ids that do not depend on pointer values.
927   DenseMap<Value *, isl::id> ValueIds;
928 
929   /// Prepare the object before computing the zones of @p S.
930   ZoneAlgorithm(Scop *S, LoopInfo *LI)
931       : IslCtx(S->getSharedIslCtx()), S(S), LI(LI),
932         Schedule(give(S->getSchedule())) {
933 
934     auto Domains = give(S->getDomains());
935 
936     Schedule =
937         give(isl_union_map_intersect_domain(Schedule.take(), Domains.take()));
938     ParamSpace = give(isl_union_map_get_space(Schedule.keep()));
939     ScatterSpace = getScatterSpace(Schedule);
940   }
941 
942 private:
943   /// Check whether @p Stmt can be accurately analyzed by zones.
944   ///
945   /// What violates our assumptions:
946   /// - A load after a write of the same location; we assume that all reads
947   ///   occur before the writes.
948   /// - Two writes to the same location; we cannot model the order in which
949   ///   these occur.
950   ///
951   /// Scalar reads implicitly always occur before other accesses therefore never
952   /// violate the first condition. There is also at most one write to a scalar,
953   /// satisfying the second condition.
954   bool isCompatibleStmt(ScopStmt *Stmt) {
955     auto Stores = makeEmptyUnionMap();
956     auto Loads = makeEmptyUnionMap();
957 
958     // This assumes that the MemoryKind::Array MemoryAccesses are iterated in
959     // order.
960     for (auto *MA : *Stmt) {
961       if (!MA->isLatestArrayKind())
962         continue;
963 
964       auto AccRel =
965           give(isl_union_map_from_map(getAccessRelationFor(MA).take()));
966 
967       if (MA->isRead()) {
968         // Reject load after store to same location.
969         if (!isl_union_map_is_disjoint(Stores.keep(), AccRel.keep())) {
970           OptimizationRemarkMissed R(DEBUG_TYPE, "LoadAfterStore",
971                                      MA->getAccessInstruction());
972           R << "load after store of same element in same statement";
973           R << " (previous stores: " << Stores;
974           R << ", loading: " << AccRel << ")";
975           S->getFunction().getContext().diagnose(R);
976           return false;
977         }
978 
979         Loads = give(isl_union_map_union(Loads.take(), AccRel.take()));
980 
981         continue;
982       }
983 
984       if (!isa<StoreInst>(MA->getAccessInstruction())) {
985         DEBUG(dbgs() << "WRITE that is not a StoreInst not supported\n");
986         OptimizationRemarkMissed R(DEBUG_TYPE, "UnusualStore",
987                                    MA->getAccessInstruction());
988         R << "encountered write that is not a StoreInst: "
989           << printIntruction(MA->getAccessInstruction());
990         S->getFunction().getContext().diagnose(R);
991         return false;
992       }
993 
994       // In region statements the order is less clear, eg. the load and store
995       // might be in a boxed loop.
996       if (Stmt->isRegionStmt() &&
997           !isl_union_map_is_disjoint(Loads.keep(), AccRel.keep())) {
998         OptimizationRemarkMissed R(DEBUG_TYPE, "StoreInSubregion",
999                                    MA->getAccessInstruction());
1000         R << "store is in a non-affine subregion";
1001         S->getFunction().getContext().diagnose(R);
1002         return false;
1003       }
1004 
1005       // Do not allow more than one store to the same location.
1006       if (!isl_union_map_is_disjoint(Stores.keep(), AccRel.keep())) {
1007         OptimizationRemarkMissed R(DEBUG_TYPE, "StoreAfterStore",
1008                                    MA->getAccessInstruction());
1009         R << "store after store of same element in same statement";
1010         R << " (previous stores: " << Stores;
1011         R << ", storing: " << AccRel << ")";
1012         S->getFunction().getContext().diagnose(R);
1013         return false;
1014       }
1015 
1016       Stores = give(isl_union_map_union(Stores.take(), AccRel.take()));
1017     }
1018 
1019     return true;
1020   }
1021 
1022   void addArrayReadAccess(MemoryAccess *MA) {
1023     assert(MA->isLatestArrayKind());
1024     assert(MA->isRead());
1025 
1026     // { DomainRead[] -> Element[] }
1027     auto AccRel = getAccessRelationFor(MA);
1028     AllReads = give(isl_union_map_add_map(AllReads.take(), AccRel.copy()));
1029   }
1030 
1031   void addArrayWriteAccess(MemoryAccess *MA) {
1032     assert(MA->isLatestArrayKind());
1033     assert(MA->isWrite());
1034     auto *Stmt = MA->getStatement();
1035 
1036     // { Domain[] -> Element[] }
1037     auto AccRel = getAccessRelationFor(MA);
1038 
1039     if (MA->isMustWrite())
1040       AllMustWrites =
1041           give(isl_union_map_add_map(AllMustWrites.take(), AccRel.copy()));
1042 
1043     if (MA->isMayWrite())
1044       AllMayWrites =
1045           give(isl_union_map_add_map(AllMayWrites.take(), AccRel.copy()));
1046 
1047     // { Domain[] -> ValInst[] }
1048     auto WriteValInstance =
1049         makeValInst(MA->getAccessValue(), Stmt,
1050                     LI->getLoopFor(MA->getAccessInstruction()->getParent()),
1051                     MA->isMustWrite());
1052 
1053     // { Domain[] -> [Element[] -> Domain[]] }
1054     auto IncludeElement =
1055         give(isl_map_curry(isl_map_domain_map(AccRel.copy())));
1056 
1057     // { [Element[] -> DomainWrite[]] -> ValInst[] }
1058     auto EltWriteValInst = give(
1059         isl_map_apply_domain(WriteValInstance.take(), IncludeElement.take()));
1060 
1061     AllWriteValInst = give(
1062         isl_union_map_add_map(AllWriteValInst.take(), EltWriteValInst.take()));
1063   }
1064 
1065 protected:
1066   isl::union_set makeEmptyUnionSet() const {
1067     return give(isl_union_set_empty(ParamSpace.copy()));
1068   }
1069 
1070   isl::union_map makeEmptyUnionMap() const {
1071     return give(isl_union_map_empty(ParamSpace.copy()));
1072   }
1073 
1074   /// Check whether @p S can be accurately analyzed by zones.
1075   bool isCompatibleScop() {
1076     for (auto &Stmt : *S) {
1077       if (!isCompatibleStmt(&Stmt))
1078         return false;
1079     }
1080     return true;
1081   }
1082 
1083   /// Get the schedule for @p Stmt.
1084   ///
1085   /// The domain of the result is as narrow as possible.
1086   isl::map getScatterFor(ScopStmt *Stmt) const {
1087     auto ResultSpace = give(isl_space_map_from_domain_and_range(
1088         Stmt->getDomainSpace(), ScatterSpace.copy()));
1089     return give(isl_union_map_extract_map(Schedule.keep(), ResultSpace.take()));
1090   }
1091 
1092   /// Get the schedule of @p MA's parent statement.
1093   isl::map getScatterFor(MemoryAccess *MA) const {
1094     return getScatterFor(MA->getStatement());
1095   }
1096 
1097   /// Get the schedule for the statement instances of @p Domain.
1098   isl::union_map getScatterFor(isl::union_set Domain) const {
1099     return give(isl_union_map_intersect_domain(Schedule.copy(), Domain.take()));
1100   }
1101 
1102   /// Get the schedule for the statement instances of @p Domain.
1103   isl::map getScatterFor(isl::set Domain) const {
1104     auto ResultSpace = give(isl_space_map_from_domain_and_range(
1105         isl_set_get_space(Domain.keep()), ScatterSpace.copy()));
1106     auto UDomain = give(isl_union_set_from_set(Domain.copy()));
1107     auto UResult = getScatterFor(std::move(UDomain));
1108     auto Result = singleton(std::move(UResult), std::move(ResultSpace));
1109     assert(!Result ||
1110            isl_set_is_equal(give(isl_map_domain(Result.copy())).keep(),
1111                             Domain.keep()) == isl_bool_true);
1112     return Result;
1113   }
1114 
1115   /// Get the domain of @p Stmt.
1116   isl::set getDomainFor(ScopStmt *Stmt) const {
1117     return give(isl_set_remove_redundancies(Stmt->getDomain()));
1118   }
1119 
1120   /// Get the domain @p MA's parent statement.
1121   isl::set getDomainFor(MemoryAccess *MA) const {
1122     return getDomainFor(MA->getStatement());
1123   }
1124 
1125   /// Get the access relation of @p MA.
1126   ///
1127   /// The domain of the result is as narrow as possible.
1128   isl::map getAccessRelationFor(MemoryAccess *MA) const {
1129     auto Domain = getDomainFor(MA);
1130     auto AccRel = give(MA->getLatestAccessRelation());
1131     return give(isl_map_intersect_domain(AccRel.take(), Domain.take()));
1132   }
1133 
1134   /// Get the reaching definition of a scalar defined in @p Stmt.
1135   ///
1136   /// Note that this does not depend on the llvm::Instruction, only on the
1137   /// statement it is defined in. Therefore the same computation can be reused.
1138   ///
1139   /// @param Stmt The statement in which a scalar is defined.
1140   ///
1141   /// @return { Scatter[] -> DomainDef[] }
1142   isl::map getScalarReachingDefinition(ScopStmt *Stmt) {
1143     auto &Result = ScalarReachDefZone[Stmt];
1144     if (Result)
1145       return Result;
1146 
1147     auto Domain = getDomainFor(Stmt);
1148     Result = computeScalarReachingDefinition(Schedule, Domain, false, true);
1149     simplify(Result);
1150 
1151     return Result;
1152   }
1153 
1154   /// Get the reaching definition of a scalar defined in @p DefDomain.
1155   ///
1156   /// @param DomainDef { DomainDef[] }
1157   ///              The write statements to get the reaching definition for.
1158   ///
1159   /// @return { Scatter[] -> DomainDef[] }
1160   isl::map getScalarReachingDefinition(isl::set DomainDef) {
1161     auto DomId = give(isl_set_get_tuple_id(DomainDef.keep()));
1162     auto *Stmt = static_cast<ScopStmt *>(isl_id_get_user(DomId.keep()));
1163 
1164     auto StmtResult = getScalarReachingDefinition(Stmt);
1165 
1166     return give(isl_map_intersect_range(StmtResult.take(), DomainDef.take()));
1167   }
1168 
1169   /// Create a statement-to-unknown value mapping.
1170   ///
1171   /// @param Stmt The statement whose instances are mapped to unknown.
1172   ///
1173   /// @return { Domain[] -> ValInst[] }
1174   isl::map makeUnknownForDomain(ScopStmt *Stmt) const {
1175     return ::makeUnknownForDomain(getDomainFor(Stmt));
1176   }
1177 
1178   /// Create an isl_id that represents @p V.
1179   isl::id makeValueId(Value *V) {
1180     if (!V)
1181       return nullptr;
1182 
1183     auto &Id = ValueIds[V];
1184     if (Id.is_null()) {
1185       auto Name = getIslCompatibleName("Val_", V, ValueIds.size() - 1,
1186                                        std::string(), UseInstructionNames);
1187       Id = give(isl_id_alloc(IslCtx.get(), Name.c_str(), V));
1188     }
1189     return Id;
1190   }
1191 
1192   /// Create the space for an llvm::Value that is available everywhere.
1193   isl::space makeValueSpace(Value *V) {
1194     auto Result = give(isl_space_set_from_params(ParamSpace.copy()));
1195     return give(isl_space_set_tuple_id(Result.take(), isl_dim_set,
1196                                        makeValueId(V).take()));
1197   }
1198 
1199   /// Create a set with the llvm::Value @p V which is available everywhere.
1200   isl::set makeValueSet(Value *V) {
1201     auto Space = makeValueSpace(V);
1202     return give(isl_set_universe(Space.take()));
1203   }
1204 
1205   /// Create a mapping from a statement instance to the instance of an
1206   /// llvm::Value that can be used in there.
1207   ///
1208   /// Although LLVM IR uses single static assignment, llvm::Values can have
1209   /// different contents in loops, when they get redefined in the last
1210   /// iteration. This function tries to get the statement instance of the
1211   /// previous definition, relative to a user.
1212   ///
1213   /// Example:
1214   /// for (int i = 0; i < N; i += 1) {
1215   /// DEF:
1216   ///    int v = A[i];
1217   /// USE:
1218   ///    use(v);
1219   ///  }
1220   ///
1221   /// The value instance used by statement instance USE[i] is DEF[i]. Hence,
1222   /// makeValInst returns:
1223   ///
1224   /// { USE[i] -> [DEF[i] -> v[]] : 0 <= i < N }
1225   ///
1226   /// @param Val       The value to get the instance of.
1227   /// @param UserStmt  The statement that uses @p Val. Can be nullptr.
1228   /// @param Scope     Loop the using instruction resides in.
1229   /// @param IsCertain Pass true if the definition of @p Val is a
1230   ///                  MUST_WRITE or false if the write is conditional.
1231   ///
1232   /// @return { DomainUse[] -> ValInst[] }
1233   isl::map makeValInst(Value *Val, ScopStmt *UserStmt, Loop *Scope,
1234                        bool IsCertain = true) {
1235     // When known knowledge is disabled, just return the unknown value. It will
1236     // either get filtered out or conflict with itself.
1237     if (!DelicmComputeKnown)
1238       return makeUnknownForDomain(UserStmt);
1239 
1240     // If the definition/write is conditional, the value at the location could
1241     // be either the written value or the old value. Since we cannot know which
1242     // one, consider the value to be unknown.
1243     if (!IsCertain)
1244       return makeUnknownForDomain(UserStmt);
1245 
1246     auto DomainUse = getDomainFor(UserStmt);
1247     auto VUse = VirtualUse::create(S, UserStmt, Scope, Val, true);
1248     switch (VUse.getKind()) {
1249     case VirtualUse::Constant:
1250     case VirtualUse::Block:
1251     case VirtualUse::Hoisted:
1252     case VirtualUse::ReadOnly: {
1253       // The definition does not depend on the statement which uses it.
1254       auto ValSet = makeValueSet(Val);
1255       return give(
1256           isl_map_from_domain_and_range(DomainUse.take(), ValSet.take()));
1257     }
1258 
1259     case VirtualUse::Synthesizable: {
1260       auto *ScevExpr = VUse.getScevExpr();
1261       auto UseDomainSpace = give(isl_set_get_space(DomainUse.keep()));
1262 
1263       // Construct the SCEV space.
1264       // TODO: Add only the induction variables referenced in SCEVAddRecExpr
1265       // expressions, not just all of them.
1266       auto ScevId = give(isl_id_alloc(UseDomainSpace.get_ctx().get(), nullptr,
1267                                       const_cast<SCEV *>(ScevExpr)));
1268       auto ScevSpace =
1269           give(isl_space_drop_dims(UseDomainSpace.copy(), isl_dim_set, 0, 0));
1270       ScevSpace = give(
1271           isl_space_set_tuple_id(ScevSpace.take(), isl_dim_set, ScevId.copy()));
1272 
1273       // { DomainUse[] -> ScevExpr[] }
1274       auto ValInst = give(isl_map_identity(isl_space_map_from_domain_and_range(
1275           UseDomainSpace.copy(), ScevSpace.copy())));
1276       return ValInst;
1277     }
1278 
1279     case VirtualUse::Intra: {
1280       // Definition and use is in the same statement. We do not need to compute
1281       // a reaching definition.
1282 
1283       // { llvm::Value }
1284       auto ValSet = makeValueSet(Val);
1285 
1286       // {  UserDomain[] -> llvm::Value }
1287       auto ValInstSet =
1288           give(isl_map_from_domain_and_range(DomainUse.take(), ValSet.take()));
1289 
1290       // { UserDomain[] -> [UserDomain[] - >llvm::Value] }
1291       auto Result =
1292           give(isl_map_reverse(isl_map_domain_map(ValInstSet.take())));
1293       simplify(Result);
1294       return Result;
1295     }
1296 
1297     case VirtualUse::Inter: {
1298       // The value is defined in a different statement.
1299 
1300       auto *Inst = cast<Instruction>(Val);
1301       auto *ValStmt = S->getStmtFor(Inst);
1302 
1303       // If the llvm::Value is defined in a removed Stmt, we cannot derive its
1304       // domain. We could use an arbitrary statement, but this could result in
1305       // different ValInst[] for the same llvm::Value.
1306       if (!ValStmt)
1307         return ::makeUnknownForDomain(DomainUse);
1308 
1309       // { DomainDef[] }
1310       auto DomainDef = getDomainFor(ValStmt);
1311 
1312       // { Scatter[] -> DomainDef[] }
1313       auto ReachDef = getScalarReachingDefinition(DomainDef);
1314 
1315       // { DomainUse[] -> Scatter[] }
1316       auto UserSched = getScatterFor(DomainUse);
1317 
1318       // { DomainUse[] -> DomainDef[] }
1319       auto UsedInstance =
1320           give(isl_map_apply_range(UserSched.take(), ReachDef.take()));
1321 
1322       // { llvm::Value }
1323       auto ValSet = makeValueSet(Val);
1324 
1325       // { DomainUse[] -> llvm::Value[] }
1326       auto ValInstSet =
1327           give(isl_map_from_domain_and_range(DomainUse.take(), ValSet.take()));
1328 
1329       // { DomainUse[] -> [DomainDef[] -> llvm::Value]  }
1330       auto Result =
1331           give(isl_map_range_product(UsedInstance.take(), ValInstSet.take()));
1332 
1333       simplify(Result);
1334       return Result;
1335     }
1336     }
1337     llvm_unreachable("Unhandled use type");
1338   }
1339 
1340   /// Compute the different zones.
1341   void computeCommon() {
1342     AllReads = makeEmptyUnionMap();
1343     AllMayWrites = makeEmptyUnionMap();
1344     AllMustWrites = makeEmptyUnionMap();
1345     AllWriteValInst = makeEmptyUnionMap();
1346 
1347     for (auto &Stmt : *S) {
1348       for (auto *MA : Stmt) {
1349         if (!MA->isLatestArrayKind())
1350           continue;
1351 
1352         if (MA->isRead())
1353           addArrayReadAccess(MA);
1354 
1355         if (MA->isWrite())
1356           addArrayWriteAccess(MA);
1357       }
1358     }
1359 
1360     // { DomainWrite[] -> Element[] }
1361     auto AllWrites =
1362         give(isl_union_map_union(AllMustWrites.copy(), AllMayWrites.copy()));
1363 
1364     // { [Element[] -> Zone[]] -> DomainWrite[] }
1365     WriteReachDefZone =
1366         computeReachingDefinition(Schedule, AllWrites, false, true);
1367     simplify(WriteReachDefZone);
1368   }
1369 
1370   /// Print the current state of all MemoryAccesses to @p.
1371   void printAccesses(llvm::raw_ostream &OS, int Indent = 0) const {
1372     OS.indent(Indent) << "After accesses {\n";
1373     for (auto &Stmt : *S) {
1374       OS.indent(Indent + 4) << Stmt.getBaseName() << "\n";
1375       for (auto *MA : Stmt)
1376         MA->print(OS);
1377     }
1378     OS.indent(Indent) << "}\n";
1379   }
1380 
1381 public:
1382   /// Return the SCoP this object is analyzing.
1383   Scop *getScop() const { return S; }
1384 };
1385 
1386 /// Implementation of the DeLICM/DePRE transformation.
1387 class DeLICMImpl : public ZoneAlgorithm {
1388 private:
1389   /// Knowledge before any transformation took place.
1390   Knowledge OriginalZone;
1391 
1392   /// Current knowledge of the SCoP including all already applied
1393   /// transformations.
1394   Knowledge Zone;
1395 
1396   /// For getting the MemoryAccesses that write or read a given scalar.
1397   ScalarDefUseChains DefUse;
1398 
1399   /// Number of StoreInsts something can be mapped to.
1400   int NumberOfCompatibleTargets = 0;
1401 
1402   /// The number of StoreInsts to which at least one value or PHI has been
1403   /// mapped to.
1404   int NumberOfTargetsMapped = 0;
1405 
1406   /// The number of llvm::Value mapped to some array element.
1407   int NumberOfMappedValueScalars = 0;
1408 
1409   /// The number of PHIs mapped to some array element.
1410   int NumberOfMappedPHIScalars = 0;
1411 
1412   /// Determine whether two knowledges are conflicting with each other.
1413   ///
1414   /// @see Knowledge::isConflicting
1415   bool isConflicting(const Knowledge &Proposed) {
1416     raw_ostream *OS = nullptr;
1417     DEBUG(OS = &llvm::dbgs());
1418     return Knowledge::isConflicting(Zone, Proposed, OS, 4);
1419   }
1420 
1421   /// Determine whether @p SAI is a scalar that can be mapped to an array
1422   /// element.
1423   bool isMappable(const ScopArrayInfo *SAI) {
1424     assert(SAI);
1425 
1426     if (SAI->isValueKind()) {
1427       auto *MA = DefUse.getValueDef(SAI);
1428       if (!MA) {
1429         DEBUG(dbgs()
1430               << "    Reject because value is read-only within the scop\n");
1431         return false;
1432       }
1433 
1434       // Mapping if value is used after scop is not supported. The code
1435       // generator would need to reload the scalar after the scop, but it
1436       // does not have the information to where it is mapped to. Only the
1437       // MemoryAccesses have that information, not the ScopArrayInfo.
1438       auto Inst = MA->getAccessInstruction();
1439       for (auto User : Inst->users()) {
1440         if (!isa<Instruction>(User))
1441           return false;
1442         auto UserInst = cast<Instruction>(User);
1443 
1444         if (!S->contains(UserInst)) {
1445           DEBUG(dbgs() << "    Reject because value is escaping\n");
1446           return false;
1447         }
1448       }
1449 
1450       return true;
1451     }
1452 
1453     if (SAI->isPHIKind()) {
1454       auto *MA = DefUse.getPHIRead(SAI);
1455       assert(MA);
1456 
1457       // Mapping of an incoming block from before the SCoP is not supported by
1458       // the code generator.
1459       auto PHI = cast<PHINode>(MA->getAccessInstruction());
1460       for (auto Incoming : PHI->blocks()) {
1461         if (!S->contains(Incoming)) {
1462           DEBUG(dbgs() << "    Reject because at least one incoming block is "
1463                           "not in the scop region\n");
1464           return false;
1465         }
1466       }
1467 
1468       return true;
1469     }
1470 
1471     DEBUG(dbgs() << "    Reject ExitPHI or other non-value\n");
1472     return false;
1473   }
1474 
1475   /// Compute the uses of a MemoryKind::Value and its lifetime (from its
1476   /// definition to the last use).
1477   ///
1478   /// @param SAI The ScopArrayInfo representing the value's storage.
1479   ///
1480   /// @return { DomainDef[] -> DomainUse[] }, { DomainDef[] -> Zone[] }
1481   ///         First element is the set of uses for each definition.
1482   ///         The second is the lifetime of each definition.
1483   std::tuple<isl::union_map, isl::map>
1484   computeValueUses(const ScopArrayInfo *SAI) {
1485     assert(SAI->isValueKind());
1486 
1487     // { DomainRead[] }
1488     auto Reads = makeEmptyUnionSet();
1489 
1490     // Find all uses.
1491     for (auto *MA : DefUse.getValueUses(SAI))
1492       Reads =
1493           give(isl_union_set_add_set(Reads.take(), getDomainFor(MA).take()));
1494 
1495     // { DomainRead[] -> Scatter[] }
1496     auto ReadSchedule = getScatterFor(Reads);
1497 
1498     auto *DefMA = DefUse.getValueDef(SAI);
1499     assert(DefMA);
1500 
1501     // { DomainDef[] }
1502     auto Writes = getDomainFor(DefMA);
1503 
1504     // { DomainDef[] -> Scatter[] }
1505     auto WriteScatter = getScatterFor(Writes);
1506 
1507     // { Scatter[] -> DomainDef[] }
1508     auto ReachDef = getScalarReachingDefinition(DefMA->getStatement());
1509 
1510     // { [DomainDef[] -> Scatter[]] -> DomainUse[] }
1511     auto Uses = give(
1512         isl_union_map_apply_range(isl_union_map_from_map(isl_map_range_map(
1513                                       isl_map_reverse(ReachDef.take()))),
1514                                   isl_union_map_reverse(ReadSchedule.take())));
1515 
1516     // { DomainDef[] -> Scatter[] }
1517     auto UseScatter =
1518         singleton(give(isl_union_set_unwrap(isl_union_map_domain(Uses.copy()))),
1519                   give(isl_space_map_from_domain_and_range(
1520                       isl_set_get_space(Writes.keep()), ScatterSpace.copy())));
1521 
1522     // { DomainDef[] -> Zone[] }
1523     auto Lifetime = betweenScatter(WriteScatter, UseScatter, false, true);
1524 
1525     // { DomainDef[] -> DomainRead[] }
1526     auto DefUses = give(isl_union_map_domain_factor_domain(Uses.take()));
1527 
1528     return std::make_pair(DefUses, Lifetime);
1529   }
1530 
1531   /// For each 'execution' of a PHINode, get the incoming block that was
1532   /// executed before.
1533   ///
1534   /// For each PHI instance we can directly determine which was the incoming
1535   /// block, and hence derive which value the PHI has.
1536   ///
1537   /// @param SAI The ScopArrayInfo representing the PHI's storage.
1538   ///
1539   /// @return { DomainPHIRead[] -> DomainPHIWrite[] }
1540   isl::union_map computePerPHI(const ScopArrayInfo *SAI) {
1541     assert(SAI->isPHIKind());
1542 
1543     // { DomainPHIWrite[] -> Scatter[] }
1544     auto PHIWriteScatter = makeEmptyUnionMap();
1545 
1546     // Collect all incoming block timepoint.
1547     for (auto *MA : DefUse.getPHIIncomings(SAI)) {
1548       auto Scatter = getScatterFor(MA);
1549       PHIWriteScatter =
1550           give(isl_union_map_add_map(PHIWriteScatter.take(), Scatter.take()));
1551     }
1552 
1553     // { DomainPHIRead[] -> Scatter[] }
1554     auto PHIReadScatter = getScatterFor(DefUse.getPHIRead(SAI));
1555 
1556     // { DomainPHIRead[] -> Scatter[] }
1557     auto BeforeRead = beforeScatter(PHIReadScatter, true);
1558 
1559     // { Scatter[] }
1560     auto WriteTimes = singleton(
1561         give(isl_union_map_range(PHIWriteScatter.copy())), ScatterSpace);
1562 
1563     // { DomainPHIRead[] -> Scatter[] }
1564     auto PHIWriteTimes =
1565         give(isl_map_intersect_range(BeforeRead.take(), WriteTimes.take()));
1566     auto LastPerPHIWrites = give(isl_map_lexmax(PHIWriteTimes.take()));
1567 
1568     // { DomainPHIRead[] -> DomainPHIWrite[] }
1569     auto Result = give(isl_union_map_apply_range(
1570         isl_union_map_from_map(LastPerPHIWrites.take()),
1571         isl_union_map_reverse(PHIWriteScatter.take())));
1572     assert(isl_union_map_is_single_valued(Result.keep()) == isl_bool_true);
1573     assert(isl_union_map_is_injective(Result.keep()) == isl_bool_true);
1574     return Result;
1575   }
1576 
1577   /// Try to map a MemoryKind::Value to a given array element.
1578   ///
1579   /// @param SAI       Representation of the scalar's memory to map.
1580   /// @param TargetElt { Scatter[] -> Element[] }
1581   ///                  Suggestion where to map a scalar to when at a timepoint.
1582   ///
1583   /// @return true if the scalar was successfully mapped.
1584   bool tryMapValue(const ScopArrayInfo *SAI, isl::map TargetElt) {
1585     assert(SAI->isValueKind());
1586 
1587     auto *DefMA = DefUse.getValueDef(SAI);
1588     assert(DefMA->isValueKind());
1589     assert(DefMA->isMustWrite());
1590     auto *V = DefMA->getAccessValue();
1591     auto *DefInst = DefMA->getAccessInstruction();
1592 
1593     // Stop if the scalar has already been mapped.
1594     if (!DefMA->getLatestScopArrayInfo()->isValueKind())
1595       return false;
1596 
1597     // { DomainDef[] -> Scatter[] }
1598     auto DefSched = getScatterFor(DefMA);
1599 
1600     // Where each write is mapped to, according to the suggestion.
1601     // { DomainDef[] -> Element[] }
1602     auto DefTarget = give(isl_map_apply_domain(
1603         TargetElt.copy(), isl_map_reverse(DefSched.copy())));
1604     simplify(DefTarget);
1605     DEBUG(dbgs() << "    Def Mapping: " << DefTarget << '\n');
1606 
1607     auto OrigDomain = getDomainFor(DefMA);
1608     auto MappedDomain = give(isl_map_domain(DefTarget.copy()));
1609     if (!isl_set_is_subset(OrigDomain.keep(), MappedDomain.keep())) {
1610       DEBUG(dbgs()
1611             << "    Reject because mapping does not encompass all instances\n");
1612       return false;
1613     }
1614 
1615     // { DomainDef[] -> Zone[] }
1616     isl::map Lifetime;
1617 
1618     // { DomainDef[] -> DomainUse[] }
1619     isl::union_map DefUses;
1620 
1621     std::tie(DefUses, Lifetime) = computeValueUses(SAI);
1622     DEBUG(dbgs() << "    Lifetime: " << Lifetime << '\n');
1623 
1624     /// { [Element[] -> Zone[]] }
1625     auto EltZone = give(
1626         isl_map_wrap(isl_map_apply_domain(Lifetime.copy(), DefTarget.copy())));
1627     simplify(EltZone);
1628 
1629     // { DomainDef[] -> ValInst[] }
1630     auto ValInst = makeValInst(V, DefMA->getStatement(),
1631                                LI->getLoopFor(DefInst->getParent()));
1632 
1633     // { DomainDef[] -> [Element[] -> Zone[]] }
1634     auto EltKnownTranslator =
1635         give(isl_map_range_product(DefTarget.copy(), Lifetime.copy()));
1636 
1637     // { [Element[] -> Zone[]] -> ValInst[] }
1638     auto EltKnown =
1639         give(isl_map_apply_domain(ValInst.copy(), EltKnownTranslator.take()));
1640     simplify(EltKnown);
1641 
1642     // { DomainDef[] -> [Element[] -> Scatter[]] }
1643     auto WrittenTranslator =
1644         give(isl_map_range_product(DefTarget.copy(), DefSched.take()));
1645 
1646     // { [Element[] -> Scatter[]] -> ValInst[] }
1647     auto DefEltSched =
1648         give(isl_map_apply_domain(ValInst.copy(), WrittenTranslator.take()));
1649     simplify(DefEltSched);
1650 
1651     Knowledge Proposed(EltZone, nullptr, filterKnownValInst(EltKnown),
1652                        DefEltSched);
1653     if (isConflicting(Proposed))
1654       return false;
1655 
1656     // { DomainUse[] -> Element[] }
1657     auto UseTarget = give(
1658         isl_union_map_apply_range(isl_union_map_reverse(DefUses.take()),
1659                                   isl_union_map_from_map(DefTarget.copy())));
1660 
1661     mapValue(SAI, std::move(DefTarget), std::move(UseTarget),
1662              std::move(Lifetime), std::move(Proposed));
1663     return true;
1664   }
1665 
1666   /// After a scalar has been mapped, update the global knowledge.
1667   void applyLifetime(Knowledge Proposed) {
1668     Zone.learnFrom(std::move(Proposed));
1669   }
1670 
1671   /// Map a MemoryKind::Value scalar to an array element.
1672   ///
1673   /// Callers must have ensured that the mapping is valid and not conflicting.
1674   ///
1675   /// @param SAI       The ScopArrayInfo representing the scalar's memory to
1676   ///                  map.
1677   /// @param DefTarget { DomainDef[] -> Element[] }
1678   ///                  The array element to map the scalar to.
1679   /// @param UseTarget { DomainUse[] -> Element[] }
1680   ///                  The array elements the uses are mapped to.
1681   /// @param Lifetime  { DomainDef[] -> Zone[] }
1682   ///                  The lifetime of each llvm::Value definition for
1683   ///                  reporting.
1684   /// @param Proposed  Mapping constraints for reporting.
1685   void mapValue(const ScopArrayInfo *SAI, isl::map DefTarget,
1686                 isl::union_map UseTarget, isl::map Lifetime,
1687                 Knowledge Proposed) {
1688     // Redirect the read accesses.
1689     for (auto *MA : DefUse.getValueUses(SAI)) {
1690       // { DomainUse[] }
1691       auto Domain = getDomainFor(MA);
1692 
1693       // { DomainUse[] -> Element[] }
1694       auto NewAccRel = give(isl_union_map_intersect_domain(
1695           UseTarget.copy(), isl_union_set_from_set(Domain.take())));
1696       simplify(NewAccRel);
1697 
1698       assert(isl_union_map_n_map(NewAccRel.keep()) == 1);
1699       MA->setNewAccessRelation(isl_map_from_union_map(NewAccRel.take()));
1700     }
1701 
1702     auto *WA = DefUse.getValueDef(SAI);
1703     WA->setNewAccessRelation(DefTarget.copy());
1704     applyLifetime(Proposed);
1705 
1706     MappedValueScalars++;
1707     NumberOfMappedValueScalars += 1;
1708   }
1709 
1710   /// Express the incoming values of a PHI for each incoming statement in an
1711   /// isl::union_map.
1712   ///
1713   /// @param SAI The PHI scalar represented by a ScopArrayInfo.
1714   ///
1715   /// @return { PHIWriteDomain[] -> ValInst[] }
1716   isl::union_map determinePHIWrittenValues(const ScopArrayInfo *SAI) {
1717     auto Result = makeEmptyUnionMap();
1718 
1719     // Collect the incoming values.
1720     for (auto *MA : DefUse.getPHIIncomings(SAI)) {
1721       // { DomainWrite[] -> ValInst[] }
1722       isl::union_map ValInst;
1723       auto *WriteStmt = MA->getStatement();
1724 
1725       auto Incoming = MA->getIncoming();
1726       assert(!Incoming.empty());
1727       if (Incoming.size() == 1) {
1728         ValInst = makeValInst(Incoming[0].second, WriteStmt,
1729                               LI->getLoopFor(Incoming[0].first));
1730       } else {
1731         // If the PHI is in a subregion's exit node it can have multiple
1732         // incoming values (+ maybe another incoming edge from an unrelated
1733         // block). We cannot directly represent it as a single llvm::Value.
1734         // We currently model it as unknown value, but modeling as the PHIInst
1735         // itself could be OK, too.
1736         ValInst = makeUnknownForDomain(WriteStmt);
1737       }
1738 
1739       Result = give(isl_union_map_union(Result.take(), ValInst.take()));
1740     }
1741 
1742     assert(isl_union_map_is_single_valued(Result.keep()) == isl_bool_true &&
1743            "Cannot have multiple incoming values for same incoming statement");
1744     return Result;
1745   }
1746 
1747   /// Try to map a MemoryKind::PHI scalar to a given array element.
1748   ///
1749   /// @param SAI       Representation of the scalar's memory to map.
1750   /// @param TargetElt { Scatter[] -> Element[] }
1751   ///                  Suggestion where to map the scalar to when at a
1752   ///                  timepoint.
1753   ///
1754   /// @return true if the PHI scalar has been mapped.
1755   bool tryMapPHI(const ScopArrayInfo *SAI, isl::map TargetElt) {
1756     auto *PHIRead = DefUse.getPHIRead(SAI);
1757     assert(PHIRead->isPHIKind());
1758     assert(PHIRead->isRead());
1759 
1760     // Skip if already been mapped.
1761     if (!PHIRead->getLatestScopArrayInfo()->isPHIKind())
1762       return false;
1763 
1764     // { DomainRead[] -> Scatter[] }
1765     auto PHISched = getScatterFor(PHIRead);
1766 
1767     // { DomainRead[] -> Element[] }
1768     auto PHITarget =
1769         give(isl_map_apply_range(PHISched.copy(), TargetElt.copy()));
1770     simplify(PHITarget);
1771     DEBUG(dbgs() << "    Mapping: " << PHITarget << '\n');
1772 
1773     auto OrigDomain = getDomainFor(PHIRead);
1774     auto MappedDomain = give(isl_map_domain(PHITarget.copy()));
1775     if (!isl_set_is_subset(OrigDomain.keep(), MappedDomain.keep())) {
1776       DEBUG(dbgs()
1777             << "    Reject because mapping does not encompass all instances\n");
1778       return false;
1779     }
1780 
1781     // { DomainRead[] -> DomainWrite[] }
1782     auto PerPHIWrites = computePerPHI(SAI);
1783 
1784     // { DomainWrite[] -> Element[] }
1785     auto WritesTarget = give(isl_union_map_reverse(isl_union_map_apply_domain(
1786         PerPHIWrites.copy(), isl_union_map_from_map(PHITarget.copy()))));
1787     simplify(WritesTarget);
1788 
1789     // { DomainWrite[] }
1790     auto UniverseWritesDom = give(isl_union_set_empty(ParamSpace.copy()));
1791 
1792     for (auto *MA : DefUse.getPHIIncomings(SAI))
1793       UniverseWritesDom = give(isl_union_set_add_set(UniverseWritesDom.take(),
1794                                                      getDomainFor(MA).take()));
1795 
1796     auto RelevantWritesTarget = WritesTarget;
1797     if (DelicmOverapproximateWrites)
1798       WritesTarget = expandMapping(WritesTarget, UniverseWritesDom);
1799 
1800     auto ExpandedWritesDom = give(isl_union_map_domain(WritesTarget.copy()));
1801     if (!DelicmPartialWrites &&
1802         !isl_union_set_is_subset(UniverseWritesDom.keep(),
1803                                  ExpandedWritesDom.keep())) {
1804       DEBUG(dbgs() << "    Reject because did not find PHI write mapping for "
1805                       "all instances\n");
1806       if (DelicmOverapproximateWrites)
1807         DEBUG(dbgs() << "      Relevant Mapping:    " << RelevantWritesTarget
1808                      << '\n');
1809       DEBUG(dbgs() << "      Deduced Mapping:     " << WritesTarget << '\n');
1810       DEBUG(dbgs() << "      Missing instances:    "
1811                    << give(isl_union_set_subtract(UniverseWritesDom.copy(),
1812                                                   ExpandedWritesDom.copy()))
1813                    << '\n');
1814       return false;
1815     }
1816 
1817     //  { DomainRead[] -> Scatter[] }
1818     auto PerPHIWriteScatter = give(isl_map_from_union_map(
1819         isl_union_map_apply_range(PerPHIWrites.copy(), Schedule.copy())));
1820 
1821     // { DomainRead[] -> Zone[] }
1822     auto Lifetime = betweenScatter(PerPHIWriteScatter, PHISched, false, true);
1823     simplify(Lifetime);
1824     DEBUG(dbgs() << "    Lifetime: " << Lifetime << "\n");
1825 
1826     // { DomainWrite[] -> Zone[] }
1827     auto WriteLifetime = give(isl_union_map_apply_domain(
1828         isl_union_map_from_map(Lifetime.copy()), PerPHIWrites.copy()));
1829 
1830     // { DomainWrite[] -> ValInst[] }
1831     auto WrittenValue = determinePHIWrittenValues(SAI);
1832 
1833     // { DomainWrite[] -> [Element[] -> Scatter[]] }
1834     auto WrittenTranslator =
1835         give(isl_union_map_range_product(WritesTarget.copy(), Schedule.copy()));
1836 
1837     // { [Element[] -> Scatter[]] -> ValInst[] }
1838     auto Written = give(isl_union_map_apply_domain(WrittenValue.copy(),
1839                                                    WrittenTranslator.copy()));
1840     simplify(Written);
1841 
1842     // { DomainWrite[] -> [Element[] -> Zone[]] }
1843     auto LifetimeTranslator = give(
1844         isl_union_map_range_product(WritesTarget.copy(), WriteLifetime.copy()));
1845 
1846     // { DomainWrite[] -> ValInst[] }
1847     auto WrittenKnownValue = filterKnownValInst(WrittenValue);
1848 
1849     // { [Element[] -> Zone[]] -> ValInst[] }
1850     auto EltLifetimeInst = give(isl_union_map_apply_domain(
1851         WrittenKnownValue.copy(), LifetimeTranslator.copy()));
1852     simplify(EltLifetimeInst);
1853 
1854     // { [Element[] -> Zone[] }
1855     auto Occupied = give(isl_union_map_range(LifetimeTranslator.copy()));
1856     simplify(Occupied);
1857 
1858     Knowledge Proposed(Occupied, nullptr, EltLifetimeInst, Written);
1859     if (isConflicting(Proposed))
1860       return false;
1861 
1862     mapPHI(SAI, std::move(PHITarget), std::move(WritesTarget),
1863            std::move(Lifetime), std::move(Proposed));
1864     return true;
1865   }
1866 
1867   /// Map a MemoryKind::PHI scalar to an array element.
1868   ///
1869   /// Callers must have ensured that the mapping is valid and not conflicting
1870   /// with the common knowledge.
1871   ///
1872   /// @param SAI         The ScopArrayInfo representing the scalar's memory to
1873   ///                    map.
1874   /// @param ReadTarget  { DomainRead[] -> Element[] }
1875   ///                    The array element to map the scalar to.
1876   /// @param WriteTarget { DomainWrite[] -> Element[] }
1877   ///                    New access target for each PHI incoming write.
1878   /// @param Lifetime    { DomainRead[] -> Zone[] }
1879   ///                    The lifetime of each PHI for reporting.
1880   /// @param Proposed    Mapping constraints for reporting.
1881   void mapPHI(const ScopArrayInfo *SAI, isl::map ReadTarget,
1882               isl::union_map WriteTarget, isl::map Lifetime,
1883               Knowledge Proposed) {
1884     // Redirect the PHI incoming writes.
1885     for (auto *MA : DefUse.getPHIIncomings(SAI)) {
1886       // { DomainWrite[] }
1887       auto Domain = getDomainFor(MA);
1888 
1889       // { DomainWrite[] -> Element[] }
1890       auto NewAccRel = give(isl_union_map_intersect_domain(
1891           WriteTarget.copy(), isl_union_set_from_set(Domain.take())));
1892       simplify(NewAccRel);
1893 
1894       assert(isl_union_map_n_map(NewAccRel.keep()) == 1);
1895       MA->setNewAccessRelation(isl_map_from_union_map(NewAccRel.take()));
1896     }
1897 
1898     // Redirect the PHI read.
1899     auto *PHIRead = DefUse.getPHIRead(SAI);
1900     PHIRead->setNewAccessRelation(ReadTarget.copy());
1901     applyLifetime(Proposed);
1902 
1903     MappedPHIScalars++;
1904     NumberOfMappedPHIScalars++;
1905   }
1906 
1907   /// Search and map scalars to memory overwritten by @p TargetStoreMA.
1908   ///
1909   /// Start trying to map scalars that are used in the same statement as the
1910   /// store. For every successful mapping, try to also map scalars of the
1911   /// statements where those are written. Repeat, until no more mapping
1912   /// opportunity is found.
1913   ///
1914   /// There is currently no preference in which order scalars are tried.
1915   /// Ideally, we would direct it towards a load instruction of the same array
1916   /// element.
1917   bool collapseScalarsToStore(MemoryAccess *TargetStoreMA) {
1918     assert(TargetStoreMA->isLatestArrayKind());
1919     assert(TargetStoreMA->isMustWrite());
1920 
1921     auto TargetStmt = TargetStoreMA->getStatement();
1922 
1923     // { DomTarget[] }
1924     auto TargetDom = getDomainFor(TargetStmt);
1925 
1926     // { DomTarget[] -> Element[] }
1927     auto TargetAccRel = getAccessRelationFor(TargetStoreMA);
1928 
1929     // { Zone[] -> DomTarget[] }
1930     // For each point in time, find the next target store instance.
1931     auto Target =
1932         computeScalarReachingOverwrite(Schedule, TargetDom, false, true);
1933 
1934     // { Zone[] -> Element[] }
1935     // Use the target store's write location as a suggestion to map scalars to.
1936     auto EltTarget =
1937         give(isl_map_apply_range(Target.take(), TargetAccRel.take()));
1938     simplify(EltTarget);
1939     DEBUG(dbgs() << "    Target mapping is " << EltTarget << '\n');
1940 
1941     // Stack of elements not yet processed.
1942     SmallVector<MemoryAccess *, 16> Worklist;
1943 
1944     // Set of scalars already tested.
1945     SmallPtrSet<const ScopArrayInfo *, 16> Closed;
1946 
1947     // Lambda to add all scalar reads to the work list.
1948     auto ProcessAllIncoming = [&](ScopStmt *Stmt) {
1949       for (auto *MA : *Stmt) {
1950         if (!MA->isLatestScalarKind())
1951           continue;
1952         if (!MA->isRead())
1953           continue;
1954 
1955         Worklist.push_back(MA);
1956       }
1957     };
1958 
1959     auto *WrittenVal = TargetStoreMA->getAccessInstruction()->getOperand(0);
1960     if (auto *WrittenValInputMA = TargetStmt->lookupInputAccessOf(WrittenVal))
1961       Worklist.push_back(WrittenValInputMA);
1962     else
1963       ProcessAllIncoming(TargetStmt);
1964 
1965     auto AnyMapped = false;
1966     auto &DL = S->getRegion().getEntry()->getModule()->getDataLayout();
1967     auto StoreSize =
1968         DL.getTypeAllocSize(TargetStoreMA->getAccessValue()->getType());
1969 
1970     while (!Worklist.empty()) {
1971       auto *MA = Worklist.pop_back_val();
1972 
1973       auto *SAI = MA->getScopArrayInfo();
1974       if (Closed.count(SAI))
1975         continue;
1976       Closed.insert(SAI);
1977       DEBUG(dbgs() << "\n    Trying to map " << MA << " (SAI: " << SAI
1978                    << ")\n");
1979 
1980       // Skip non-mappable scalars.
1981       if (!isMappable(SAI))
1982         continue;
1983 
1984       auto MASize = DL.getTypeAllocSize(MA->getAccessValue()->getType());
1985       if (MASize > StoreSize) {
1986         DEBUG(dbgs() << "    Reject because storage size is insufficient\n");
1987         continue;
1988       }
1989 
1990       // Try to map MemoryKind::Value scalars.
1991       if (SAI->isValueKind()) {
1992         if (!tryMapValue(SAI, EltTarget))
1993           continue;
1994 
1995         auto *DefAcc = DefUse.getValueDef(SAI);
1996         ProcessAllIncoming(DefAcc->getStatement());
1997 
1998         AnyMapped = true;
1999         continue;
2000       }
2001 
2002       // Try to map MemoryKind::PHI scalars.
2003       if (SAI->isPHIKind()) {
2004         if (!tryMapPHI(SAI, EltTarget))
2005           continue;
2006         // Add inputs of all incoming statements to the worklist. Prefer the
2007         // input accesses of the incoming blocks.
2008         for (auto *PHIWrite : DefUse.getPHIIncomings(SAI)) {
2009           auto *PHIWriteStmt = PHIWrite->getStatement();
2010           bool FoundAny = false;
2011           for (auto Incoming : PHIWrite->getIncoming()) {
2012             auto *IncomingInputMA =
2013                 PHIWriteStmt->lookupInputAccessOf(Incoming.second);
2014             if (!IncomingInputMA)
2015               continue;
2016 
2017             Worklist.push_back(IncomingInputMA);
2018             FoundAny = true;
2019           }
2020 
2021           if (!FoundAny)
2022             ProcessAllIncoming(PHIWrite->getStatement());
2023         }
2024 
2025         AnyMapped = true;
2026         continue;
2027       }
2028     }
2029 
2030     if (AnyMapped) {
2031       TargetsMapped++;
2032       NumberOfTargetsMapped++;
2033     }
2034     return AnyMapped;
2035   }
2036 
2037   /// Compute when an array element is unused.
2038   ///
2039   /// @return { [Element[] -> Zone[]] }
2040   isl::union_set computeLifetime() const {
2041     // { Element[] -> Zone[] }
2042     auto ArrayUnused = computeArrayUnused(Schedule, AllMustWrites, AllReads,
2043                                           false, false, true);
2044 
2045     auto Result = give(isl_union_map_wrap(ArrayUnused.copy()));
2046 
2047     simplify(Result);
2048     return Result;
2049   }
2050 
2051   /// Compute which value an array element stores at every instant.
2052   ///
2053   /// @return { [Element[] -> Zone[]] -> ValInst[] }
2054   isl::union_map computeKnown() const {
2055     // { [Element[] -> Zone[]] -> [Element[] -> DomainWrite[]] }
2056     auto EltReachdDef =
2057         distributeDomain(give(isl_union_map_curry(WriteReachDefZone.copy())));
2058 
2059     // { [Element[] -> DomainWrite[]] -> ValInst[] }
2060     auto AllKnownWriteValInst = filterKnownValInst(AllWriteValInst);
2061 
2062     // { [Element[] -> Zone[]] -> ValInst[] }
2063     return EltReachdDef.apply_range(AllKnownWriteValInst);
2064   }
2065 
2066   /// Determine when an array element is written to, and which value instance is
2067   /// written.
2068   ///
2069   /// @return { [Element[] -> Scatter[]] -> ValInst[] }
2070   isl::union_map computeWritten() const {
2071     // { [Element[] -> Scatter[]] -> ValInst[] }
2072     auto EltWritten = applyDomainRange(AllWriteValInst, Schedule);
2073 
2074     simplify(EltWritten);
2075     return EltWritten;
2076   }
2077 
2078   /// Determine whether an access touches at most one element.
2079   ///
2080   /// The accessed element could be a scalar or accessing an array with constant
2081   /// subscript, such that all instances access only that element.
2082   ///
2083   /// @param MA The access to test.
2084   ///
2085   /// @return True, if zero or one elements are accessed; False if at least two
2086   ///         different elements are accessed.
2087   bool isScalarAccess(MemoryAccess *MA) {
2088     auto Map = getAccessRelationFor(MA);
2089     auto Set = give(isl_map_range(Map.take()));
2090     return isl_set_is_singleton(Set.keep()) == isl_bool_true;
2091   }
2092 
2093   /// Print mapping statistics to @p OS.
2094   void printStatistics(llvm::raw_ostream &OS, int Indent = 0) const {
2095     OS.indent(Indent) << "Statistics {\n";
2096     OS.indent(Indent + 4) << "Compatible overwrites: "
2097                           << NumberOfCompatibleTargets << "\n";
2098     OS.indent(Indent + 4) << "Overwrites mapped to:  " << NumberOfTargetsMapped
2099                           << '\n';
2100     OS.indent(Indent + 4) << "Value scalars mapped:  "
2101                           << NumberOfMappedValueScalars << '\n';
2102     OS.indent(Indent + 4) << "PHI scalars mapped:    "
2103                           << NumberOfMappedPHIScalars << '\n';
2104     OS.indent(Indent) << "}\n";
2105   }
2106 
2107   /// Return whether at least one transformation been applied.
2108   bool isModified() const { return NumberOfTargetsMapped > 0; }
2109 
2110 public:
2111   DeLICMImpl(Scop *S, LoopInfo *LI) : ZoneAlgorithm(S, LI) {}
2112 
2113   /// Calculate the lifetime (definition to last use) of every array element.
2114   ///
2115   /// @return True if the computed lifetimes (#Zone) is usable.
2116   bool computeZone() {
2117     // Check that nothing strange occurs.
2118     if (!isCompatibleScop()) {
2119       DeLICMIncompatible++;
2120       return false;
2121     }
2122 
2123     DefUse.compute(S);
2124     isl::union_set EltUnused;
2125     isl::union_map EltKnown, EltWritten;
2126 
2127     {
2128       IslMaxOperationsGuard MaxOpGuard(IslCtx.get(), DelicmMaxOps);
2129 
2130       computeCommon();
2131 
2132       EltUnused = computeLifetime();
2133       EltKnown = computeKnown();
2134       EltWritten = computeWritten();
2135     }
2136     DeLICMAnalyzed++;
2137 
2138     if (!EltUnused || !EltKnown || !EltWritten) {
2139       assert(isl_ctx_last_error(IslCtx.get()) == isl_error_quota &&
2140              "The only reason that these things have not been computed should "
2141              "be if the max-operations limit hit");
2142       DeLICMOutOfQuota++;
2143       DEBUG(dbgs() << "DeLICM analysis exceeded max_operations\n");
2144       DebugLoc Begin, End;
2145       getDebugLocations(getBBPairForRegion(&S->getRegion()), Begin, End);
2146       OptimizationRemarkAnalysis R(DEBUG_TYPE, "OutOfQuota", Begin,
2147                                    S->getEntry());
2148       R << "maximal number of operations exceeded during zone analysis";
2149       S->getFunction().getContext().diagnose(R);
2150       return false;
2151     }
2152 
2153     Zone = OriginalZone = Knowledge(nullptr, EltUnused, EltKnown, EltWritten);
2154     DEBUG(dbgs() << "Computed Zone:\n"; OriginalZone.print(dbgs(), 4));
2155 
2156     assert(Zone.isUsable() && OriginalZone.isUsable());
2157     return true;
2158   }
2159 
2160   /// Try to map as many scalars to unused array elements as possible.
2161   ///
2162   /// Multiple scalars might be mappable to intersecting unused array element
2163   /// zones, but we can only chose one. This is a greedy algorithm, therefore
2164   /// the first processed element claims it.
2165   void greedyCollapse() {
2166     bool Modified = false;
2167 
2168     for (auto &Stmt : *S) {
2169       for (auto *MA : Stmt) {
2170         if (!MA->isLatestArrayKind())
2171           continue;
2172         if (!MA->isWrite())
2173           continue;
2174 
2175         if (MA->isMayWrite()) {
2176           DEBUG(dbgs() << "Access " << MA
2177                        << " pruned because it is a MAY_WRITE\n");
2178           OptimizationRemarkMissed R(DEBUG_TYPE, "TargetMayWrite",
2179                                      MA->getAccessInstruction());
2180           R << "Skipped possible mapping target because it is not an "
2181                "unconditional overwrite";
2182           S->getFunction().getContext().diagnose(R);
2183           continue;
2184         }
2185 
2186         if (Stmt.getNumIterators() == 0) {
2187           DEBUG(dbgs() << "Access " << MA
2188                        << " pruned because it is not in a loop\n");
2189           OptimizationRemarkMissed R(DEBUG_TYPE, "WriteNotInLoop",
2190                                      MA->getAccessInstruction());
2191           R << "skipped possible mapping target because it is not in a loop";
2192           S->getFunction().getContext().diagnose(R);
2193           continue;
2194         }
2195 
2196         if (isScalarAccess(MA)) {
2197           DEBUG(dbgs() << "Access " << MA
2198                        << " pruned because it writes only a single element\n");
2199           OptimizationRemarkMissed R(DEBUG_TYPE, "ScalarWrite",
2200                                      MA->getAccessInstruction());
2201           R << "skipped possible mapping target because the memory location "
2202                "written to does not depend on its outer loop";
2203           S->getFunction().getContext().diagnose(R);
2204           continue;
2205         }
2206 
2207         NumberOfCompatibleTargets++;
2208         DEBUG(dbgs() << "Analyzing target access " << MA << "\n");
2209         if (collapseScalarsToStore(MA))
2210           Modified = true;
2211       }
2212     }
2213 
2214     if (Modified)
2215       DeLICMScopsModified++;
2216   }
2217 
2218   /// Dump the internal information about a performed DeLICM to @p OS.
2219   void print(llvm::raw_ostream &OS, int Indent = 0) {
2220     if (!Zone.isUsable()) {
2221       OS.indent(Indent) << "Zone not computed\n";
2222       return;
2223     }
2224 
2225     printStatistics(OS, Indent);
2226     if (!isModified()) {
2227       OS.indent(Indent) << "No modification has been made\n";
2228       return;
2229     }
2230     printAccesses(OS, Indent);
2231   }
2232 };
2233 
2234 class DeLICM : public ScopPass {
2235 private:
2236   DeLICM(const DeLICM &) = delete;
2237   const DeLICM &operator=(const DeLICM &) = delete;
2238 
2239   /// The pass implementation, also holding per-scop data.
2240   std::unique_ptr<DeLICMImpl> Impl;
2241 
2242   void collapseToUnused(Scop &S) {
2243     auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
2244     Impl = make_unique<DeLICMImpl>(&S, &LI);
2245 
2246     if (!Impl->computeZone()) {
2247       DEBUG(dbgs() << "Abort because cannot reliably compute lifetimes\n");
2248       return;
2249     }
2250 
2251     DEBUG(dbgs() << "Collapsing scalars to unused array elements...\n");
2252     Impl->greedyCollapse();
2253 
2254     DEBUG(dbgs() << "\nFinal Scop:\n");
2255     DEBUG(S.print(dbgs()));
2256   }
2257 
2258 public:
2259   static char ID;
2260   explicit DeLICM() : ScopPass(ID) {}
2261 
2262   virtual void getAnalysisUsage(AnalysisUsage &AU) const override {
2263     AU.addRequiredTransitive<ScopInfoRegionPass>();
2264     AU.addRequired<LoopInfoWrapperPass>();
2265     AU.setPreservesAll();
2266   }
2267 
2268   virtual bool runOnScop(Scop &S) override {
2269     // Free resources for previous scop's computation, if not yet done.
2270     releaseMemory();
2271 
2272     collapseToUnused(S);
2273 
2274     return false;
2275   }
2276 
2277   virtual void printScop(raw_ostream &OS, Scop &S) const override {
2278     if (!Impl)
2279       return;
2280     assert(Impl->getScop() == &S);
2281 
2282     OS << "DeLICM result:\n";
2283     Impl->print(OS);
2284   }
2285 
2286   virtual void releaseMemory() override { Impl.reset(); }
2287 };
2288 
2289 char DeLICM::ID;
2290 } // anonymous namespace
2291 
2292 Pass *polly::createDeLICMPass() { return new DeLICM(); }
2293 
2294 INITIALIZE_PASS_BEGIN(DeLICM, "polly-delicm", "Polly - DeLICM/DePRE", false,
2295                       false)
2296 INITIALIZE_PASS_DEPENDENCY(ScopInfoWrapperPass)
2297 INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
2298 INITIALIZE_PASS_END(DeLICM, "polly-delicm", "Polly - DeLICM/DePRE", false,
2299                     false)
2300 
2301 bool polly::isConflicting(
2302     isl::union_set ExistingOccupied, isl::union_set ExistingUnused,
2303     isl::union_map ExistingKnown, isl::union_map ExistingWrites,
2304     isl::union_set ProposedOccupied, isl::union_set ProposedUnused,
2305     isl::union_map ProposedKnown, isl::union_map ProposedWrites,
2306     llvm::raw_ostream *OS, unsigned Indent) {
2307   Knowledge Existing(std::move(ExistingOccupied), std::move(ExistingUnused),
2308                      std::move(ExistingKnown), std::move(ExistingWrites));
2309   Knowledge Proposed(std::move(ProposedOccupied), std::move(ProposedUnused),
2310                      std::move(ProposedKnown), std::move(ProposedWrites));
2311 
2312   return Knowledge::isConflicting(Existing, Proposed, OS, Indent);
2313 }
2314