1 //===- DependenceInfo.cpp - Calculate dependency information for a Scop. --===//
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 // Calculate the data dependency relations for a Scop using ISL.
11 //
12 // The integer set library (ISL) from Sven, has a integrated dependency analysis
13 // to calculate data dependences. This pass takes advantage of this and
14 // calculate those dependences a Scop.
15 //
16 // The dependences in this pass are exact in terms that for a specific read
17 // statement instance only the last write statement instance is returned. In
18 // case of may writes a set of possible write instances is returned. This
19 // analysis will never produce redundant dependences.
20 //
21 //===----------------------------------------------------------------------===//
22 //
23 #include "polly/DependenceInfo.h"
24 #include "polly/LinkAllPasses.h"
25 #include "polly/Options.h"
26 #include "polly/ScopInfo.h"
27 #include "polly/Support/GICHelper.h"
28 #include "llvm/Support/Debug.h"
29 #include <isl/aff.h>
30 #include <isl/ctx.h>
31 #include <isl/flow.h>
32 #include <isl/map.h>
33 #include <isl/options.h>
34 #include <isl/schedule.h>
35 #include <isl/set.h>
36 #include <isl/union_map.h>
37 #include <isl/union_set.h>
38 
39 using namespace polly;
40 using namespace llvm;
41 
42 #define DEBUG_TYPE "polly-dependence"
43 
44 static cl::opt<int> OptComputeOut(
45     "polly-dependences-computeout",
46     cl::desc("Bound the dependence analysis by a maximal amount of "
47              "computational steps (0 means no bound)"),
48     cl::Hidden, cl::init(500000), cl::ZeroOrMore, cl::cat(PollyCategory));
49 
50 static cl::opt<bool> LegalityCheckDisabled(
51     "disable-polly-legality", cl::desc("Disable polly legality check"),
52     cl::Hidden, cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory));
53 
54 static cl::opt<bool>
55     UseReductions("polly-dependences-use-reductions",
56                   cl::desc("Exploit reductions in dependence analysis"),
57                   cl::Hidden, cl::init(true), cl::ZeroOrMore,
58                   cl::cat(PollyCategory));
59 
60 enum AnalysisType { VALUE_BASED_ANALYSIS, MEMORY_BASED_ANALYSIS };
61 
62 static cl::opt<enum AnalysisType> OptAnalysisType(
63     "polly-dependences-analysis-type",
64     cl::desc("The kind of dependence analysis to use"),
65     cl::values(clEnumValN(VALUE_BASED_ANALYSIS, "value-based",
66                           "Exact dependences without transitive dependences"),
67                clEnumValN(MEMORY_BASED_ANALYSIS, "memory-based",
68                           "Overapproximation of dependences")),
69     cl::Hidden, cl::init(VALUE_BASED_ANALYSIS), cl::ZeroOrMore,
70     cl::cat(PollyCategory));
71 
72 static cl::opt<Dependences::AnalysisLevel> OptAnalysisLevel(
73     "polly-dependences-analysis-level",
74     cl::desc("The level of dependence analysis"),
75     cl::values(clEnumValN(Dependences::AL_Statement, "statement-wise",
76                           "Statement-level analysis"),
77                clEnumValN(Dependences::AL_Reference, "reference-wise",
78                           "Memory reference level analysis that distinguish"
79                           " accessed references in the same statement"),
80                clEnumValN(Dependences::AL_Access, "access-wise",
81                           "Memory reference level analysis that distinguish"
82                           " access instructions in the same statement")),
83     cl::Hidden, cl::init(Dependences::AL_Statement), cl::ZeroOrMore,
84     cl::cat(PollyCategory));
85 
86 //===----------------------------------------------------------------------===//
87 
88 /// Tag the @p Relation domain with @p TagId
89 static __isl_give isl_map *tag(__isl_take isl_map *Relation,
90                                __isl_take isl_id *TagId) {
91   isl_space *Space = isl_map_get_space(Relation);
92   Space = isl_space_drop_dims(Space, isl_dim_out, 0, isl_map_n_out(Relation));
93   Space = isl_space_set_tuple_id(Space, isl_dim_out, TagId);
94   isl_multi_aff *Tag = isl_multi_aff_domain_map(Space);
95   Relation = isl_map_preimage_domain_multi_aff(Relation, Tag);
96   return Relation;
97 }
98 
99 /// Tag the @p Relation domain with either MA->getArrayId() or
100 ///        MA->getId() based on @p TagLevel
101 static __isl_give isl_map *tag(__isl_take isl_map *Relation, MemoryAccess *MA,
102                                Dependences::AnalysisLevel TagLevel) {
103   if (TagLevel == Dependences::AL_Reference)
104     return tag(Relation, MA->getArrayId());
105 
106   if (TagLevel == Dependences::AL_Access)
107     return tag(Relation, MA->getId());
108 
109   // No need to tag at the statement level.
110   return Relation;
111 }
112 
113 /// Collect information about the SCoP @p S.
114 static void collectInfo(Scop &S, isl_union_map *&Read, isl_union_map *&Write,
115                         isl_union_map *&MayWrite,
116                         isl_union_map *&ReductionTagMap,
117                         isl_union_set *&TaggedStmtDomain,
118                         Dependences::AnalysisLevel Level) {
119   isl_space *Space = S.getParamSpace();
120   Read = isl_union_map_empty(isl_space_copy(Space));
121   Write = isl_union_map_empty(isl_space_copy(Space));
122   MayWrite = isl_union_map_empty(isl_space_copy(Space));
123   ReductionTagMap = isl_union_map_empty(isl_space_copy(Space));
124   isl_union_map *StmtSchedule = isl_union_map_empty(Space);
125 
126   SmallPtrSet<const ScopArrayInfo *, 8> ReductionArrays;
127   if (UseReductions)
128     for (ScopStmt &Stmt : S)
129       for (MemoryAccess *MA : Stmt)
130         if (MA->isReductionLike())
131           ReductionArrays.insert(MA->getScopArrayInfo());
132 
133   for (ScopStmt &Stmt : S) {
134     for (MemoryAccess *MA : Stmt) {
135       isl_set *domcp = Stmt.getDomain();
136       isl_map *accdom = MA->getAccessRelation();
137 
138       accdom = isl_map_intersect_domain(accdom, domcp);
139 
140       if (ReductionArrays.count(MA->getScopArrayInfo())) {
141         // Wrap the access domain and adjust the schedule accordingly.
142         //
143         // An access domain like
144         //   Stmt[i0, i1] -> MemAcc_A[i0 + i1]
145         // will be transformed into
146         //   [Stmt[i0, i1] -> MemAcc_A[i0 + i1]] -> MemAcc_A[i0 + i1]
147         //
148         // We collect all the access domains in the ReductionTagMap.
149         // This is used in Dependences::calculateDependences to create
150         // a tagged Schedule tree.
151 
152         ReductionTagMap =
153             isl_union_map_add_map(ReductionTagMap, isl_map_copy(accdom));
154         accdom = isl_map_range_map(accdom);
155       } else {
156         accdom = tag(accdom, MA, Level);
157         if (Level > Dependences::AL_Statement) {
158           auto *StmtScheduleMap = Stmt.getSchedule();
159           assert(StmtScheduleMap &&
160                  "Schedules that contain extension nodes require special "
161                  "handling.");
162           isl_map *Schedule = tag(StmtScheduleMap, MA, Level);
163           StmtSchedule = isl_union_map_add_map(StmtSchedule, Schedule);
164         }
165       }
166 
167       if (MA->isRead())
168         Read = isl_union_map_add_map(Read, accdom);
169       else
170         Write = isl_union_map_add_map(Write, accdom);
171     }
172 
173     if (!ReductionArrays.empty() && Level == Dependences::AL_Statement)
174       StmtSchedule = isl_union_map_add_map(StmtSchedule, Stmt.getSchedule());
175   }
176 
177   StmtSchedule =
178       isl_union_map_intersect_params(StmtSchedule, S.getAssumedContext());
179   TaggedStmtDomain = isl_union_map_domain(StmtSchedule);
180 
181   ReductionTagMap = isl_union_map_coalesce(ReductionTagMap);
182   Read = isl_union_map_coalesce(Read);
183   Write = isl_union_map_coalesce(Write);
184   MayWrite = isl_union_map_coalesce(MayWrite);
185 }
186 
187 /// Fix all dimension of @p Zero to 0 and add it to @p user
188 static isl_stat fixSetToZero(__isl_take isl_set *Zero, void *user) {
189   isl_union_set **User = (isl_union_set **)user;
190   for (unsigned i = 0; i < isl_set_dim(Zero, isl_dim_set); i++)
191     Zero = isl_set_fix_si(Zero, isl_dim_set, i, 0);
192   *User = isl_union_set_add_set(*User, Zero);
193   return isl_stat_ok;
194 }
195 
196 /// Compute the privatization dependences for a given dependency @p Map
197 ///
198 /// Privatization dependences are widened original dependences which originate
199 /// or end in a reduction access. To compute them we apply the transitive close
200 /// of the reduction dependences (which maps each iteration of a reduction
201 /// statement to all following ones) on the RAW/WAR/WAW dependences. The
202 /// dependences which start or end at a reduction statement will be extended to
203 /// depend on all following reduction statement iterations as well.
204 /// Note: "Following" here means according to the reduction dependences.
205 ///
206 /// For the input:
207 ///
208 ///  S0:   *sum = 0;
209 ///        for (int i = 0; i < 1024; i++)
210 ///  S1:     *sum += i;
211 ///  S2:   *sum = *sum * 3;
212 ///
213 /// we have the following dependences before we add privatization dependences:
214 ///
215 ///   RAW:
216 ///     { S0[] -> S1[0]; S1[1023] -> S2[] }
217 ///   WAR:
218 ///     {  }
219 ///   WAW:
220 ///     { S0[] -> S1[0]; S1[1024] -> S2[] }
221 ///   RED:
222 ///     { S1[i0] -> S1[1 + i0] : i0 >= 0 and i0 <= 1022 }
223 ///
224 /// and afterwards:
225 ///
226 ///   RAW:
227 ///     { S0[] -> S1[i0] : i0 >= 0 and i0 <= 1023;
228 ///       S1[i0] -> S2[] : i0 >= 0 and i0 <= 1023}
229 ///   WAR:
230 ///     {  }
231 ///   WAW:
232 ///     { S0[] -> S1[i0] : i0 >= 0 and i0 <= 1023;
233 ///       S1[i0] -> S2[] : i0 >= 0 and i0 <= 1023}
234 ///   RED:
235 ///     { S1[i0] -> S1[1 + i0] : i0 >= 0 and i0 <= 1022 }
236 ///
237 /// Note: This function also computes the (reverse) transitive closure of the
238 ///       reduction dependences.
239 void Dependences::addPrivatizationDependences() {
240   isl_union_map *PrivRAW, *PrivWAW, *PrivWAR;
241 
242   // The transitive closure might be over approximated, thus could lead to
243   // dependency cycles in the privatization dependences. To make sure this
244   // will not happen we remove all negative dependences after we computed
245   // the transitive closure.
246   TC_RED = isl_union_map_transitive_closure(isl_union_map_copy(RED), nullptr);
247 
248   // FIXME: Apply the current schedule instead of assuming the identity schedule
249   //        here. The current approach is only valid as long as we compute the
250   //        dependences only with the initial (identity schedule). Any other
251   //        schedule could change "the direction of the backward dependences" we
252   //        want to eliminate here.
253   isl_union_set *UDeltas = isl_union_map_deltas(isl_union_map_copy(TC_RED));
254   isl_union_set *Universe = isl_union_set_universe(isl_union_set_copy(UDeltas));
255   isl_union_set *Zero = isl_union_set_empty(isl_union_set_get_space(Universe));
256   isl_union_set_foreach_set(Universe, fixSetToZero, &Zero);
257   isl_union_map *NonPositive = isl_union_set_lex_le_union_set(UDeltas, Zero);
258 
259   TC_RED = isl_union_map_subtract(TC_RED, NonPositive);
260 
261   TC_RED = isl_union_map_union(
262       TC_RED, isl_union_map_reverse(isl_union_map_copy(TC_RED)));
263   TC_RED = isl_union_map_coalesce(TC_RED);
264 
265   isl_union_map **Maps[] = {&RAW, &WAW, &WAR};
266   isl_union_map **PrivMaps[] = {&PrivRAW, &PrivWAW, &PrivWAR};
267   for (unsigned u = 0; u < 3; u++) {
268     isl_union_map **Map = Maps[u], **PrivMap = PrivMaps[u];
269 
270     *PrivMap = isl_union_map_apply_range(isl_union_map_copy(*Map),
271                                          isl_union_map_copy(TC_RED));
272     *PrivMap = isl_union_map_union(
273         *PrivMap, isl_union_map_apply_range(isl_union_map_copy(TC_RED),
274                                             isl_union_map_copy(*Map)));
275 
276     *Map = isl_union_map_union(*Map, *PrivMap);
277   }
278 
279   isl_union_set_free(Universe);
280 }
281 
282 static __isl_give isl_union_flow *buildFlow(__isl_keep isl_union_map *Snk,
283                                             __isl_keep isl_union_map *Src,
284                                             __isl_keep isl_union_map *MaySrc,
285                                             __isl_keep isl_schedule *Schedule) {
286   isl_union_access_info *AI;
287 
288   AI = isl_union_access_info_from_sink(isl_union_map_copy(Snk));
289   AI = isl_union_access_info_set_may_source(AI, isl_union_map_copy(MaySrc));
290   if (Src)
291     AI = isl_union_access_info_set_must_source(AI, isl_union_map_copy(Src));
292   AI = isl_union_access_info_set_schedule(AI, isl_schedule_copy(Schedule));
293   auto Flow = isl_union_access_info_compute_flow(AI);
294   DEBUG(if (!Flow) dbgs() << "last error: "
295                           << isl_ctx_last_error(isl_schedule_get_ctx(Schedule))
296                           << '\n';);
297   return Flow;
298 }
299 
300 void Dependences::calculateDependences(Scop &S) {
301   isl_union_map *Read, *Write, *MayWrite, *ReductionTagMap;
302   isl_schedule *Schedule;
303   isl_union_set *TaggedStmtDomain;
304 
305   DEBUG(dbgs() << "Scop: \n" << S << "\n");
306 
307   collectInfo(S, Read, Write, MayWrite, ReductionTagMap, TaggedStmtDomain,
308               Level);
309 
310   bool HasReductions = !isl_union_map_is_empty(ReductionTagMap);
311 
312   DEBUG(dbgs() << "Read: " << Read << '\n';
313         dbgs() << "Write: " << Write << '\n';
314         dbgs() << "MayWrite: " << MayWrite << '\n';
315         dbgs() << "ReductionTagMap: " << ReductionTagMap << '\n';
316         dbgs() << "TaggedStmtDomain: " << TaggedStmtDomain << '\n';);
317 
318   Schedule = S.getScheduleTree();
319 
320   if (!HasReductions) {
321     isl_union_map_free(ReductionTagMap);
322     // Tag the schedule tree if we want fine-grain dependence info
323     if (Level > AL_Statement) {
324       auto TaggedMap =
325           isl_union_set_unwrap(isl_union_set_copy(TaggedStmtDomain));
326       auto Tags = isl_union_map_domain_map_union_pw_multi_aff(TaggedMap);
327       Schedule = isl_schedule_pullback_union_pw_multi_aff(Schedule, Tags);
328     }
329   } else {
330     isl_union_map *IdentityMap;
331     isl_union_pw_multi_aff *ReductionTags, *IdentityTags, *Tags;
332 
333     // Extract Reduction tags from the combined access domains in the given
334     // SCoP. The result is a map that maps each tagged element in the domain to
335     // the memory location it accesses. ReductionTags = {[Stmt[i] ->
336     // Array[f(i)]] -> Stmt[i] }
337     ReductionTags =
338         isl_union_map_domain_map_union_pw_multi_aff(ReductionTagMap);
339 
340     // Compute an identity map from each statement in domain to itself.
341     // IdentityTags = { [Stmt[i] -> Stmt[i] }
342     IdentityMap = isl_union_set_identity(isl_union_set_copy(TaggedStmtDomain));
343     IdentityTags = isl_union_pw_multi_aff_from_union_map(IdentityMap);
344 
345     Tags = isl_union_pw_multi_aff_union_add(ReductionTags, IdentityTags);
346 
347     // By pulling back Tags from Schedule, we have a schedule tree that can
348     // be used to compute normal dependences, as well as 'tagged' reduction
349     // dependences.
350     Schedule = isl_schedule_pullback_union_pw_multi_aff(Schedule, Tags);
351   }
352 
353   DEBUG(dbgs() << "Read: " << Read << "\n";
354         dbgs() << "Write: " << Write << "\n";
355         dbgs() << "MayWrite: " << MayWrite << "\n";
356         dbgs() << "Schedule: " << Schedule << "\n");
357 
358   {
359     IslMaxOperationsGuard MaxOpGuard(IslCtx.get(), OptComputeOut);
360 
361     RAW = WAW = WAR = RED = nullptr;
362 
363     if (OptAnalysisType == VALUE_BASED_ANALYSIS) {
364       isl_union_flow *Flow;
365 
366       Flow = buildFlow(Read, Write, MayWrite, Schedule);
367 
368       RAW = isl_union_flow_get_must_dependence(Flow);
369       isl_union_flow_free(Flow);
370 
371       Flow = buildFlow(Write, Write, Read, Schedule);
372 
373       WAW = isl_union_flow_get_must_dependence(Flow);
374       WAR = isl_union_flow_get_may_dependence(Flow);
375 
376       // This subtraction is needed to obtain the same results as were given by
377       // isl_union_map_compute_flow. For large sets this may add some
378       // compile-time cost. As there does not seem to be a need to distinguish
379       // between WAW and WAR, refactoring Polly to only track general non-flow
380       // dependences may improve performance.
381       WAR = isl_union_map_subtract(WAR, isl_union_map_copy(WAW));
382 
383       isl_union_flow_free(Flow);
384       isl_schedule_free(Schedule);
385     } else {
386       isl_union_flow *Flow;
387 
388       Write = isl_union_map_union(Write, isl_union_map_copy(MayWrite));
389 
390       Flow = buildFlow(Read, nullptr, Write, Schedule);
391 
392       RAW = isl_union_flow_get_may_dependence(Flow);
393       isl_union_flow_free(Flow);
394 
395       Flow = buildFlow(Write, nullptr, Read, Schedule);
396 
397       WAR = isl_union_flow_get_may_dependence(Flow);
398       isl_union_flow_free(Flow);
399 
400       Flow = buildFlow(Write, nullptr, Write, Schedule);
401 
402       WAW = isl_union_flow_get_may_dependence(Flow);
403       isl_union_flow_free(Flow);
404       isl_schedule_free(Schedule);
405     }
406 
407     isl_union_map_free(MayWrite);
408     isl_union_map_free(Write);
409     isl_union_map_free(Read);
410 
411     RAW = isl_union_map_coalesce(RAW);
412     WAW = isl_union_map_coalesce(WAW);
413     WAR = isl_union_map_coalesce(WAR);
414 
415     // End of max_operations scope.
416   }
417 
418   if (isl_ctx_last_error(IslCtx.get()) == isl_error_quota) {
419     isl_union_map_free(RAW);
420     isl_union_map_free(WAW);
421     isl_union_map_free(WAR);
422     RAW = WAW = WAR = nullptr;
423     isl_ctx_reset_error(IslCtx.get());
424   }
425 
426   // Drop out early, as the remaining computations are only needed for
427   // reduction dependences or dependences that are finer than statement
428   // level dependences.
429   if (!HasReductions && Level == AL_Statement) {
430     TC_RED = isl_union_map_empty(isl_union_set_get_space(TaggedStmtDomain));
431     isl_union_set_free(TaggedStmtDomain);
432     return;
433   }
434 
435   isl_union_map *STMT_RAW, *STMT_WAW, *STMT_WAR;
436   STMT_RAW = isl_union_map_intersect_domain(
437       isl_union_map_copy(RAW), isl_union_set_copy(TaggedStmtDomain));
438   STMT_WAW = isl_union_map_intersect_domain(
439       isl_union_map_copy(WAW), isl_union_set_copy(TaggedStmtDomain));
440   STMT_WAR =
441       isl_union_map_intersect_domain(isl_union_map_copy(WAR), TaggedStmtDomain);
442   DEBUG({
443     dbgs() << "Wrapped Dependences:\n";
444     dump();
445     dbgs() << "\n";
446   });
447 
448   // To handle reduction dependences we proceed as follows:
449   // 1) Aggregate all possible reduction dependences, namely all self
450   //    dependences on reduction like statements.
451   // 2) Intersect them with the actual RAW & WAW dependences to the get the
452   //    actual reduction dependences. This will ensure the load/store memory
453   //    addresses were __identical__ in the two iterations of the statement.
454   // 3) Relax the original RAW and WAW dependences by subtracting the actual
455   //    reduction dependences. Binary reductions (sum += A[i]) cause both, and
456   //    the same, RAW and WAW dependences.
457   // 4) Add the privatization dependences which are widened versions of
458   //    already present dependences. They model the effect of manual
459   //    privatization at the outermost possible place (namely after the last
460   //    write and before the first access to a reduction location).
461 
462   // Step 1)
463   RED = isl_union_map_empty(isl_union_map_get_space(RAW));
464   for (ScopStmt &Stmt : S) {
465     for (MemoryAccess *MA : Stmt) {
466       if (!MA->isReductionLike())
467         continue;
468       isl_set *AccDomW = isl_map_wrap(MA->getAccessRelation());
469       isl_map *Identity =
470           isl_map_from_domain_and_range(isl_set_copy(AccDomW), AccDomW);
471       RED = isl_union_map_add_map(RED, Identity);
472     }
473   }
474 
475   // Step 2)
476   RED = isl_union_map_intersect(RED, isl_union_map_copy(RAW));
477   RED = isl_union_map_intersect(RED, isl_union_map_copy(WAW));
478 
479   if (!isl_union_map_is_empty(RED)) {
480 
481     // Step 3)
482     RAW = isl_union_map_subtract(RAW, isl_union_map_copy(RED));
483     WAW = isl_union_map_subtract(WAW, isl_union_map_copy(RED));
484 
485     // Step 4)
486     addPrivatizationDependences();
487   }
488 
489   DEBUG({
490     dbgs() << "Final Wrapped Dependences:\n";
491     dump();
492     dbgs() << "\n";
493   });
494 
495   // RED_SIN is used to collect all reduction dependences again after we
496   // split them according to the causing memory accesses. The current assumption
497   // is that our method of splitting will not have any leftovers. In the end
498   // we validate this assumption until we have more confidence in this method.
499   isl_union_map *RED_SIN = isl_union_map_empty(isl_union_map_get_space(RAW));
500 
501   // For each reduction like memory access, check if there are reduction
502   // dependences with the access relation of the memory access as a domain
503   // (wrapped space!). If so these dependences are caused by this memory access.
504   // We then move this portion of reduction dependences back to the statement ->
505   // statement space and add a mapping from the memory access to these
506   // dependences.
507   for (ScopStmt &Stmt : S) {
508     for (MemoryAccess *MA : Stmt) {
509       if (!MA->isReductionLike())
510         continue;
511 
512       isl_set *AccDomW = isl_map_wrap(MA->getAccessRelation());
513       isl_union_map *AccRedDepU = isl_union_map_intersect_domain(
514           isl_union_map_copy(TC_RED), isl_union_set_from_set(AccDomW));
515       if (isl_union_map_is_empty(AccRedDepU)) {
516         isl_union_map_free(AccRedDepU);
517         continue;
518       }
519 
520       isl_map *AccRedDep = isl_map_from_union_map(AccRedDepU);
521       RED_SIN = isl_union_map_add_map(RED_SIN, isl_map_copy(AccRedDep));
522       AccRedDep = isl_map_zip(AccRedDep);
523       AccRedDep = isl_set_unwrap(isl_map_domain(AccRedDep));
524       setReductionDependences(MA, AccRedDep);
525     }
526   }
527 
528   assert(isl_union_map_is_equal(RED_SIN, TC_RED) &&
529          "Intersecting the reduction dependence domain with the wrapped access "
530          "relation is not enough, we need to loosen the access relation also");
531   isl_union_map_free(RED_SIN);
532 
533   RAW = isl_union_map_zip(RAW);
534   WAW = isl_union_map_zip(WAW);
535   WAR = isl_union_map_zip(WAR);
536   RED = isl_union_map_zip(RED);
537   TC_RED = isl_union_map_zip(TC_RED);
538 
539   DEBUG({
540     dbgs() << "Zipped Dependences:\n";
541     dump();
542     dbgs() << "\n";
543   });
544 
545   RAW = isl_union_set_unwrap(isl_union_map_domain(RAW));
546   WAW = isl_union_set_unwrap(isl_union_map_domain(WAW));
547   WAR = isl_union_set_unwrap(isl_union_map_domain(WAR));
548   RED = isl_union_set_unwrap(isl_union_map_domain(RED));
549   TC_RED = isl_union_set_unwrap(isl_union_map_domain(TC_RED));
550 
551   DEBUG({
552     dbgs() << "Unwrapped Dependences:\n";
553     dump();
554     dbgs() << "\n";
555   });
556 
557   RAW = isl_union_map_union(RAW, STMT_RAW);
558   WAW = isl_union_map_union(WAW, STMT_WAW);
559   WAR = isl_union_map_union(WAR, STMT_WAR);
560 
561   RAW = isl_union_map_coalesce(RAW);
562   WAW = isl_union_map_coalesce(WAW);
563   WAR = isl_union_map_coalesce(WAR);
564   RED = isl_union_map_coalesce(RED);
565   TC_RED = isl_union_map_coalesce(TC_RED);
566 
567   DEBUG(dump());
568 }
569 
570 bool Dependences::isValidSchedule(Scop &S,
571                                   StatementToIslMapTy *NewSchedule) const {
572   if (LegalityCheckDisabled)
573     return true;
574 
575   isl_union_map *Dependences = getDependences(TYPE_RAW | TYPE_WAW | TYPE_WAR);
576   isl_space *Space = S.getParamSpace();
577   isl_union_map *Schedule = isl_union_map_empty(Space);
578 
579   isl_space *ScheduleSpace = nullptr;
580 
581   for (ScopStmt &Stmt : S) {
582     isl_map *StmtScat;
583 
584     if (NewSchedule->find(&Stmt) == NewSchedule->end())
585       StmtScat = Stmt.getSchedule();
586     else
587       StmtScat = isl_map_copy((*NewSchedule)[&Stmt]);
588     assert(StmtScat &&
589            "Schedules that contain extension nodes require special handling.");
590 
591     if (!ScheduleSpace)
592       ScheduleSpace = isl_space_range(isl_map_get_space(StmtScat));
593 
594     Schedule = isl_union_map_add_map(Schedule, StmtScat);
595   }
596 
597   Dependences =
598       isl_union_map_apply_domain(Dependences, isl_union_map_copy(Schedule));
599   Dependences = isl_union_map_apply_range(Dependences, Schedule);
600 
601   isl_set *Zero = isl_set_universe(isl_space_copy(ScheduleSpace));
602   for (unsigned i = 0; i < isl_set_dim(Zero, isl_dim_set); i++)
603     Zero = isl_set_fix_si(Zero, isl_dim_set, i, 0);
604 
605   isl_union_set *UDeltas = isl_union_map_deltas(Dependences);
606   isl_set *Deltas = isl_union_set_extract_set(UDeltas, ScheduleSpace);
607   isl_union_set_free(UDeltas);
608 
609   isl_map *NonPositive = isl_set_lex_le_set(Deltas, Zero);
610   bool IsValid = isl_map_is_empty(NonPositive);
611   isl_map_free(NonPositive);
612 
613   return IsValid;
614 }
615 
616 // Check if the current scheduling dimension is parallel.
617 //
618 // We check for parallelism by verifying that the loop does not carry any
619 // dependences.
620 //
621 // Parallelism test: if the distance is zero in all outer dimensions, then it
622 // has to be zero in the current dimension as well.
623 //
624 // Implementation: first, translate dependences into time space, then force
625 // outer dimensions to be equal. If the distance is zero in the current
626 // dimension, then the loop is parallel. The distance is zero in the current
627 // dimension if it is a subset of a map with equal values for the current
628 // dimension.
629 bool Dependences::isParallel(isl_union_map *Schedule, isl_union_map *Deps,
630                              isl_pw_aff **MinDistancePtr) const {
631   isl_set *Deltas, *Distance;
632   isl_map *ScheduleDeps;
633   unsigned Dimension;
634   bool IsParallel;
635 
636   Deps = isl_union_map_apply_range(Deps, isl_union_map_copy(Schedule));
637   Deps = isl_union_map_apply_domain(Deps, isl_union_map_copy(Schedule));
638 
639   if (isl_union_map_is_empty(Deps)) {
640     isl_union_map_free(Deps);
641     return true;
642   }
643 
644   ScheduleDeps = isl_map_from_union_map(Deps);
645   Dimension = isl_map_dim(ScheduleDeps, isl_dim_out) - 1;
646 
647   for (unsigned i = 0; i < Dimension; i++)
648     ScheduleDeps = isl_map_equate(ScheduleDeps, isl_dim_out, i, isl_dim_in, i);
649 
650   Deltas = isl_map_deltas(ScheduleDeps);
651   Distance = isl_set_universe(isl_set_get_space(Deltas));
652 
653   // [0, ..., 0, +] - All zeros and last dimension larger than zero
654   for (unsigned i = 0; i < Dimension; i++)
655     Distance = isl_set_fix_si(Distance, isl_dim_set, i, 0);
656 
657   Distance = isl_set_lower_bound_si(Distance, isl_dim_set, Dimension, 1);
658   Distance = isl_set_intersect(Distance, Deltas);
659 
660   IsParallel = isl_set_is_empty(Distance);
661   if (IsParallel || !MinDistancePtr) {
662     isl_set_free(Distance);
663     return IsParallel;
664   }
665 
666   Distance = isl_set_project_out(Distance, isl_dim_set, 0, Dimension);
667   Distance = isl_set_coalesce(Distance);
668 
669   // This last step will compute a expression for the minimal value in the
670   // distance polyhedron Distance with regards to the first (outer most)
671   // dimension.
672   *MinDistancePtr = isl_pw_aff_coalesce(isl_set_dim_min(Distance, 0));
673 
674   return false;
675 }
676 
677 static void printDependencyMap(raw_ostream &OS, __isl_keep isl_union_map *DM) {
678   if (DM)
679     OS << DM << "\n";
680   else
681     OS << "n/a\n";
682 }
683 
684 void Dependences::print(raw_ostream &OS) const {
685   OS << "\tRAW dependences:\n\t\t";
686   printDependencyMap(OS, RAW);
687   OS << "\tWAR dependences:\n\t\t";
688   printDependencyMap(OS, WAR);
689   OS << "\tWAW dependences:\n\t\t";
690   printDependencyMap(OS, WAW);
691   OS << "\tReduction dependences:\n\t\t";
692   printDependencyMap(OS, RED);
693   OS << "\tTransitive closure of reduction dependences:\n\t\t";
694   printDependencyMap(OS, TC_RED);
695 }
696 
697 void Dependences::dump() const { print(dbgs()); }
698 
699 void Dependences::releaseMemory() {
700   isl_union_map_free(RAW);
701   isl_union_map_free(WAR);
702   isl_union_map_free(WAW);
703   isl_union_map_free(RED);
704   isl_union_map_free(TC_RED);
705 
706   RED = RAW = WAR = WAW = TC_RED = nullptr;
707 
708   for (auto &ReductionDeps : ReductionDependences)
709     isl_map_free(ReductionDeps.second);
710   ReductionDependences.clear();
711 }
712 
713 __isl_give isl_union_map *Dependences::getDependences(int Kinds) const {
714   assert(hasValidDependences() && "No valid dependences available");
715   isl_space *Space = isl_union_map_get_space(RAW);
716   isl_union_map *Deps = isl_union_map_empty(Space);
717 
718   if (Kinds & TYPE_RAW)
719     Deps = isl_union_map_union(Deps, isl_union_map_copy(RAW));
720 
721   if (Kinds & TYPE_WAR)
722     Deps = isl_union_map_union(Deps, isl_union_map_copy(WAR));
723 
724   if (Kinds & TYPE_WAW)
725     Deps = isl_union_map_union(Deps, isl_union_map_copy(WAW));
726 
727   if (Kinds & TYPE_RED)
728     Deps = isl_union_map_union(Deps, isl_union_map_copy(RED));
729 
730   if (Kinds & TYPE_TC_RED)
731     Deps = isl_union_map_union(Deps, isl_union_map_copy(TC_RED));
732 
733   Deps = isl_union_map_coalesce(Deps);
734   Deps = isl_union_map_detect_equalities(Deps);
735   return Deps;
736 }
737 
738 bool Dependences::hasValidDependences() const {
739   return (RAW != nullptr) && (WAR != nullptr) && (WAW != nullptr);
740 }
741 
742 __isl_give isl_map *
743 Dependences::getReductionDependences(MemoryAccess *MA) const {
744   return isl_map_copy(ReductionDependences.lookup(MA));
745 }
746 
747 void Dependences::setReductionDependences(MemoryAccess *MA, isl_map *D) {
748   assert(ReductionDependences.count(MA) == 0 &&
749          "Reduction dependences set twice!");
750   ReductionDependences[MA] = D;
751 }
752 
753 const Dependences &
754 DependenceInfo::getDependences(Dependences::AnalysisLevel Level) {
755   if (Dependences *d = D[Level].get())
756     return *d;
757 
758   return recomputeDependences(Level);
759 }
760 
761 const Dependences &
762 DependenceInfo::recomputeDependences(Dependences::AnalysisLevel Level) {
763   D[Level].reset(new Dependences(S->getSharedIslCtx(), Level));
764   D[Level]->calculateDependences(*S);
765   return *D[Level];
766 }
767 
768 bool DependenceInfo::runOnScop(Scop &ScopVar) {
769   S = &ScopVar;
770   return false;
771 }
772 
773 /// Print the dependences for the given SCoP to @p OS.
774 
775 void polly::DependenceInfo::printScop(raw_ostream &OS, Scop &S) const {
776   if (auto d = D[OptAnalysisLevel].get()) {
777     d->print(OS);
778     return;
779   }
780 
781   // Otherwise create the dependences on-the-fly and print it
782   Dependences D(S.getSharedIslCtx(), OptAnalysisLevel);
783   D.calculateDependences(S);
784   D.print(OS);
785 }
786 
787 void DependenceInfo::getAnalysisUsage(AnalysisUsage &AU) const {
788   AU.addRequiredTransitive<ScopInfoRegionPass>();
789   AU.setPreservesAll();
790 }
791 
792 char DependenceInfo::ID = 0;
793 
794 Pass *polly::createDependenceInfoPass() { return new DependenceInfo(); }
795 
796 INITIALIZE_PASS_BEGIN(DependenceInfo, "polly-dependences",
797                       "Polly - Calculate dependences", false, false);
798 INITIALIZE_PASS_DEPENDENCY(ScopInfoRegionPass);
799 INITIALIZE_PASS_END(DependenceInfo, "polly-dependences",
800                     "Polly - Calculate dependences", false, false)
801 
802 //===----------------------------------------------------------------------===//
803 const Dependences &
804 DependenceInfoWrapperPass::getDependences(Scop *S,
805                                           Dependences::AnalysisLevel Level) {
806   auto It = ScopToDepsMap.find(S);
807   if (It != ScopToDepsMap.end())
808     if (It->second) {
809       if (It->second->getDependenceLevel() == Level)
810         return *It->second.get();
811     }
812   return recomputeDependences(S, Level);
813 }
814 
815 const Dependences &DependenceInfoWrapperPass::recomputeDependences(
816     Scop *S, Dependences::AnalysisLevel Level) {
817   std::unique_ptr<Dependences> D(new Dependences(S->getSharedIslCtx(), Level));
818   D->calculateDependences(*S);
819   auto Inserted = ScopToDepsMap.insert(std::make_pair(S, std::move(D)));
820   return *Inserted.first->second;
821 }
822 
823 bool DependenceInfoWrapperPass::runOnFunction(Function &F) {
824   auto &SI = getAnalysis<ScopInfoWrapperPass>();
825   for (auto &It : SI) {
826     assert(It.second && "Invalid SCoP object!");
827     recomputeDependences(It.second.get(), Dependences::AL_Access);
828   }
829   return false;
830 }
831 
832 void DependenceInfoWrapperPass::print(raw_ostream &OS, const Module *M) const {
833   for (auto &It : ScopToDepsMap) {
834     assert((It.first && It.second) && "Invalid Scop or Dependence object!\n");
835     It.second->print(OS);
836   }
837 }
838 
839 void DependenceInfoWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
840   AU.addRequiredTransitive<ScopInfoWrapperPass>();
841   AU.setPreservesAll();
842 }
843 
844 char DependenceInfoWrapperPass::ID = 0;
845 
846 Pass *polly::createDependenceInfoWrapperPassPass() {
847   return new DependenceInfoWrapperPass();
848 }
849 
850 INITIALIZE_PASS_BEGIN(
851     DependenceInfoWrapperPass, "polly-function-dependences",
852     "Polly - Calculate dependences for all the SCoPs of a function", false,
853     false)
854 INITIALIZE_PASS_DEPENDENCY(ScopInfoWrapperPass);
855 INITIALIZE_PASS_END(
856     DependenceInfoWrapperPass, "polly-function-dependences",
857     "Polly - Calculate dependences for all the SCoPs of a function", false,
858     false)
859