Polly 24.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 isl::boolean::true if executing parallel the outermost dimension
123 /// of @p Schedule is valid according to the dependences @p Deps,
124 /// isl::boolean::false if it is not, and isl::boolean::error() if the
125 /// result could not be computed (e.g. the ISL operation quota was
126 /// exhausted during AST generation).
128 isl::pw_aff *MinDistancePtr = nullptr) const;
129
130 /// Check if a new schedule is valid.
131 ///
132 /// @param S The current SCoP.
133 /// @param NewSchedules The new schedules
134 ///
135 /// @return True if the new schedule is valid, false if it reverses
136 /// dependences.
137 bool isValidSchedule(Scop &S, const StatementToIslMapTy &NewSchedules) const;
138
139 /// Return true of the schedule @p NewSched is a schedule for @S that does not
140 /// violate any dependences.
141 bool isValidSchedule(Scop &S, isl::schedule NewSched) const;
142
143 /// Print the stored dependence information.
144 void print(llvm::raw_ostream &OS) const;
145
146 /// Dump the dependence information stored to the dbgs stream.
147 void dump() const;
148
149 /// Return the granularity of this dependence analysis.
151
152 /// Allow the DependenceInfo access to private members and methods.
153 ///
154 /// To restrict access to the internal state, only the DependenceInfo class
155 /// is able to call or modify a Dependences struct.
156 friend struct DependenceAnalysis;
158 friend class DependenceInfo;
159
160 /// Destructor that will free internal objects.
162
163private:
164 /// Create an empty dependences struct.
165 explicit Dependences(const std::shared_ptr<isl_ctx> &IslCtx,
167 : RAW(nullptr), WAR(nullptr), WAW(nullptr), RED(nullptr), TC_RED(nullptr),
169
170 /// Calculate and add at the privatization dependences.
172
173 /// Calculate the dependences for a certain SCoP @p S.
175
176 /// Set the reduction dependences for @p MA to @p Deps.
178
179 /// Free the objects associated with this Dependences struct.
180 ///
181 /// The Dependences struct will again be "empty" afterwards.
182 void releaseMemory();
183
184 /// The different basic kinds of dependences we calculate.
188
189 /// The special reduction dependences.
191
192 /// The (reverse) transitive closure of reduction dependences.
194
195 /// Mapping from memory accesses to their reduction dependences.
197
198 /// Isl context from the SCoP.
199 std::shared_ptr<isl_ctx> IslCtx;
200
201 /// Granularity of this dependence analysis.
203};
204
206
207struct DependenceAnalysis final {
208 struct Result {
210 std::unique_ptr<Dependences> D[Dependences::NumAnalysisLevels];
211
212 /// Return the dependence information for the current SCoP.
213 ///
214 /// @param Level The granularity of dependence analysis result.
215 ///
216 /// @return The dependence analysis result
217 ///
219
220 /// Recompute dependences from schedule and memory accesses.
222
223 /// Invalidate the dependence information and recompute it when needed
224 /// again.
225 /// May be required when the underlying Scop was changed in a way that
226 /// would add new dependencies (e.g. between new statement instances
227 /// insierted into the SCoP) or intentionally breaks existing ones. It is
228 /// not required when updating the schedule that conforms the existing
229 /// dependencies.
230 void abandonDependences();
231 };
232};
233
235} // namespace polly
236
237#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
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.
isl::boolean isKnownParallel(isl::union_map Schedule, isl::union_map Deps, isl::pw_aff *MinDistancePtr=nullptr) const
Check if a partial schedule is parallel wrt to Deps.
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:427
Statement of the Scop.
Definition ScopInfo.h:1136
Static Control Part.
Definition ScopInfo.h:1626
#define __isl_take
Definition ctx.h:23
#define __isl_give
Definition ctx.h:20
#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.