forked from OSchip/llvm-project
[PM] Refector LoopAccessInfo analysis code
This is the preparation patch to port the analysis to new PM Differential Revision: http://reviews.llvm.org/D20560 llvm-svn: 272194
This commit is contained in:
parent
10a2c38d83
commit
572135f717
|
@ -670,10 +670,48 @@ int getPtrStride(PredicatedScalarEvolution &PSE, Value *Ptr, const Loop *Lp,
|
|||
bool Assume = false);
|
||||
|
||||
/// \brief Returns true if the memory operations \p A and \p B are consecutive.
|
||||
/// This is a simple API that does not depend on the analysis pass.
|
||||
/// This is a simple API that does not depend on the analysis pass.
|
||||
bool isConsecutiveAccess(Value *A, Value *B, const DataLayout &DL,
|
||||
ScalarEvolution &SE, bool CheckType = true);
|
||||
|
||||
/// \brief This class holds the result of LoopAccessAnalysis pass.
|
||||
class LoopAccessAnalysisResult {
|
||||
public:
|
||||
void setDepAnalyses(AliasAnalysis *AA, DominatorTree *DT, LoopInfo *LI,
|
||||
ScalarEvolution *SCEV, TargetLibraryInfo *TLI) {
|
||||
this->AA = AA;
|
||||
this->DT = DT;
|
||||
this->LI = LI;
|
||||
this->SCEV = SCEV;
|
||||
this->TLI = TLI;
|
||||
}
|
||||
/// \brief Query the result of the loop access information for the loop \p L.
|
||||
///
|
||||
/// If the client speculates (and then issues run-time checks) for the values
|
||||
/// of symbolic strides, \p Strides provides the mapping (see
|
||||
/// replaceSymbolicStrideSCEV). If there is no cached result available run
|
||||
/// the analysis.
|
||||
const LoopAccessInfo &getInfo(Loop *L, const ValueToValueMap &Strides);
|
||||
|
||||
void print(raw_ostream &OS, const Module *M = nullptr) const;
|
||||
|
||||
/// \brief Invalidate the cache when the pass is freed.
|
||||
void releaseMemory() {
|
||||
LoopAccessInfoMap.clear();
|
||||
}
|
||||
|
||||
private:
|
||||
/// \brief LoopAccessInfo is created on demand. This map caches
|
||||
/// the computed results.
|
||||
DenseMap<Loop *, std::unique_ptr<LoopAccessInfo>> LoopAccessInfoMap;
|
||||
|
||||
AliasAnalysis *AA = nullptr;
|
||||
DominatorTree *DT = nullptr;
|
||||
LoopInfo *LI = nullptr;
|
||||
ScalarEvolution *SCEV = nullptr;
|
||||
TargetLibraryInfo *TLI = nullptr;
|
||||
};
|
||||
|
||||
/// \brief This analysis provides dependence information for the memory accesses
|
||||
/// of a loop.
|
||||
///
|
||||
|
@ -685,7 +723,7 @@ class LoopAccessAnalysis : public FunctionPass {
|
|||
public:
|
||||
static char ID;
|
||||
|
||||
LoopAccessAnalysis() : FunctionPass(ID) {
|
||||
LoopAccessAnalysis() : FunctionPass(ID), LAAR() {
|
||||
initializeLoopAccessAnalysisPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
|
||||
|
@ -693,32 +731,20 @@ public:
|
|||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override;
|
||||
|
||||
/// \brief Query the result of the loop access information for the loop \p L.
|
||||
///
|
||||
/// If the client speculates (and then issues run-time checks) for the values
|
||||
/// of symbolic strides, \p Strides provides the mapping (see
|
||||
/// replaceSymbolicStrideSCEV). If there is no cached result available run
|
||||
/// the analysis.
|
||||
const LoopAccessInfo &getInfo(Loop *L, const ValueToValueMap &Strides);
|
||||
LoopAccessAnalysisResult &getResult() { return LAAR; }
|
||||
|
||||
void releaseMemory() override {
|
||||
// Invalidate the cache when the pass is freed.
|
||||
LoopAccessInfoMap.clear();
|
||||
LAAR.releaseMemory();
|
||||
}
|
||||
|
||||
/// \brief Print the result of the analysis when invoked with -analyze.
|
||||
void print(raw_ostream &OS, const Module *M = nullptr) const override;
|
||||
void print(raw_ostream &OS, const Module *M = nullptr) const override {
|
||||
LAAR.print(OS, M);
|
||||
}
|
||||
|
||||
private:
|
||||
/// \brief The cache.
|
||||
DenseMap<Loop *, std::unique_ptr<LoopAccessInfo>> LoopAccessInfoMap;
|
||||
|
||||
// The used analysis passes.
|
||||
ScalarEvolution *SE;
|
||||
const TargetLibraryInfo *TLI;
|
||||
AliasAnalysis *AA;
|
||||
DominatorTree *DT;
|
||||
LoopInfo *LI;
|
||||
LoopAccessAnalysisResult LAAR;
|
||||
};
|
||||
|
||||
inline Instruction *MemoryDepChecker::Dependence::getSource(
|
||||
|
|
|
@ -1932,7 +1932,7 @@ void LoopAccessInfo::print(raw_ostream &OS, unsigned Depth) const {
|
|||
}
|
||||
|
||||
const LoopAccessInfo &
|
||||
LoopAccessAnalysis::getInfo(Loop *L, const ValueToValueMap &Strides) {
|
||||
LoopAccessAnalysisResult::getInfo(Loop *L, const ValueToValueMap &Strides) {
|
||||
auto &LAI = LoopAccessInfoMap[L];
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
@ -1942,8 +1942,8 @@ LoopAccessAnalysis::getInfo(Loop *L, const ValueToValueMap &Strides) {
|
|||
|
||||
if (!LAI) {
|
||||
const DataLayout &DL = L->getHeader()->getModule()->getDataLayout();
|
||||
LAI =
|
||||
llvm::make_unique<LoopAccessInfo>(L, SE, DL, TLI, AA, DT, LI, Strides);
|
||||
LAI = llvm::make_unique<LoopAccessInfo>(L, SCEV, DL, TLI, AA, DT, LI,
|
||||
Strides);
|
||||
#ifndef NDEBUG
|
||||
LAI->NumSymbolicStrides = Strides.size();
|
||||
#endif
|
||||
|
@ -1951,26 +1951,25 @@ LoopAccessAnalysis::getInfo(Loop *L, const ValueToValueMap &Strides) {
|
|||
return *LAI.get();
|
||||
}
|
||||
|
||||
void LoopAccessAnalysis::print(raw_ostream &OS, const Module *M) const {
|
||||
LoopAccessAnalysis &LAA = *const_cast<LoopAccessAnalysis *>(this);
|
||||
|
||||
void LoopAccessAnalysisResult::print(raw_ostream &OS, const Module *M) const {
|
||||
ValueToValueMap NoSymbolicStrides;
|
||||
|
||||
for (Loop *TopLevelLoop : *LI)
|
||||
for (Loop *L : depth_first(TopLevelLoop)) {
|
||||
OS.indent(2) << L->getHeader()->getName() << ":\n";
|
||||
auto &LAI = LAA.getInfo(L, NoSymbolicStrides);
|
||||
auto &LAI = const_cast<LoopAccessAnalysisResult *>(this)->getInfo(
|
||||
L, NoSymbolicStrides);
|
||||
LAI.print(OS, 4);
|
||||
}
|
||||
}
|
||||
|
||||
bool LoopAccessAnalysis::runOnFunction(Function &F) {
|
||||
SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
|
||||
auto *TLIP = getAnalysisIfAvailable<TargetLibraryInfoWrapperPass>();
|
||||
TLI = TLIP ? &TLIP->getTLI() : nullptr;
|
||||
AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
|
||||
DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
|
||||
LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
|
||||
LAAR.setDepAnalyses(&getAnalysis<AAResultsWrapperPass>().getAAResults(),
|
||||
&getAnalysis<DominatorTreeWrapperPass>().getDomTree(),
|
||||
&getAnalysis<LoopInfoWrapperPass>().getLoopInfo(),
|
||||
&getAnalysis<ScalarEvolutionWrapperPass>().getSE(),
|
||||
TLIP ? &TLIP->getTLI() : nullptr);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -608,7 +608,7 @@ public:
|
|||
return fail("multiple exit blocks");
|
||||
|
||||
// LAA will check that we only have a single exiting block.
|
||||
LAI = &LAA->getInfo(L, ValueToValueMap());
|
||||
LAI = &LAA->getResult().getInfo(L, ValueToValueMap());
|
||||
|
||||
// Currently, we only distribute to isolate the part of the loop with
|
||||
// dependence cycles to enable partial vectorization.
|
||||
|
|
|
@ -552,7 +552,7 @@ public:
|
|||
// Now walk the identified inner loops.
|
||||
bool Changed = false;
|
||||
for (Loop *L : Worklist) {
|
||||
const LoopAccessInfo &LAI = LAA->getInfo(L, ValueToValueMap());
|
||||
const LoopAccessInfo &LAI = LAA->getResult().getInfo(L, ValueToValueMap());
|
||||
// The actual work is performed by LoadEliminationForLoop.
|
||||
LoadEliminationForLoop LEL(L, LI, LAI, DT);
|
||||
Changed |= LEL.processLoop();
|
||||
|
|
|
@ -411,7 +411,7 @@ bool LoopVersioningLICM::legalLoopInstructions() {
|
|||
return false;
|
||||
}
|
||||
// Get LoopAccessInfo from current loop.
|
||||
LAI = &LAA->getInfo(CurLoop, Strides);
|
||||
LAI = &LAA->getResult().getInfo(CurLoop, Strides);
|
||||
// Check LoopAccessInfo for need of runtime check.
|
||||
if (LAI->getRuntimePointerChecking()->getChecks().empty()) {
|
||||
DEBUG(dbgs() << " LAA: Runtime check not found !!\n");
|
||||
|
|
|
@ -268,7 +268,7 @@ public:
|
|||
// Now walk the identified inner loops.
|
||||
bool Changed = false;
|
||||
for (Loop *L : Worklist) {
|
||||
const LoopAccessInfo &LAI = LAA->getInfo(L, ValueToValueMap());
|
||||
const LoopAccessInfo &LAI = LAA->getResult().getInfo(L, ValueToValueMap());
|
||||
if (LAI.getNumRuntimePointerChecks() ||
|
||||
!LAI.PSE.getUnionPredicate().isAlwaysTrue()) {
|
||||
LoopVersioning LVer(LAI, L, LI, DT, SE);
|
||||
|
|
|
@ -4931,7 +4931,7 @@ void LoopVectorizationLegality::collectLoopUniforms() {
|
|||
}
|
||||
|
||||
bool LoopVectorizationLegality::canVectorizeMemory() {
|
||||
LAI = &LAA->getInfo(TheLoop, Strides);
|
||||
LAI = &LAA->getResult().getInfo(TheLoop, Strides);
|
||||
auto &OptionalReport = LAI->getReport();
|
||||
if (OptionalReport)
|
||||
emitAnalysis(VectorizationReport(*OptionalReport));
|
||||
|
|
Loading…
Reference in New Issue