/usr/lib/llvm-6.0/include/polly/DependenceInfo.h is in libclang-common-6.0-dev 1:6.0-1ubuntu2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 | //===--- polly/DependenceInfo.h - Polyhedral dependency analysis *- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Calculate the data dependency relations for a Scop using ISL.
//
// The integer set library (ISL) from Sven has an integrated dependency analysis
// to calculate data dependences. This pass takes advantage of this and
// calculates those dependences of a Scop.
//
// The dependences in this pass are exact in terms that for a specific read
// statement instance only the last write statement instance is returned. In
// case of may-writes, a set of possible write instances is returned. This
// analysis will never produce redundant dependences.
//
//===----------------------------------------------------------------------===//
#ifndef POLLY_DEPENDENCE_INFO_H
#define POLLY_DEPENDENCE_INFO_H
#include "polly/ScopPass.h"
#include "isl/ctx.h"
struct isl_pw_aff;
struct isl_union_map;
struct isl_union_set;
struct isl_map;
struct isl_set;
struct clast_for;
using namespace llvm;
namespace polly {
class Scop;
class ScopStmt;
class MemoryAccess;
/// The accumulated dependence information for a SCoP.
///
/// The Dependences struct holds all dependence information we collect and
/// compute for one SCoP. It also offers an interface that allows users to
/// query only specific parts.
struct Dependences {
// Granularities of the current dependence analysis
enum AnalysisLevel {
AL_Statement = 0,
// Distinguish accessed memory references in the same statement
AL_Reference,
// Distinguish memory access instances in the same statement
AL_Access,
NumAnalysisLevels
};
/// Map type for reduction dependences.
using ReductionDependencesMapTy = DenseMap<MemoryAccess *, isl_map *>;
/// Map type to associate statements with schedules.
using StatementToIslMapTy = DenseMap<ScopStmt *, isl_map *>;
/// The type of the dependences.
///
/// Reduction dependences are separated from RAW/WAW/WAR dependences because
/// we can ignore them during the scheduling. That's because the order
/// in which the reduction statements are executed does not matter. However,
/// if they are executed in parallel we need to take additional measures
/// (e.g, privatization) to ensure a correct result. The (reverse) transitive
/// closure of the reduction dependences are used to check for parallel
/// executed reduction statements during code generation. These dependences
/// connect all instances of a reduction with each other, they are therefore
/// cyclic and possibly "reversed".
enum Type {
// Write after read
TYPE_WAR = 1 << 0,
// Read after write
TYPE_RAW = 1 << 1,
// Write after write
TYPE_WAW = 1 << 2,
// Reduction dependences
TYPE_RED = 1 << 3,
// Transitive closure of the reduction dependences (& the reverse)
TYPE_TC_RED = 1 << 4,
};
const std::shared_ptr<isl_ctx> &getSharedIslCtx() const { return IslCtx; }
/// Get the dependences of type @p Kinds.
///
/// @param Kinds This integer defines the different kinds of dependences
/// that will be returned. To return more than one kind, the
/// different kinds are 'ored' together.
__isl_give isl_union_map *getDependences(int Kinds) const;
/// Report if valid dependences are available.
bool hasValidDependences() const;
/// Return the reduction dependences caused by @p MA.
///
/// @return The reduction dependences caused by @p MA or nullptr if none.
__isl_give isl_map *getReductionDependences(MemoryAccess *MA) const;
/// Return all reduction dependences.
const ReductionDependencesMapTy &getReductionDependences() const {
return ReductionDependences;
}
/// Check if a partial schedule is parallel wrt to @p Deps.
///
/// @param Schedule The subset of the schedule space that we want to
/// check.
/// @param Deps The dependences @p Schedule needs to respect.
/// @param MinDistancePtr If not nullptr, the minimal dependence distance will
/// be returned at the address of that pointer
///
/// @return Returns true, if executing parallel the outermost dimension of
/// @p Schedule is valid according to the dependences @p Deps.
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 new schedule is valid.
///
/// @param S The current SCoP.
/// @param NewSchedules The new schedules
///
/// @return True if the new schedule is valid, false if it reverses
/// dependences.
bool isValidSchedule(Scop &S, StatementToIslMapTy *NewSchedules) const;
/// Print the stored dependence information.
void print(llvm::raw_ostream &OS) const;
/// Dump the dependence information stored to the dbgs stream.
void dump() const;
/// Return the granularity of this dependence analysis.
AnalysisLevel getDependenceLevel() { return Level; }
/// Allow the DependenceInfo access to private members and methods.
///
/// To restrict access to the internal state, only the DependenceInfo class
/// is able to call or modify a Dependences struct.
friend struct DependenceAnalysis;
friend struct DependenceInfoPrinterPass;
friend class DependenceInfo;
friend class DependenceInfoWrapperPass;
/// Destructor that will free internal objects.
~Dependences() { releaseMemory(); }
private:
/// Create an empty dependences struct.
explicit Dependences(const std::shared_ptr<isl_ctx> &IslCtx,
AnalysisLevel Level)
: RAW(nullptr), WAR(nullptr), WAW(nullptr), RED(nullptr), TC_RED(nullptr),
IslCtx(IslCtx), Level(Level) {}
/// Calculate and add at the privatization dependences.
void addPrivatizationDependences();
/// Calculate the dependences for a certain SCoP @p S.
void calculateDependences(Scop &S);
/// Set the reduction dependences for @p MA to @p Deps.
void setReductionDependences(MemoryAccess *MA, __isl_take isl_map *Deps);
/// Free the objects associated with this Dependences struct.
///
/// The Dependences struct will again be "empty" afterwards.
void releaseMemory();
/// The different basic kinds of dependences we calculate.
isl_union_map *RAW;
isl_union_map *WAR;
isl_union_map *WAW;
/// The special reduction dependences.
isl_union_map *RED;
/// The (reverse) transitive closure of reduction dependences.
isl_union_map *TC_RED;
/// Mapping from memory accesses to their reduction dependences.
ReductionDependencesMapTy ReductionDependences;
/// Isl context from the SCoP.
std::shared_ptr<isl_ctx> IslCtx;
/// Granularity of this dependence analysis.
const AnalysisLevel Level;
};
struct DependenceAnalysis : public AnalysisInfoMixin<DependenceAnalysis> {
static AnalysisKey Key;
struct Result {
Scop &S;
std::unique_ptr<Dependences> D[Dependences::NumAnalysisLevels];
/// Return the dependence information for the current SCoP.
///
/// @param Level The granularity of dependence analysis result.
///
/// @return The dependence analysis result
///
const Dependences &getDependences(Dependences::AnalysisLevel Level);
/// Recompute dependences from schedule and memory accesses.
const Dependences &recomputeDependences(Dependences::AnalysisLevel Level);
};
Result run(Scop &S, ScopAnalysisManager &SAM,
ScopStandardAnalysisResults &SAR);
};
struct DependenceInfoPrinterPass
: public PassInfoMixin<DependenceInfoPrinterPass> {
DependenceInfoPrinterPass(raw_ostream &OS) : OS(OS) {}
PreservedAnalyses run(Scop &S, ScopAnalysisManager &,
ScopStandardAnalysisResults &, SPMUpdater &);
raw_ostream &OS;
};
class DependenceInfo : public ScopPass {
public:
static char ID;
/// Construct a new DependenceInfo pass.
DependenceInfo() : ScopPass(ID) {}
/// Return the dependence information for the current SCoP.
///
/// @param Level The granularity of dependence analysis result.
///
/// @return The dependence analysis result
///
const Dependences &getDependences(Dependences::AnalysisLevel Level);
/// Recompute dependences from schedule and memory accesses.
const Dependences &recomputeDependences(Dependences::AnalysisLevel Level);
/// Compute the dependence information for the SCoP @p S.
bool runOnScop(Scop &S) override;
/// Print the dependences for the given SCoP to @p OS.
void printScop(raw_ostream &OS, Scop &) const override;
/// Release the internal memory.
void releaseMemory() override {
for (auto &d : D)
d.reset();
}
/// Register all analyses and transformation required.
void getAnalysisUsage(AnalysisUsage &AU) const override;
private:
Scop *S;
/// Dependences struct for the current SCoP.
std::unique_ptr<Dependences> D[Dependences::NumAnalysisLevels];
};
/// Construct a new DependenceInfoWrapper pass.
class DependenceInfoWrapperPass : public FunctionPass {
public:
static char ID;
/// Construct a new DependenceInfoWrapper pass.
DependenceInfoWrapperPass() : FunctionPass(ID) {}
/// Return the dependence information for the given SCoP.
///
/// @param S SCoP object.
/// @param Level The granularity of dependence analysis result.
///
/// @return The dependence analysis result
///
const Dependences &getDependences(Scop *S, Dependences::AnalysisLevel Level);
/// Recompute dependences from schedule and memory accesses.
const Dependences &recomputeDependences(Scop *S,
Dependences::AnalysisLevel Level);
/// Compute the dependence information on-the-fly for the function.
bool runOnFunction(Function &F) override;
/// Print the dependences for the current function to @p OS.
void print(raw_ostream &OS, const Module *M = nullptr) const override;
/// Release the internal memory.
void releaseMemory() override { ScopToDepsMap.clear(); }
/// Register all analyses and transformation required.
void getAnalysisUsage(AnalysisUsage &AU) const override;
private:
using ScopToDepsMapTy = DenseMap<Scop *, std::unique_ptr<Dependences>>;
/// Scop to Dependence map for the current function.
ScopToDepsMapTy ScopToDepsMap;
};
} // namespace polly
namespace llvm {
class PassRegistry;
void initializeDependenceInfoPass(llvm::PassRegistry &);
void initializeDependenceInfoWrapperPassPass(llvm::PassRegistry &);
} // namespace llvm
#endif
|