forked from OSchip/llvm-project
[PM]: LoopAccessInfo simple refactoring
To make definition of mov ctors easier. Differential Revision: http://reviews.llvm.org/D21563 llvm-svn: 273506
This commit is contained in:
parent
38adadfe2a
commit
ce030acb4e
|
@ -520,13 +520,13 @@ public:
|
||||||
bool canVectorizeMemory() const { return CanVecMem; }
|
bool canVectorizeMemory() const { return CanVecMem; }
|
||||||
|
|
||||||
const RuntimePointerChecking *getRuntimePointerChecking() const {
|
const RuntimePointerChecking *getRuntimePointerChecking() const {
|
||||||
return &PtrRtChecking;
|
return PtrRtChecking.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Number of memchecks required to prove independence of otherwise
|
/// \brief Number of memchecks required to prove independence of otherwise
|
||||||
/// may-alias pointers.
|
/// may-alias pointers.
|
||||||
unsigned getNumRuntimePointerChecks() const {
|
unsigned getNumRuntimePointerChecks() const {
|
||||||
return PtrRtChecking.getNumberOfChecks();
|
return PtrRtChecking->getNumberOfChecks();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return true if the block BB needs to be predicated in order for the loop
|
/// Return true if the block BB needs to be predicated in order for the loop
|
||||||
|
@ -565,13 +565,13 @@ public:
|
||||||
|
|
||||||
/// \brief the Memory Dependence Checker which can determine the
|
/// \brief 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.
|
||||||
const MemoryDepChecker &getDepChecker() const { return DepChecker; }
|
const MemoryDepChecker &getDepChecker() const { return *DepChecker; }
|
||||||
|
|
||||||
/// \brief Return the list of instructions that use \p Ptr to read or write
|
/// \brief Return the list of instructions that use \p Ptr to read or write
|
||||||
/// memory.
|
/// memory.
|
||||||
SmallVector<Instruction *, 4> getInstructionsForAccess(Value *Ptr,
|
SmallVector<Instruction *, 4> getInstructionsForAccess(Value *Ptr,
|
||||||
bool isWrite) const {
|
bool isWrite) const {
|
||||||
return DepChecker.getInstructionsForAccess(Ptr, isWrite);
|
return DepChecker->getInstructionsForAccess(Ptr, isWrite);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief If an access has a symbolic strides, this maps the pointer value to
|
/// \brief If an access has a symbolic strides, this maps the pointer value to
|
||||||
|
@ -615,12 +615,12 @@ private:
|
||||||
void collectStridedAccess(Value *LoadOrStoreInst);
|
void collectStridedAccess(Value *LoadOrStoreInst);
|
||||||
|
|
||||||
/// 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
|
||||||
/// at runtime.
|
/// at runtime. Using std::unique_ptr to make using move ctor simpler.
|
||||||
RuntimePointerChecking PtrRtChecking;
|
std::unique_ptr<RuntimePointerChecking> PtrRtChecking;
|
||||||
|
|
||||||
/// \brief the Memory Dependence Checker which can determine the
|
/// \brief 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.
|
||||||
MemoryDepChecker DepChecker;
|
std::unique_ptr<MemoryDepChecker> DepChecker;
|
||||||
|
|
||||||
Loop *TheLoop;
|
Loop *TheLoop;
|
||||||
const DataLayout &DL;
|
const DataLayout &DL;
|
||||||
|
|
|
@ -1514,8 +1514,8 @@ void LoopAccessInfo::analyzeLoop() {
|
||||||
unsigned NumReads = 0;
|
unsigned NumReads = 0;
|
||||||
unsigned NumReadWrites = 0;
|
unsigned NumReadWrites = 0;
|
||||||
|
|
||||||
PtrRtChecking.Pointers.clear();
|
PtrRtChecking->Pointers.clear();
|
||||||
PtrRtChecking.Need = false;
|
PtrRtChecking->Need = false;
|
||||||
|
|
||||||
const bool IsAnnotatedParallel = TheLoop->isAnnotatedParallel();
|
const bool IsAnnotatedParallel = TheLoop->isAnnotatedParallel();
|
||||||
|
|
||||||
|
@ -1554,7 +1554,7 @@ void LoopAccessInfo::analyzeLoop() {
|
||||||
}
|
}
|
||||||
NumLoads++;
|
NumLoads++;
|
||||||
Loads.push_back(Ld);
|
Loads.push_back(Ld);
|
||||||
DepChecker.addAccess(Ld);
|
DepChecker->addAccess(Ld);
|
||||||
if (EnableMemAccessVersioning)
|
if (EnableMemAccessVersioning)
|
||||||
collectStridedAccess(Ld);
|
collectStridedAccess(Ld);
|
||||||
continue;
|
continue;
|
||||||
|
@ -1578,7 +1578,7 @@ void LoopAccessInfo::analyzeLoop() {
|
||||||
}
|
}
|
||||||
NumStores++;
|
NumStores++;
|
||||||
Stores.push_back(St);
|
Stores.push_back(St);
|
||||||
DepChecker.addAccess(St);
|
DepChecker->addAccess(St);
|
||||||
if (EnableMemAccessVersioning)
|
if (EnableMemAccessVersioning)
|
||||||
collectStridedAccess(St);
|
collectStridedAccess(St);
|
||||||
}
|
}
|
||||||
|
@ -1676,7 +1676,7 @@ void LoopAccessInfo::analyzeLoop() {
|
||||||
|
|
||||||
// Find pointers with computable bounds. We are going to use this information
|
// Find pointers with computable bounds. We are going to use this information
|
||||||
// to place a runtime bound check.
|
// to place a runtime bound check.
|
||||||
bool CanDoRTIfNeeded = Accesses.canCheckPtrAtRT(PtrRtChecking, PSE.getSE(),
|
bool CanDoRTIfNeeded = Accesses.canCheckPtrAtRT(*PtrRtChecking, PSE.getSE(),
|
||||||
TheLoop, SymbolicStrides);
|
TheLoop, SymbolicStrides);
|
||||||
if (!CanDoRTIfNeeded) {
|
if (!CanDoRTIfNeeded) {
|
||||||
emitAnalysis(LoopAccessReport() << "cannot identify array bounds");
|
emitAnalysis(LoopAccessReport() << "cannot identify array bounds");
|
||||||
|
@ -1691,21 +1691,21 @@ void LoopAccessInfo::analyzeLoop() {
|
||||||
CanVecMem = true;
|
CanVecMem = true;
|
||||||
if (Accesses.isDependencyCheckNeeded()) {
|
if (Accesses.isDependencyCheckNeeded()) {
|
||||||
DEBUG(dbgs() << "LAA: Checking memory dependencies\n");
|
DEBUG(dbgs() << "LAA: Checking memory dependencies\n");
|
||||||
CanVecMem = DepChecker.areDepsSafe(
|
CanVecMem = DepChecker->areDepsSafe(
|
||||||
DependentAccesses, Accesses.getDependenciesToCheck(), SymbolicStrides);
|
DependentAccesses, Accesses.getDependenciesToCheck(), SymbolicStrides);
|
||||||
MaxSafeDepDistBytes = DepChecker.getMaxSafeDepDistBytes();
|
MaxSafeDepDistBytes = DepChecker->getMaxSafeDepDistBytes();
|
||||||
|
|
||||||
if (!CanVecMem && DepChecker.shouldRetryWithRuntimeCheck()) {
|
if (!CanVecMem && DepChecker->shouldRetryWithRuntimeCheck()) {
|
||||||
DEBUG(dbgs() << "LAA: Retrying with memory checks\n");
|
DEBUG(dbgs() << "LAA: Retrying with memory checks\n");
|
||||||
|
|
||||||
// Clear the dependency checks. We assume they are not needed.
|
// Clear the dependency checks. We assume they are not needed.
|
||||||
Accesses.resetDepChecks(DepChecker);
|
Accesses.resetDepChecks(*DepChecker);
|
||||||
|
|
||||||
PtrRtChecking.reset();
|
PtrRtChecking->reset();
|
||||||
PtrRtChecking.Need = true;
|
PtrRtChecking->Need = true;
|
||||||
|
|
||||||
auto *SE = PSE.getSE();
|
auto *SE = PSE.getSE();
|
||||||
CanDoRTIfNeeded = Accesses.canCheckPtrAtRT(PtrRtChecking, SE, TheLoop,
|
CanDoRTIfNeeded = Accesses.canCheckPtrAtRT(*PtrRtChecking, SE, TheLoop,
|
||||||
SymbolicStrides, true);
|
SymbolicStrides, true);
|
||||||
|
|
||||||
// Check that we found the bounds for the pointer.
|
// Check that we found the bounds for the pointer.
|
||||||
|
@ -1723,7 +1723,7 @@ void LoopAccessInfo::analyzeLoop() {
|
||||||
|
|
||||||
if (CanVecMem)
|
if (CanVecMem)
|
||||||
DEBUG(dbgs() << "LAA: No unsafe dependent memory operations in loop. We"
|
DEBUG(dbgs() << "LAA: No unsafe dependent memory operations in loop. We"
|
||||||
<< (PtrRtChecking.Need ? "" : " don't")
|
<< (PtrRtChecking->Need ? "" : " don't")
|
||||||
<< " need runtime memory checks.\n");
|
<< " need runtime memory checks.\n");
|
||||||
else {
|
else {
|
||||||
emitAnalysis(
|
emitAnalysis(
|
||||||
|
@ -1835,7 +1835,7 @@ std::pair<Instruction *, Instruction *> LoopAccessInfo::addRuntimeChecks(
|
||||||
auto *SE = PSE.getSE();
|
auto *SE = PSE.getSE();
|
||||||
SCEVExpander Exp(*SE, DL, "induction");
|
SCEVExpander Exp(*SE, DL, "induction");
|
||||||
auto ExpandedChecks =
|
auto ExpandedChecks =
|
||||||
expandBounds(PointerChecks, TheLoop, Loc, SE, Exp, PtrRtChecking);
|
expandBounds(PointerChecks, TheLoop, Loc, SE, Exp, *PtrRtChecking);
|
||||||
|
|
||||||
LLVMContext &Ctx = Loc->getContext();
|
LLVMContext &Ctx = Loc->getContext();
|
||||||
Instruction *FirstInst = nullptr;
|
Instruction *FirstInst = nullptr;
|
||||||
|
@ -1891,10 +1891,10 @@ std::pair<Instruction *, Instruction *> LoopAccessInfo::addRuntimeChecks(
|
||||||
|
|
||||||
std::pair<Instruction *, Instruction *>
|
std::pair<Instruction *, Instruction *>
|
||||||
LoopAccessInfo::addRuntimeChecks(Instruction *Loc) const {
|
LoopAccessInfo::addRuntimeChecks(Instruction *Loc) const {
|
||||||
if (!PtrRtChecking.Need)
|
if (!PtrRtChecking->Need)
|
||||||
return std::make_pair(nullptr, nullptr);
|
return std::make_pair(nullptr, nullptr);
|
||||||
|
|
||||||
return addRuntimeChecks(Loc, PtrRtChecking.getChecks());
|
return addRuntimeChecks(Loc, PtrRtChecking->getChecks());
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoopAccessInfo::collectStridedAccess(Value *MemAccess) {
|
void LoopAccessInfo::collectStridedAccess(Value *MemAccess) {
|
||||||
|
@ -1920,8 +1920,10 @@ LoopAccessInfo::LoopAccessInfo(Loop *L, ScalarEvolution *SE,
|
||||||
const DataLayout &DL,
|
const DataLayout &DL,
|
||||||
const TargetLibraryInfo *TLI, AliasAnalysis *AA,
|
const TargetLibraryInfo *TLI, AliasAnalysis *AA,
|
||||||
DominatorTree *DT, LoopInfo *LI)
|
DominatorTree *DT, LoopInfo *LI)
|
||||||
: PSE(*SE, *L), PtrRtChecking(SE), DepChecker(PSE, L), TheLoop(L), DL(DL),
|
: PSE(*SE, *L),
|
||||||
TLI(TLI), AA(AA), DT(DT), LI(LI), NumLoads(0), NumStores(0),
|
PtrRtChecking(llvm::make_unique<RuntimePointerChecking>(SE)),
|
||||||
|
DepChecker(llvm::make_unique<MemoryDepChecker>(PSE, L)), TheLoop(L),
|
||||||
|
DL(DL), TLI(TLI), AA(AA), DT(DT), LI(LI), NumLoads(0), NumStores(0),
|
||||||
MaxSafeDepDistBytes(-1U), CanVecMem(false),
|
MaxSafeDepDistBytes(-1U), CanVecMem(false),
|
||||||
StoreToLoopInvariantAddress(false) {
|
StoreToLoopInvariantAddress(false) {
|
||||||
if (canAnalyzeLoop())
|
if (canAnalyzeLoop())
|
||||||
|
@ -1934,7 +1936,7 @@ void LoopAccessInfo::print(raw_ostream &OS, unsigned Depth) const {
|
||||||
if (MaxSafeDepDistBytes != -1U)
|
if (MaxSafeDepDistBytes != -1U)
|
||||||
OS << " with a maximum dependence distance of " << MaxSafeDepDistBytes
|
OS << " with a maximum dependence distance of " << MaxSafeDepDistBytes
|
||||||
<< " bytes";
|
<< " bytes";
|
||||||
if (PtrRtChecking.Need)
|
if (PtrRtChecking->Need)
|
||||||
OS << " with run-time checks";
|
OS << " with run-time checks";
|
||||||
OS << "\n";
|
OS << "\n";
|
||||||
}
|
}
|
||||||
|
@ -1942,17 +1944,17 @@ void LoopAccessInfo::print(raw_ostream &OS, unsigned Depth) const {
|
||||||
if (Report)
|
if (Report)
|
||||||
OS.indent(Depth) << "Report: " << Report->str() << "\n";
|
OS.indent(Depth) << "Report: " << Report->str() << "\n";
|
||||||
|
|
||||||
if (auto *Dependences = DepChecker.getDependences()) {
|
if (auto *Dependences = DepChecker->getDependences()) {
|
||||||
OS.indent(Depth) << "Dependences:\n";
|
OS.indent(Depth) << "Dependences:\n";
|
||||||
for (auto &Dep : *Dependences) {
|
for (auto &Dep : *Dependences) {
|
||||||
Dep.print(OS, Depth + 2, DepChecker.getMemoryInstructions());
|
Dep.print(OS, Depth + 2, DepChecker->getMemoryInstructions());
|
||||||
OS << "\n";
|
OS << "\n";
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
OS.indent(Depth) << "Too many dependences, not recorded\n";
|
OS.indent(Depth) << "Too many dependences, not recorded\n";
|
||||||
|
|
||||||
// List the pair of accesses need run-time checks to prove independence.
|
// List the pair of accesses need run-time checks to prove independence.
|
||||||
PtrRtChecking.print(OS, Depth);
|
PtrRtChecking->print(OS, Depth);
|
||||||
OS << "\n";
|
OS << "\n";
|
||||||
|
|
||||||
OS.indent(Depth) << "Store to invariant address was "
|
OS.indent(Depth) << "Store to invariant address was "
|
||||||
|
|
Loading…
Reference in New Issue