Polly 22.0.0git
DependenceInfo.h
Go to the documentation of this file.
1//===--- polly/DependenceInfo.h - Polyhedral dependency analysis *- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Calculate the data dependency relations for a Scop using ISL.
10//
11// The integer set library (ISL) from Sven has an integrated dependency analysis
12// to calculate data dependences. This pass takes advantage of this and
13// calculates those dependences of a Scop.
14//
15// The dependences in this pass are exact in terms that for a specific read
16// statement instance only the last write statement instance is returned. In
17// case of may-writes, a set of possible write instances is returned. This
18// analysis will never produce redundant dependences.
19//
20//===----------------------------------------------------------------------===//
21
22#ifndef POLLY_DEPENDENCE_INFO_H
23#define POLLY_DEPENDENCE_INFO_H
24
25#include "llvm/ADT/DenseMap.h"
26#include "isl/ctx.h"
28
29namespace llvm {
30class raw_ostream;
31}
32
33namespace polly {
34class MemoryAccess;
35class Scop;
36class ScopStmt;
37
38using llvm::DenseMap;
39
40/// The accumulated dependence information for a SCoP.
41///
42/// The Dependences struct holds all dependence information we collect and
43/// compute for one SCoP. It also offers an interface that allows users to
44/// query only specific parts.
45class Dependences final {
46public:
47 // Granularities of the current dependence analysis
50 // Distinguish accessed memory references in the same statement
52 // Distinguish memory access instances in the same statement
54
56 };
57
58 /// Map type for reduction dependences.
59 using ReductionDependencesMapTy = DenseMap<MemoryAccess *, isl_map *>;
60
61 /// Map type to associate statements with schedules.
62 using StatementToIslMapTy = DenseMap<ScopStmt *, isl::map>;
63
64 /// The type of the dependences.
65 ///
66 /// Reduction dependences are separated from RAW/WAW/WAR dependences because
67 /// we can ignore them during the scheduling. That's because the order
68 /// in which the reduction statements are executed does not matter. However,
69 /// if they are executed in parallel we need to take additional measures
70 /// (e.g, privatization) to ensure a correct result. The (reverse) transitive
71 /// closure of the reduction dependences are used to check for parallel
72 /// executed reduction statements during code generation. These dependences
73 /// connect all instances of a reduction with each other, they are therefore
74 /// cyclic and possibly "reversed".
75 enum Type {
76 // Write after read
77 TYPE_WAR = 1 << 0,
78
79 // Read after write
80 TYPE_RAW = 1 << 1,
81
82 // Write after write
83 TYPE_WAW = 1 << 2,
84
85 // Reduction dependences
86 TYPE_RED = 1 << 3,
87
88 // Transitive closure of the reduction dependences (& the reverse)
89 TYPE_TC_RED = 1 << 4,
90 };
91
92 const std::shared_ptr<isl_ctx> &getSharedIslCtx() const { return IslCtx; }
93
94 /// Get the dependences of type @p Kinds.
95 ///
96 /// @param Kinds This integer defines the different kinds of dependences
97 /// that will be returned. To return more than one kind, the
98 /// different kinds are 'ored' together.
99 isl::union_map getDependences(int Kinds) const;
100
101 /// Report if valid dependences are available.
102 bool hasValidDependences() const;
103
104 /// Return the reduction dependences caused by @p MA.
105 ///
106 /// @return The reduction dependences caused by @p MA or nullptr if none.
108
109 /// Return all reduction dependences.
113
114 /// Check if a partial schedule is parallel wrt to @p Deps.
115 ///
116 /// @param Schedule The subset of the schedule space that we want to
117 /// check.
118 /// @param Deps The dependences @p Schedule needs to respect.
119 /// @param MinDistancePtr If not nullptr, the minimal dependence distance will
120 /// be returned at the address of that pointer
121 ///
122 /// @return Returns true, if executing parallel the outermost dimension of
123 /// @p Schedule is valid according to the dependences @p Deps.
124 bool isParallel(__isl_keep isl_union_map *Schedule,
126 __isl_give isl_pw_aff **MinDistancePtr = nullptr) const;
127
128 /// Check if a new schedule is valid.
129 ///
130 /// @param S The current SCoP.
131 /// @param NewSchedules The new schedules
132 ///
133 /// @return True if the new schedule is valid, false if it reverses
134 /// dependences.
135 bool isValidSchedule(Scop &S, const StatementToIslMapTy &NewSchedules) const;
136
137 /// Return true of the schedule @p NewSched is a schedule for @S that does not
138 /// violate any dependences.
139 bool isValidSchedule(Scop &S, isl::schedule NewSched) const;
140
141 /// Print the stored dependence information.
142 void print(llvm::raw_ostream &OS) const;
143
144 /// Dump the dependence information stored to the dbgs stream.
145 void dump() const;
146
147 /// Return the granularity of this dependence analysis.
149
150 /// Allow the DependenceInfo access to private members and methods.
151 ///
152 /// To restrict access to the internal state, only the DependenceInfo class
153 /// is able to call or modify a Dependences struct.
154 friend struct DependenceAnalysis;
156 friend class DependenceInfo;
157
158 /// Destructor that will free internal objects.
160
161private:
162 /// Create an empty dependences struct.
163 explicit Dependences(const std::shared_ptr<isl_ctx> &IslCtx,
165 : RAW(nullptr), WAR(nullptr), WAW(nullptr), RED(nullptr), TC_RED(nullptr),
167
168 /// Calculate and add at the privatization dependences.
170
171 /// Calculate the dependences for a certain SCoP @p S.
173
174 /// Set the reduction dependences for @p MA to @p Deps.
176
177 /// Free the objects associated with this Dependences struct.
178 ///
179 /// The Dependences struct will again be "empty" afterwards.
180 void releaseMemory();
181
182 /// The different basic kinds of dependences we calculate.
186
187 /// The special reduction dependences.
189
190 /// The (reverse) transitive closure of reduction dependences.
192
193 /// Mapping from memory accesses to their reduction dependences.
195
196 /// Isl context from the SCoP.
197 std::shared_ptr<isl_ctx> IslCtx;
198
199 /// Granularity of this dependence analysis.
201};
202
204
205struct DependenceAnalysis final {
206 struct Result {
208 std::unique_ptr<Dependences> D[Dependences::NumAnalysisLevels];
209
210 /// Return the dependence information for the current SCoP.
211 ///
212 /// @param Level The granularity of dependence analysis result.
213 ///
214 /// @return The dependence analysis result
215 ///
217
218 /// Recompute dependences from schedule and memory accesses.
220
221 /// Invalidate the dependence information and recompute it when needed
222 /// again.
223 /// May be required when the underlying Scop was changed in a way that
224 /// would add new dependencies (e.g. between new statement instances
225 /// insierted into the SCoP) or intentionally breaks existing ones. It is
226 /// not required when updating the schedule that conforms the existing
227 /// dependencies.
228 void abandonDependences();
229 };
230};
231
233} // namespace polly
234
235#endif
Dependences::StatementToIslMapTy StatementToIslMapTy
The accumulated dependence information for a SCoP.
void setReductionDependences(MemoryAccess *MA, __isl_take isl_map *Deps)
Set the reduction dependences for MA to Deps.
DenseMap< ScopStmt *, isl::map > StatementToIslMapTy
Map type to associate statements with schedules.
~Dependences()
Destructor that will free internal objects.
isl_union_map * TC_RED
The (reverse) transitive closure of reduction dependences.
void addPrivatizationDependences()
Calculate and add at the privatization dependences.
friend struct DependenceInfoPrinterPass
bool isParallel(__isl_keep isl_union_map *Schedule, __isl_take isl_union_map *Deps, __isl_give isl_pw_aff **MinDistancePtr=nullptr) const
Check if a partial schedule is parallel wrt to Deps.
const AnalysisLevel Level
Granularity of this dependence analysis.
friend class DependenceInfo
isl_union_map * WAW
void print(llvm::raw_ostream &OS) const
Print the stored dependence information.
const ReductionDependencesMapTy & getReductionDependences() const
Return all reduction dependences.
void calculateDependences(Scop &S)
Calculate the dependences for a certain SCoP S.
bool hasValidDependences() const
Report if valid dependences are available.
isl_union_map * RED
The special reduction dependences.
isl_union_map * RAW
The different basic kinds of dependences we calculate.
void dump() const
Dump the dependence information stored to the dbgs stream.
AnalysisLevel getDependenceLevel()
Return the granularity of this dependence analysis.
const std::shared_ptr< isl_ctx > & getSharedIslCtx() const
isl::union_map getDependences(int Kinds) const
Get the dependences of type Kinds.
bool isValidSchedule(Scop &S, const StatementToIslMapTy &NewSchedules) const
Check if a new schedule is valid.
friend struct DependenceAnalysis
Allow the DependenceInfo access to private members and methods.
void releaseMemory()
Free the objects associated with this Dependences struct.
Type
The type of the dependences.
std::shared_ptr< isl_ctx > IslCtx
Isl context from the SCoP.
Dependences(const std::shared_ptr< isl_ctx > &IslCtx, AnalysisLevel Level)
Create an empty dependences struct.
isl_union_map * WAR
DenseMap< MemoryAccess *, isl_map * > ReductionDependencesMapTy
Map type for reduction dependences.
ReductionDependencesMapTy ReductionDependences
Mapping from memory accesses to their reduction dependences.
Represent memory accesses in statements.
Definition ScopInfo.h:426
Statement of the Scop.
Definition ScopInfo.h:1135
Static Control Part.
Definition ScopInfo.h:1625
#define __isl_take
Definition ctx.h:22
#define __isl_give
Definition ctx.h:19
#define __isl_keep
Definition ctx.h:25
#define S(TYPE, NAME)
Dependences::AnalysisLevel OptAnalysisLevel
DependenceAnalysis::Result runDependenceAnalysis(Scop &S)
const Dependences & getDependences(Dependences::AnalysisLevel Level)
Return the dependence information for the current SCoP.
std::unique_ptr< Dependences > D[Dependences::NumAnalysisLevels]
const Dependences & recomputeDependences(Dependences::AnalysisLevel Level)
Recompute dependences from schedule and memory accesses.
void abandonDependences()
Invalidate the dependence information and recompute it when needed again.