Changeset View
Standalone View
llvm/include/llvm/Analysis/LoopAccessAnalysis.h
Show All 10 Lines | |||||
// | // | ||||
//===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||
#ifndef LLVM_ANALYSIS_LOOPACCESSANALYSIS_H | #ifndef LLVM_ANALYSIS_LOOPACCESSANALYSIS_H | ||||
#define LLVM_ANALYSIS_LOOPACCESSANALYSIS_H | #define LLVM_ANALYSIS_LOOPACCESSANALYSIS_H | ||||
#include "llvm/ADT/EquivalenceClasses.h" | #include "llvm/ADT/EquivalenceClasses.h" | ||||
#include "llvm/Analysis/LoopAnalysisManager.h" | #include "llvm/Analysis/LoopAnalysisManager.h" | ||||
#include "llvm/Analysis/OptimizationRemarkEmitter.h" | |||||
fhahn: This change is unnecessary, keep the include in the .cpp | |||||
#include "llvm/Analysis/ScalarEvolutionExpressions.h" | #include "llvm/Analysis/ScalarEvolutionExpressions.h" | ||||
#include "llvm/IR/DiagnosticInfo.h" | #include "llvm/IR/DiagnosticInfo.h" | ||||
#include "llvm/Pass.h" | #include "llvm/Pass.h" | ||||
namespace llvm { | namespace llvm { | ||||
class AAResults; | class AAResults; | ||||
class DataLayout; | class DataLayout; | ||||
class Loop; | class Loop; | ||||
class LoopAccessInfo; | class LoopAccessInfo; | ||||
class OptimizationRemarkEmitter; | |||||
class raw_ostream; | class raw_ostream; | ||||
class SCEV; | class SCEV; | ||||
class SCEVUnionPredicate; | class SCEVUnionPredicate; | ||||
class Value; | class Value; | ||||
/// Collection of parameters shared beetween the Loop Vectorizer and the | /// Collection of parameters shared beetween the Loop Vectorizer and the | ||||
/// Loop Access Analysis. | /// Loop Access Analysis. | ||||
struct VectorizerParams { | struct VectorizerParams { | ||||
▲ Show 20 Lines • Show All 205 Lines • ▼ Show 20 Lines | DenseMap<Instruction *, unsigned> generateInstructionOrderMap() const { | ||||
return OrderMap; | return OrderMap; | ||||
} | } | ||||
/// Find the set of instructions that read or write via \p Ptr. | /// Find the set of instructions that read or write via \p Ptr. | ||||
SmallVector<Instruction *, 4> getInstructionsForAccess(Value *Ptr, | SmallVector<Instruction *, 4> getInstructionsForAccess(Value *Ptr, | ||||
bool isWrite) const; | bool isWrite) const; | ||||
private: | private: | ||||
Not Done ReplyInline ActionsThere's no need to return a SmallVector with the length encoded, the callers should not care about that. You can use ArrayRef if the callers do not add to the vector or SmalLVectorImpl if they need to add elements. fhahn: There's no need to return a SmallVector with the length encoded, the callers should not care… | |||||
Currently the code uses "auto" when accessing the. value returned by this getter regardless, I've changed it to use SmallVector<T> instead if that's ok. malharJ: Currently the code uses "auto" when accessing the. value returned by this getter
so there isn't… | |||||
If there is no need to modify the array returned by getUnsafeDependences (which there isn't, because the returned value is const), ArrayRef seems the better class to use, because it has all sorts of convenient utilities and is similarly just a (immutable) reference to the array. sdesmalen: If there is no need to modify the array returned by getUnsafeDependences (which there isn't… | |||||
/// A wrapper around ScalarEvolution, used to add runtime SCEV checks, and | /// A wrapper around ScalarEvolution, used to add runtime SCEV checks, and | ||||
/// applies dynamic knowledge to simplify SCEV expressions and convert them | /// applies dynamic knowledge to simplify SCEV expressions and convert them | ||||
/// to a more usable form. We need this in case assumptions about SCEV | /// to a more usable form. We need this in case assumptions about SCEV | ||||
/// expressions need to be made in order to avoid unknown dependences. For | /// expressions need to be made in order to avoid unknown dependences. For | ||||
/// example we might assume a unit stride for a pointer in order to prove | /// example we might assume a unit stride for a pointer in order to prove | ||||
/// that a memory access is strided and doesn't wrap. | /// that a memory access is strided and doesn't wrap. | ||||
PredicatedScalarEvolution &PSE; | PredicatedScalarEvolution &PSE; | ||||
const Loop *InnermostLoop; | const Loop *InnermostLoop; | ||||
Show All 30 Lines | private: | ||||
//// Dependences is invalid. | //// Dependences is invalid. | ||||
bool RecordDependences; | bool RecordDependences; | ||||
/// Memory dependences collected during the analysis. Only valid if | /// Memory dependences collected during the analysis. Only valid if | ||||
/// RecordDependences is true. | /// RecordDependences is true. | ||||
SmallVector<Dependence, 8> Dependences; | SmallVector<Dependence, 8> Dependences; | ||||
/// Check whether there is a plausible dependence between the two | /// Check whether there is a plausible dependence between the two | ||||
/// accesses. | /// accesses. | ||||
Seems you only wanted one of these 2 words? alban.bridonneau: Seems you only wanted one of these 2 words? | |||||
/// | /// | ||||
Does this need to be a shared_ptr? If you want to encode the fact that it may not be set, using Optional may be a better choice. Or you could initialize it to NoDep in case there is no unsafe dependence. fhahn: Does this need to be a `shared_ptr`? If you want to encode the fact that it may not be set… | |||||
I've removed it now based on review comment by sdesmalen, so this is no longer an issue. malharJ: I've removed it now based on review comment by sdesmalen, so this is no longer an issue. | |||||
/// Access \p A must happen before \p B in program order. The two indices | /// Access \p A must happen before \p B in program order. The two indices | ||||
/// identify the index into the program order map. | /// identify the index into the program order map. | ||||
/// | /// | ||||
/// This function checks whether there is a plausible dependence (or the | /// This function checks whether there is a plausible dependence (or the | ||||
/// absence of such can't be proved) between the two accesses. If there is a | /// absence of such can't be proved) between the two accesses. If there is a | ||||
/// plausible dependence but the dependence distance is bigger than one | /// plausible dependence but the dependence distance is bigger than one | ||||
/// element access it records this distance in \p MaxSafeDepDistBytes (if this | /// element access it records this distance in \p MaxSafeDepDistBytes (if this | ||||
/// distance is smaller than any other distance encountered so far). | /// distance is smaller than any other distance encountered so far). | ||||
▲ Show 20 Lines • Show All 209 Lines • ▼ Show 20 Lines | public: | ||||
LoopAccessInfo(Loop *L, ScalarEvolution *SE, const TargetLibraryInfo *TLI, | LoopAccessInfo(Loop *L, ScalarEvolution *SE, const TargetLibraryInfo *TLI, | ||||
AAResults *AA, DominatorTree *DT, LoopInfo *LI); | AAResults *AA, DominatorTree *DT, LoopInfo *LI); | ||||
/// Return true we can analyze the memory accesses in the loop and there are | /// Return true we can analyze the memory accesses in the loop and there are | ||||
/// no memory dependence cycles. | /// no memory dependence cycles. | ||||
bool canVectorizeMemory() const { return CanVecMem; } | bool canVectorizeMemory() const { return CanVecMem; } | ||||
/// Return true if there is a convergent operation in the loop. There may | /// Return true if there is a convergent operation in the loop. There may | ||||
/// still be reported runtime pointer checks that would be required, but it is | /// still be reported runtime pointer checks that would be required, but it is | ||||
Nit: Missing a slash alban.bridonneau: Nit: Missing a slash | |||||
/// not legal to insert them. | /// not legal to insert them. | ||||
bool hasConvergentOp() const { return HasConvergentOp; } | bool hasConvergentOp() const { return HasConvergentOp; } | ||||
const RuntimePointerChecking *getRuntimePointerChecking() const { | const RuntimePointerChecking *getRuntimePointerChecking() const { | ||||
return PtrRtChecking.get(); | return PtrRtChecking.get(); | ||||
} | } | ||||
/// Number of memchecks required to prove independence of otherwise | /// Number of memchecks required to prove independence of otherwise | ||||
▲ Show 20 Lines • Show All 72 Lines • ▼ Show 20 Lines | private: | ||||
/// Collect memory access with loop invariant strides. | /// Collect memory access with loop invariant strides. | ||||
/// | /// | ||||
/// Looks for accesses like "a[i * StrideA]" where "StrideA" is loop | /// Looks for accesses like "a[i * StrideA]" where "StrideA" is loop | ||||
/// invariant. | /// invariant. | ||||
void collectStridedAccess(Value *LoadOrStoreInst); | void collectStridedAccess(Value *LoadOrStoreInst); | ||||
std::unique_ptr<PredicatedScalarEvolution> PSE; | std::unique_ptr<PredicatedScalarEvolution> PSE; | ||||
/// We need to check that all of the pointers in this list are disjoint | /// We need to check that all of the pointers in this list are disjoint | ||||
This seems unused? sdesmalen: This seems unused? | |||||
thanks for pointing it out. Removed it. malharJ: thanks for pointing it out. Removed it. | |||||
/// at runtime. Using std::unique_ptr to make using move ctor simpler. | /// at runtime. Using std::unique_ptr to make using move ctor simpler. | ||||
std::unique_ptr<RuntimePointerChecking> PtrRtChecking; | std::unique_ptr<RuntimePointerChecking> PtrRtChecking; | ||||
/// the Memory Dependence Checker which can determine the | /// the Memory Dependence Checker which can determine the | ||||
/// loop-independent and loop-carried dependences between memory accesses. | /// loop-independent and loop-carried dependences between memory accesses. | ||||
std::unique_ptr<MemoryDepChecker> DepChecker; | std::unique_ptr<MemoryDepChecker> DepChecker; | ||||
Loop *TheLoop; | Loop *TheLoop; | ||||
▲ Show 20 Lines • Show All 157 Lines • Show Last 20 Lines |
This change is unnecessary, keep the include in the .cpp