[ScopBuilder] Move buildInvariantEquivalenceClasses function from ScopInfo. NFC.

Refactor Scop and ScopBuilder class. Move
buildInvariantEquivalenceClasses function from Scop class to ScopBuilder
class.

Patch by: Dominik Adamski <adamski.dominik@gmail.com>

Differential Revision: https://reviews.llvm.org/D62351

llvm-svn: 361902
This commit is contained in:
Michael Kruse
2019-05-28 23:47:55 +00:00
parent a6f57ad2c9
commit 26212da555
4 changed files with 48 additions and 36 deletions

View File

@@ -120,6 +120,20 @@ class ScopBuilder {
void buildScop(Region &R, AssumptionCache &AC,
OptimizationRemarkEmitter &ORE);
/// Create equivalence classes for required invariant accesses.
///
/// These classes will consolidate multiple required invariant loads from the
/// same address in order to keep the number of dimensions in the SCoP
/// description small. For each such class equivalence class only one
/// representing element, hence one required invariant load, will be chosen
/// and modeled as parameter. The method
/// Scop::getRepresentingInvariantLoadSCEV() will replace each element from an
/// equivalence class with the representing element that is modeled. As a
/// consequence Scop::getIdForParam() will only return an id for the
/// representing element of each equivalence class, thus for each required
/// invariant location.
void buildInvariantEquivalenceClasses();
/// Try to build a multi-dimensional fixed sized MemoryAccess from the
/// Load/Store instruction.
///

View File

@@ -2031,20 +2031,6 @@ private:
/// Check if the base ptr of @p MA is in the SCoP but not hoistable.
bool hasNonHoistableBasePtrInScop(MemoryAccess *MA, isl::union_map Writes);
/// Create equivalence classes for required invariant accesses.
///
/// These classes will consolidate multiple required invariant loads from the
/// same address in order to keep the number of dimensions in the SCoP
/// description small. For each such class equivalence class only one
/// representing element, hence one required invariant load, will be chosen
/// and modeled as parameter. The method
/// Scop::getRepresentingInvariantLoadSCEV() will replace each element from an
/// equivalence class with the representing element that is modeled. As a
/// consequence Scop::getIdForParam() will only return an id for the
/// representing element of each equivalence class, thus for each required
/// invariant location.
void buildInvariantEquivalenceClasses();
/// Return the context under which the access cannot be hoisted.
///
/// @param Access The access to check.
@@ -2386,6 +2372,18 @@ public:
/// Add metadata for @p Access.
void addAccessData(MemoryAccess *Access);
/// Add new invariant access equivalence class
void
addInvariantEquivClass(const InvariantEquivClassTy &InvariantEquivClass) {
InvariantEquivClasses.emplace_back(InvariantEquivClass);
}
/// Add mapping from invariant loads to the representing invariant load of
/// their equivalence class.
void addInvariantLoadMapping(const Value *LoadInst, Value *ClassRep) {
InvEquivClassVMap[LoadInst] = ClassRep;
}
/// Remove the metadata stored for @p Access.
void removeAccessData(MemoryAccess *Access);

View File

@@ -105,6 +105,26 @@ static cl::opt<GranularityChoice> StmtGranularity(
"Store-level granularity")),
cl::init(GranularityChoice::ScalarIndependence), cl::cat(PollyCategory));
void ScopBuilder::buildInvariantEquivalenceClasses() {
DenseMap<std::pair<const SCEV *, Type *>, LoadInst *> EquivClasses;
const InvariantLoadsSetTy &RIL = scop->getRequiredInvariantLoads();
for (LoadInst *LInst : RIL) {
const SCEV *PointerSCEV = SE.getSCEV(LInst->getPointerOperand());
Type *Ty = LInst->getType();
LoadInst *&ClassRep = EquivClasses[std::make_pair(PointerSCEV, Ty)];
if (ClassRep) {
scop->addInvariantLoadMapping(LInst, ClassRep);
continue;
}
ClassRep = LInst;
scop->addInvariantEquivClass(
InvariantEquivClassTy{PointerSCEV, MemoryAccessList(), nullptr, Ty});
}
}
void ScopBuilder::buildPHIAccesses(ScopStmt *PHIStmt, PHINode *PHI,
Region *NonAffineSubRegion,
bool IsExitBlock) {
@@ -1492,7 +1512,7 @@ void ScopBuilder::buildScop(Region &R, AssumptionCache &AC,
BP, BP->getType(), false, {AF}, {nullptr}, GlobalRead);
}
scop->buildInvariantEquivalenceClasses();
buildInvariantEquivalenceClasses();
/// A map from basic blocks to their invalid domains.
DenseMap<BasicBlock *, isl::set> InvalidDomainMap;

View File

@@ -2102,26 +2102,6 @@ void Scop::addUserContext() {
Context = Context.intersect(UserContext);
}
void Scop::buildInvariantEquivalenceClasses() {
DenseMap<std::pair<const SCEV *, Type *>, LoadInst *> EquivClasses;
const InvariantLoadsSetTy &RIL = getRequiredInvariantLoads();
for (LoadInst *LInst : RIL) {
const SCEV *PointerSCEV = SE->getSCEV(LInst->getPointerOperand());
Type *Ty = LInst->getType();
LoadInst *&ClassRep = EquivClasses[std::make_pair(PointerSCEV, Ty)];
if (ClassRep) {
InvEquivClassVMap[LInst] = ClassRep;
continue;
}
ClassRep = LInst;
InvariantEquivClasses.emplace_back(
InvariantEquivClassTy{PointerSCEV, MemoryAccessList(), nullptr, Ty});
}
}
void Scop::buildContext() {
isl::space Space = isl::space::params_alloc(getIslCtx(), 0);
Context = isl::set::universe(Space);
@@ -3699,7 +3679,7 @@ void Scop::addInvariantLoads(ScopStmt &Stmt, InvariantAccessesTy &InvMAs) {
// If we did not consolidate MA, thus did not find an equivalence class
// for it, we create a new one.
InvariantEquivClasses.emplace_back(
addInvariantEquivClass(
InvariantEquivClassTy{PointerSCEV, MemoryAccessList{MA}, MACtx, Ty});
}
}