forked from OSchip/llvm-project
Expose the detection context to ScopDetection users
ScopDetection users are interested in the detection context and access these via different get-methods. However, not all information was exposed though the number of maps to hold it was increasing steadily. With this change only the detection contexts the rejection log and the ValidRegions set are mapped. The former is needed, the second could be integrated in the first and the ValidRegions set is only needed for the deterministic order of the regions. llvm-svn: 249614
This commit is contained in:
parent
7d0ea14cb0
commit
c06b7d67cd
|
@ -121,35 +121,14 @@ class ScopDetection : public FunctionPass {
|
|||
public:
|
||||
typedef SetVector<const Region *> RegionSet;
|
||||
|
||||
// Remember the valid regions
|
||||
RegionSet ValidRegions;
|
||||
|
||||
/// @brief Set of loops (used to remember loops in non-affine subregions).
|
||||
using BoxedLoopsSetTy = SetVector<const Loop *>;
|
||||
|
||||
private:
|
||||
//===--------------------------------------------------------------------===//
|
||||
ScopDetection(const ScopDetection &) = delete;
|
||||
const ScopDetection &operator=(const ScopDetection &) = delete;
|
||||
|
||||
/// @brief Analysis passes used.
|
||||
//@{
|
||||
const DominatorTree *DT;
|
||||
ScalarEvolution *SE;
|
||||
LoopInfo *LI;
|
||||
RegionInfo *RI;
|
||||
AliasAnalysis *AA;
|
||||
//@}
|
||||
|
||||
/// @brief Set to remember non-affine branches in regions.
|
||||
using NonAffineSubRegionSetTy = RegionSet;
|
||||
using NonAffineSubRegionMapTy =
|
||||
DenseMap<const Region *, NonAffineSubRegionSetTy>;
|
||||
NonAffineSubRegionMapTy NonAffineSubRegionMap;
|
||||
|
||||
/// @brief Map to remeber loops in non-affine regions.
|
||||
using BoxedLoopsMapTy = DenseMap<const Region *, BoxedLoopsSetTy>;
|
||||
BoxedLoopsMapTy BoxedLoopsMap;
|
||||
|
||||
/// @brief Map to remember loads that are required to be invariant.
|
||||
DenseMap<const Region *, InvariantLoadsSetTy> RequiredInvariantLoadsMap;
|
||||
|
||||
/// @brief Context variables for SCoP detection.
|
||||
struct DetectionContext {
|
||||
|
@ -178,24 +157,51 @@ private:
|
|||
bool hasStores;
|
||||
|
||||
/// @brief The set of non-affine subregions in the region we analyze.
|
||||
NonAffineSubRegionSetTy &NonAffineSubRegionSet;
|
||||
NonAffineSubRegionSetTy NonAffineSubRegionSet;
|
||||
|
||||
/// @brief The set of loops contained in non-affine regions.
|
||||
BoxedLoopsSetTy &BoxedLoopsSet;
|
||||
BoxedLoopsSetTy BoxedLoopsSet;
|
||||
|
||||
/// @brief Loads that need to be invariant during execution.
|
||||
InvariantLoadsSetTy &RequiredILS;
|
||||
InvariantLoadsSetTy RequiredILS;
|
||||
|
||||
DetectionContext(Region &R, AliasAnalysis &AA,
|
||||
NonAffineSubRegionSetTy &NASRS, BoxedLoopsSetTy &BLS,
|
||||
InvariantLoadsSetTy &RequiredILS, bool Verify)
|
||||
/// @brief Initialize a DetectionContext from scratch.
|
||||
DetectionContext(Region &R, AliasAnalysis &AA, bool Verify)
|
||||
: CurRegion(R), AST(AA), Verifying(Verify), Log(&R), hasLoads(false),
|
||||
hasStores(false), NonAffineSubRegionSet(NASRS), BoxedLoopsSet(BLS),
|
||||
RequiredILS(RequiredILS) {}
|
||||
hasStores(false) {}
|
||||
|
||||
/// @brief Initialize a DetectionContext with the data from @p DC.
|
||||
DetectionContext(const DetectionContext &&DC)
|
||||
: CurRegion(DC.CurRegion), AST(DC.AST.getAliasAnalysis()),
|
||||
Verifying(DC.Verifying), Log(std::move(DC.Log)),
|
||||
Accesses(std::move(DC.Accesses)),
|
||||
NonAffineAccesses(std::move(DC.NonAffineAccesses)),
|
||||
ElementSize(std::move(DC.ElementSize)), hasLoads(DC.hasLoads),
|
||||
hasStores(DC.hasStores),
|
||||
NonAffineSubRegionSet(std::move(DC.NonAffineSubRegionSet)),
|
||||
BoxedLoopsSet(std::move(DC.BoxedLoopsSet)),
|
||||
RequiredILS(std::move(DC.RequiredILS)) {
|
||||
AST.add(DC.AST);
|
||||
}
|
||||
};
|
||||
|
||||
// Remember the valid regions
|
||||
RegionSet ValidRegions;
|
||||
private:
|
||||
//===--------------------------------------------------------------------===//
|
||||
ScopDetection(const ScopDetection &) = delete;
|
||||
const ScopDetection &operator=(const ScopDetection &) = delete;
|
||||
|
||||
/// @brief Analysis passes used.
|
||||
//@{
|
||||
const DominatorTree *DT;
|
||||
ScalarEvolution *SE;
|
||||
LoopInfo *LI;
|
||||
RegionInfo *RI;
|
||||
AliasAnalysis *AA;
|
||||
//@}
|
||||
|
||||
/// @brief Map to remember detection contexts for valid regions.
|
||||
using DetectionContextMapTy = DenseMap<const Region *, DetectionContext>;
|
||||
DetectionContextMapTy DetectionContextMap;
|
||||
|
||||
// Remember a list of errors for every region.
|
||||
mutable RejectLogsContainer RejectLogs;
|
||||
|
@ -399,6 +405,9 @@ public:
|
|||
/// @return Return true if R is the maximum Region in a Scop, false otherwise.
|
||||
bool isMaxRegionInScop(const Region &R, bool Verify = true) const;
|
||||
|
||||
/// @brief Return the detection context for @p R, nullptr if @p R was invalid.
|
||||
const DetectionContext *getDetectionContext(const Region *R) const;
|
||||
|
||||
/// @brief Return the set of loops in non-affine subregions for @p R.
|
||||
const BoxedLoopsSetTy *getBoxedLoops(const Region *R) const;
|
||||
|
||||
|
@ -459,9 +468,7 @@ public:
|
|||
/// detected Scops.
|
||||
///
|
||||
/// @param F The function to emit remarks for.
|
||||
/// @param ValidRegions The set of valid regions to emit remarks for.
|
||||
void emitMissedRemarksForValidRegions(const Function &F,
|
||||
const RegionSet &ValidRegions);
|
||||
void emitMissedRemarksForValidRegions(const Function &F);
|
||||
|
||||
/// @brief Mark the function as invalid so we will not extract any scop from
|
||||
/// the function.
|
||||
|
|
|
@ -255,12 +255,7 @@ bool ScopDetection::isMaxRegionInScop(const Region &R, bool Verify) const {
|
|||
return false;
|
||||
|
||||
if (Verify) {
|
||||
BoxedLoopsSetTy DummyBoxedLoopsSet;
|
||||
NonAffineSubRegionSetTy DummyNonAffineSubRegionSet;
|
||||
InvariantLoadsSetTy DummyILS;
|
||||
DetectionContext Context(const_cast<Region &>(R), *AA,
|
||||
DummyNonAffineSubRegionSet, DummyBoxedLoopsSet,
|
||||
DummyILS, false /*verifying*/);
|
||||
DetectionContext Context(const_cast<Region &>(R), *AA, false /*verifying*/);
|
||||
return isValidRegion(Context);
|
||||
}
|
||||
|
||||
|
@ -830,10 +825,10 @@ Region *ScopDetection::expandRegion(Region &R) {
|
|||
DEBUG(dbgs() << "\tExpanding " << R.getNameStr() << "\n");
|
||||
|
||||
while (ExpandedRegion) {
|
||||
DetectionContext Context(
|
||||
*ExpandedRegion, *AA, NonAffineSubRegionMap[ExpandedRegion.get()],
|
||||
BoxedLoopsMap[ExpandedRegion.get()],
|
||||
RequiredInvariantLoadsMap[ExpandedRegion.get()], false /* verifying */);
|
||||
const auto &It = DetectionContextMap.insert(std::make_pair(
|
||||
ExpandedRegion.get(),
|
||||
DetectionContext(*ExpandedRegion, *AA, false /*verifying*/)));
|
||||
DetectionContext &Context = It.first->second;
|
||||
DEBUG(dbgs() << "\t\tTrying " << ExpandedRegion->getNameStr() << "\n");
|
||||
// Only expand when we did not collect errors.
|
||||
|
||||
|
@ -857,6 +852,7 @@ Region *ScopDetection::expandRegion(Region &R) {
|
|||
|
||||
} else {
|
||||
// Create and test the next greater region (if any)
|
||||
removeCachedResults(*ExpandedRegion);
|
||||
ExpandedRegion =
|
||||
std::unique_ptr<Region>(ExpandedRegion->getExpandedRegion());
|
||||
}
|
||||
|
@ -893,14 +889,13 @@ unsigned ScopDetection::removeCachedResultsRecursively(const Region &R) {
|
|||
|
||||
void ScopDetection::removeCachedResults(const Region &R) {
|
||||
ValidRegions.remove(&R);
|
||||
BoxedLoopsMap.erase(&R);
|
||||
NonAffineSubRegionMap.erase(&R);
|
||||
RequiredInvariantLoadsMap.erase(&R);
|
||||
DetectionContextMap.erase(&R);
|
||||
}
|
||||
|
||||
void ScopDetection::findScops(Region &R) {
|
||||
DetectionContext Context(R, *AA, NonAffineSubRegionMap[&R], BoxedLoopsMap[&R],
|
||||
RequiredInvariantLoadsMap[&R], false /*verifying*/);
|
||||
const auto &It = DetectionContextMap.insert(
|
||||
std::make_pair(&R, DetectionContext(R, *AA, false /*verifying*/)));
|
||||
DetectionContext &Context = It.first->second;
|
||||
|
||||
bool RegionIsValid = false;
|
||||
if (!PollyProcessUnprofitable && regionWithoutLoops(R, LI)) {
|
||||
|
@ -1061,8 +1056,7 @@ void ScopDetection::printLocations(llvm::Function &F) {
|
|||
}
|
||||
}
|
||||
|
||||
void ScopDetection::emitMissedRemarksForValidRegions(
|
||||
const Function &F, const RegionSet &ValidRegions) {
|
||||
void ScopDetection::emitMissedRemarksForValidRegions(const Function &F) {
|
||||
for (const Region *R : ValidRegions) {
|
||||
const Region *Parent = R->getParent();
|
||||
if (Parent && !Parent->isTopLevelRegion() && RejectLogs.count(Parent))
|
||||
|
@ -1073,7 +1067,7 @@ void ScopDetection::emitMissedRemarksForValidRegions(
|
|||
void ScopDetection::emitMissedRemarksForLeaves(const Function &F,
|
||||
const Region *R) {
|
||||
for (const std::unique_ptr<Region> &Child : *R) {
|
||||
bool IsValid = ValidRegions.count(Child.get());
|
||||
bool IsValid = DetectionContextMap.count(Child.get());
|
||||
if (IsValid)
|
||||
continue;
|
||||
|
||||
|
@ -1111,7 +1105,7 @@ bool ScopDetection::runOnFunction(llvm::Function &F) {
|
|||
|
||||
// Only makes sense when we tracked errors.
|
||||
if (PollyTrackFailures) {
|
||||
emitMissedRemarksForValidRegions(F, ValidRegions);
|
||||
emitMissedRemarksForValidRegions(F);
|
||||
emitMissedRemarksForLeaves(F, TopRegion);
|
||||
}
|
||||
|
||||
|
@ -1121,43 +1115,44 @@ bool ScopDetection::runOnFunction(llvm::Function &F) {
|
|||
if (ReportLevel)
|
||||
printLocations(F);
|
||||
|
||||
assert(ValidRegions.size() == BoxedLoopsMap.size() &&
|
||||
"Cached more results than valid regions");
|
||||
assert(ValidRegions.size() == NonAffineSubRegionMap.size() &&
|
||||
assert(ValidRegions.size() == DetectionContextMap.size() &&
|
||||
"Cached more results than valid regions");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ScopDetection::isNonAffineSubRegion(const Region *SubR,
|
||||
const Region *ScopR) const {
|
||||
return NonAffineSubRegionMap.lookup(ScopR).count(SubR);
|
||||
const DetectionContext *DC = getDetectionContext(ScopR);
|
||||
assert(DC && "ScopR is no valid region!");
|
||||
return DC->NonAffineSubRegionSet.count(SubR);
|
||||
}
|
||||
|
||||
const ScopDetection::DetectionContext *
|
||||
ScopDetection::getDetectionContext(const Region *R) const {
|
||||
auto DCMIt = DetectionContextMap.find(R);
|
||||
if (DCMIt == DetectionContextMap.end())
|
||||
return nullptr;
|
||||
return &DCMIt->second;
|
||||
}
|
||||
|
||||
const ScopDetection::BoxedLoopsSetTy *
|
||||
ScopDetection::getBoxedLoops(const Region *R) const {
|
||||
auto BLMIt = BoxedLoopsMap.find(R);
|
||||
if (BLMIt == BoxedLoopsMap.end())
|
||||
return nullptr;
|
||||
return &BLMIt->second;
|
||||
const DetectionContext *DC = getDetectionContext(R);
|
||||
assert(DC && "ScopR is no valid region!");
|
||||
return &DC->BoxedLoopsSet;
|
||||
}
|
||||
|
||||
const InvariantLoadsSetTy *
|
||||
ScopDetection::getRequiredInvariantLoads(const Region *R) const {
|
||||
auto I = RequiredInvariantLoadsMap.find(R);
|
||||
if (I == RequiredInvariantLoadsMap.end())
|
||||
return nullptr;
|
||||
return &I->second;
|
||||
const DetectionContext *DC = getDetectionContext(R);
|
||||
assert(DC && "ScopR is no valid region!");
|
||||
return &DC->RequiredILS;
|
||||
}
|
||||
|
||||
void polly::ScopDetection::verifyRegion(const Region &R) const {
|
||||
assert(isMaxRegionInScop(R) && "Expect R is a valid region.");
|
||||
|
||||
BoxedLoopsSetTy DummyBoxedLoopsSet;
|
||||
NonAffineSubRegionSetTy DummyNonAffineSubRegionSet;
|
||||
InvariantLoadsSetTy DummyILS;
|
||||
DetectionContext Context(const_cast<Region &>(R), *AA,
|
||||
DummyNonAffineSubRegionSet, DummyBoxedLoopsSet,
|
||||
DummyILS, true /*verifying*/);
|
||||
DetectionContext Context(const_cast<Region &>(R), *AA, true /*verifying*/);
|
||||
isValidRegion(Context);
|
||||
}
|
||||
|
||||
|
@ -1190,9 +1185,7 @@ void ScopDetection::releaseMemory() {
|
|||
RejectLogs.clear();
|
||||
ValidRegions.clear();
|
||||
InsnToMemAcc.clear();
|
||||
BoxedLoopsMap.clear();
|
||||
NonAffineSubRegionMap.clear();
|
||||
RequiredInvariantLoadsMap.clear();
|
||||
DetectionContextMap.clear();
|
||||
|
||||
// Do not clear the invalid function set.
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue