/usr/lib/llvm-6.0/include/polly/ZoneAlgo.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 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 | //===------ ZoneAlgo.h ------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Derive information about array elements between statements ("Zones").
//
//===----------------------------------------------------------------------===//
#ifndef POLLY_ZONEALGO_H
#define POLLY_ZONEALGO_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "isl/isl-noexceptions.h"
#include <memory>
namespace llvm {
class Value;
class LoopInfo;
class Loop;
class PHINode;
class raw_ostream;
} // namespace llvm
namespace polly {
class Scop;
class ScopStmt;
class MemoryAccess;
class ScopArrayInfo;
/// Return only the mappings that map to known values.
///
/// @param UMap { [] -> ValInst[] }
///
/// @return { [] -> ValInst[] }
isl::union_map filterKnownValInst(const isl::union_map &UMap);
/// Base class for algorithms based on zones, like DeLICM.
class ZoneAlgorithm {
protected:
/// The name of the pass this is used from. Used for optimization remarks.
const char *PassName;
/// Hold a reference to the isl_ctx to avoid it being freed before we released
/// all of the isl objects.
///
/// This must be declared before any other member that holds an isl object.
/// This guarantees that the shared_ptr and its isl_ctx is destructed last,
/// after all other members free'd the isl objects they were holding.
std::shared_ptr<isl_ctx> IslCtx;
/// Cached reaching definitions for each ScopStmt.
///
/// Use getScalarReachingDefinition() to get its contents.
llvm::DenseMap<ScopStmt *, isl::map> ScalarReachDefZone;
/// The analyzed Scop.
Scop *S;
/// LoopInfo analysis used to determine whether values are synthesizable.
llvm::LoopInfo *LI;
/// Parameter space that does not need realignment.
isl::space ParamSpace;
/// Space the schedule maps to.
isl::space ScatterSpace;
/// Cached version of the schedule and domains.
isl::union_map Schedule;
/// Combined access relations of all MemoryKind::Array READ accesses.
/// { DomainRead[] -> Element[] }
isl::union_map AllReads;
/// The loaded values (llvm::LoadInst) of all reads.
/// { [Element[] -> DomainRead[]] -> ValInst[] }
isl::union_map AllReadValInst;
/// Combined access relations of all MemoryKind::Array, MAY_WRITE accesses.
/// { DomainMayWrite[] -> Element[] }
isl::union_map AllMayWrites;
/// Combined access relations of all MemoryKind::Array, MUST_WRITE accesses.
/// { DomainMustWrite[] -> Element[] }
isl::union_map AllMustWrites;
/// Combined access relations of all MK_Array write accesses (union of
/// AllMayWrites and AllMustWrites).
/// { DomainWrite[] -> Element[] }
isl::union_map AllWrites;
/// The value instances written to array elements of all write accesses.
/// { [Element[] -> DomainWrite[]] -> ValInst[] }
isl::union_map AllWriteValInst;
/// All reaching definitions for MemoryKind::Array writes.
/// { [Element[] -> Zone[]] -> DomainWrite[] }
isl::union_map WriteReachDefZone;
/// Map llvm::Values to an isl identifier.
/// Used with -polly-use-llvm-names=false as an alternative method to get
/// unique ids that do not depend on pointer values.
llvm::DenseMap<llvm::Value *, isl::id> ValueIds;
/// Set of array elements that can be reliably used for zone analysis.
/// { Element[] }
isl::union_set CompatibleElts;
/// List of PHIs that may transitively refer to themselves.
///
/// Computing them would require a polyhedral transitive closure operation,
/// for which isl may only return an approximation. For correctness, we always
/// require an exact result. Hence, we exclude such PHIs.
llvm::SmallPtrSet<llvm::PHINode *, 4> RecursivePHIs;
/// PHIs that have been computed.
///
/// Computed PHIs are replaced by their incoming values using #NormalizeMap.
llvm::DenseSet<llvm::PHINode *> ComputedPHIs;
/// For computed PHIs, contains the ValInst they stand for.
///
/// To show an example, assume the following PHINode:
///
/// Stmt:
/// %phi = phi double [%val1, %bb1], [%val2, %bb2]
///
/// It's ValInst is:
///
/// { [Stmt[i] -> phi[]] }
///
/// The value %phi will be either %val1 or %val2, depending on whether in
/// iteration i %bb1 or %bb2 has been executed before. In SCoPs, this can be
/// determined at compile-time, and the result stored in #NormalizeMap. For
/// the previous example, it could be:
///
/// { [Stmt[i] -> phi[]] -> [Stmt[0] -> val1[]];
/// [Stmt[i] -> phi[]] -> [Stmt[i] -> val2[]] : i > 0 }
///
/// Only ValInsts in #ComputedPHIs are present in this map. Other values are
/// assumed to represent themselves. This is to avoid adding lots of identity
/// entries to this map.
///
/// { PHIValInst[] -> IncomingValInst[] }
isl::union_map NormalizeMap;
/// Cache for computePerPHI(const ScopArrayInfo *)
llvm::SmallDenseMap<llvm::PHINode *, isl::union_map> PerPHIMaps;
/// Prepare the object before computing the zones of @p S.
///
/// @param PassName Name of the pass using this analysis.
/// @param S The SCoP to process.
/// @param LI LoopInfo analysis used to determine synthesizable values.
ZoneAlgorithm(const char *PassName, Scop *S, llvm::LoopInfo *LI);
private:
/// Find the array elements that violate the zone analysis assumptions.
///
/// What violates our assumptions:
/// - A load after a write of the same location; we assume that all reads
/// occur before the writes.
/// - Two writes to the same location; we cannot model the order in which
/// these occur.
///
/// Scalar reads implicitly always occur before other accesses therefore never
/// violate the first condition. There is also at most one write to a scalar,
/// satisfying the second condition.
///
/// @param Stmt The statement to be analyzed.
/// @param[out] IncompatibleElts Receives the elements that are not
/// zone-analysis compatible.
/// @param[out] AllElts receives all encountered elements.
void collectIncompatibleElts(ScopStmt *Stmt, isl::union_set &IncompatibleElts,
isl::union_set &AllElts);
void addArrayReadAccess(MemoryAccess *MA);
/// Return the ValInst write by a (must-)write access. Returns the 'unknown'
/// ValInst if there is no single ValInst[] the array element written to will
/// have.
///
/// @return { ValInst[] }
isl::union_map getWrittenValue(MemoryAccess *MA, isl::map AccRel);
void addArrayWriteAccess(MemoryAccess *MA);
protected:
isl::union_set makeEmptyUnionSet() const;
isl::union_map makeEmptyUnionMap() const;
/// For each 'execution' of a PHINode, get the incoming block that was
/// executed before.
///
/// For each PHI instance we can directly determine which was the incoming
/// block, and hence derive which value the PHI has.
///
/// @param SAI The ScopArrayInfo representing the PHI's storage.
///
/// @return { DomainPHIRead[] -> DomainPHIWrite[] }
isl::union_map computePerPHI(const polly::ScopArrayInfo *SAI);
/// Find the array elements that can be used for zone analysis.
void collectCompatibleElts();
/// Get the schedule for @p Stmt.
///
/// The domain of the result is as narrow as possible.
isl::map getScatterFor(ScopStmt *Stmt) const;
/// Get the schedule of @p MA's parent statement.
isl::map getScatterFor(MemoryAccess *MA) const;
/// Get the schedule for the statement instances of @p Domain.
isl::union_map getScatterFor(isl::union_set Domain) const;
/// Get the schedule for the statement instances of @p Domain.
isl::map getScatterFor(isl::set Domain) const;
/// Get the domain of @p Stmt.
isl::set getDomainFor(ScopStmt *Stmt) const;
/// Get the domain @p MA's parent statement.
isl::set getDomainFor(MemoryAccess *MA) const;
/// Get the access relation of @p MA.
///
/// The domain of the result is as narrow as possible.
isl::map getAccessRelationFor(MemoryAccess *MA) const;
/// Get the reaching definition of a scalar defined in @p Stmt.
///
/// Note that this does not depend on the llvm::Instruction, only on the
/// statement it is defined in. Therefore the same computation can be reused.
///
/// @param Stmt The statement in which a scalar is defined.
///
/// @return { Scatter[] -> DomainDef[] }
isl::map getScalarReachingDefinition(ScopStmt *Stmt);
/// Get the reaching definition of a scalar defined in @p DefDomain.
///
/// @param DomainDef { DomainDef[] }
/// The write statements to get the reaching definition for.
///
/// @return { Scatter[] -> DomainDef[] }
isl::map getScalarReachingDefinition(isl::set DomainDef);
/// Create a statement-to-unknown value mapping.
///
/// @param Stmt The statement whose instances are mapped to unknown.
///
/// @return { Domain[] -> ValInst[] }
isl::map makeUnknownForDomain(ScopStmt *Stmt) const;
/// Create an isl_id that represents @p V.
isl::id makeValueId(llvm::Value *V);
/// Create the space for an llvm::Value that is available everywhere.
isl::space makeValueSpace(llvm::Value *V);
/// Create a set with the llvm::Value @p V which is available everywhere.
isl::set makeValueSet(llvm::Value *V);
/// Create a mapping from a statement instance to the instance of an
/// llvm::Value that can be used in there.
///
/// Although LLVM IR uses single static assignment, llvm::Values can have
/// different contents in loops, when they get redefined in the last
/// iteration. This function tries to get the statement instance of the
/// previous definition, relative to a user.
///
/// Example:
/// for (int i = 0; i < N; i += 1) {
/// DEF:
/// int v = A[i];
/// USE:
/// use(v);
/// }
///
/// The value instance used by statement instance USE[i] is DEF[i]. Hence,
/// makeValInst returns:
///
/// { USE[i] -> [DEF[i] -> v[]] : 0 <= i < N }
///
/// @param Val The value to get the instance of.
/// @param UserStmt The statement that uses @p Val. Can be nullptr.
/// @param Scope Loop the using instruction resides in.
/// @param IsCertain Pass true if the definition of @p Val is a
/// MUST_WRITE or false if the write is conditional.
///
/// @return { DomainUse[] -> ValInst[] }
isl::map makeValInst(llvm::Value *Val, ScopStmt *UserStmt, llvm::Loop *Scope,
bool IsCertain = true);
/// Create and normalize a ValInst.
///
/// @see makeValInst
/// @see normalizeValInst
/// @see #NormalizedPHI
isl::union_map makeNormalizedValInst(llvm::Value *Val, ScopStmt *UserStmt,
llvm::Loop *Scope,
bool IsCertain = true);
/// Return whether @p MA can be used for transformations (e.g. OpTree load
/// forwarding, DeLICM mapping).
bool isCompatibleAccess(MemoryAccess *MA);
/// Compute the different zones.
void computeCommon();
/// Compute the normalization map that replaces PHIs by their incoming
/// values.
///
/// @see #NormalizeMap
void computeNormalizedPHIs();
/// Print the current state of all MemoryAccesses to @p.
void printAccesses(llvm::raw_ostream &OS, int Indent = 0) const;
/// Is @p MA a PHI READ access that can be normalized?
///
/// @see #NormalizeMap
bool isNormalizable(MemoryAccess *MA);
/// @{
/// Determine whether the argument does not map to any computed PHI. Those
/// should have been replaced by their incoming values.
///
/// @see #NormalizedPHI
bool isNormalized(isl::map Map);
bool isNormalized(isl::union_map Map);
/// @}
public:
/// Return the SCoP this object is analyzing.
Scop *getScop() const { return S; }
/// A reaching definition zone is known to have the definition's written value
/// if the definition is a MUST_WRITE.
///
/// @return { [Element[] -> Zone[]] -> ValInst[] }
isl::union_map computeKnownFromMustWrites() const;
/// A reaching definition zone is known to be the same value as any load that
/// reads from that array element in that period.
///
/// @return { [Element[] -> Zone[]] -> ValInst[] }
isl::union_map computeKnownFromLoad() const;
/// Compute which value an array element stores at every instant.
///
/// @param FromWrite Use stores as source of information.
/// @param FromRead Use loads as source of information.
///
/// @return { [Element[] -> Zone[]] -> ValInst[] }
isl::union_map computeKnown(bool FromWrite, bool FromRead) const;
};
/// Create a domain-to-unknown value mapping.
///
/// Value instances that do not represent a specific value are represented by an
/// unnamed tuple of 0 dimensions. Its meaning depends on the context. It can
/// either mean a specific but unknown value which cannot be represented by
/// other means. It conflicts with itself because those two unknown ValInsts may
/// have different concrete values at runtime.
///
/// The other meaning is an arbitrary or wildcard value that can be chosen
/// freely, like LLVM's undef. If matched with an unknown ValInst, there is no
/// conflict.
///
/// @param Domain { Domain[] }
///
/// @return { Domain[] -> ValInst[] }
isl::union_map makeUnknownForDomain(isl::union_set Domain);
} // namespace polly
#endif /* POLLY_ZONEALGO_H */
|