private:
Module &M;
std::unique_ptr<ProfileSummary> Summary;
- bool computeSummary();
void computeThresholds();
// Count thresholds to answer isHotCount and isColdCount queries.
Optional<uint64_t> HotCountThreshold, ColdCountThreshold;
Optional<uint64_t> computeThreshold(int PercentileCutoff);
// The map that caches the threshold values. The keys are the percentile
// cutoff values and the values are the corresponding threshold values.
- DenseMap<int, uint64_t> ThresholdCache;
+ mutable DenseMap<int, uint64_t> ThresholdCache;
public:
- ProfileSummaryInfo(Module &M) : M(M) {}
- ProfileSummaryInfo(ProfileSummaryInfo &&Arg)
- : M(Arg.M), Summary(std::move(Arg.Summary)) {}
+ ProfileSummaryInfo(Module &M) : M(M) { refresh(); }
+ ProfileSummaryInfo(ProfileSummaryInfo &&Arg) = default;
+
+ /// If no summary is present, attempt to refresh.
+ void refresh();
/// Returns true if profile summary is available.
- bool hasProfileSummary() { return computeSummary(); }
+ bool hasProfileSummary() const { return Summary != nullptr; }
/// Returns true if module \c M has sample profile.
bool hasSampleProfile() {
// The profile summary metadata may be attached either by the frontend or by
// any backend passes (IR level instrumentation, for example). This method
// checks if the Summary is null and if so checks if the summary metadata is now
-// available in the module and parses it to get the Summary object. Returns true
-// if a valid Summary is available.
-bool ProfileSummaryInfo::computeSummary() {
- if (Summary)
- return true;
+// available in the module and parses it to get the Summary object.
+void ProfileSummaryInfo::refresh() {
+ if (hasProfileSummary())
+ return;
// First try to get context sensitive ProfileSummary.
auto *SummaryMD = M.getProfileSummary(/* IsCS */ true);
- if (SummaryMD) {
+ if (SummaryMD)
Summary.reset(ProfileSummary::getFromMD(SummaryMD));
- return true;
+
+ if (!hasProfileSummary()) {
+ // This will actually return PSK_Instr or PSK_Sample summary.
+ SummaryMD = M.getProfileSummary(/* IsCS */ false);
+ if (SummaryMD)
+ Summary.reset(ProfileSummary::getFromMD(SummaryMD));
}
- // This will actually return PSK_Instr or PSK_Sample summary.
- SummaryMD = M.getProfileSummary(/* IsCS */ false);
- if (!SummaryMD)
- return false;
- Summary.reset(ProfileSummary::getFromMD(SummaryMD));
- return true;
+ if (!hasProfileSummary())
+ return;
+ computeThresholds();
}
Optional<uint64_t> ProfileSummaryInfo::getProfileCount(const CallBase &Call,
/// either means it is not hot or it is unknown whether it is hot or not (for
/// example, no profile data is available).
bool ProfileSummaryInfo::isFunctionEntryHot(const Function *F) {
- if (!F || !computeSummary())
+ if (!F || !hasProfileSummary())
return false;
auto FunctionCount = F->getEntryCount();
// FIXME: The heuristic used below for determining hotness is based on
/// (for example, no profile data is available).
bool ProfileSummaryInfo::isFunctionHotInCallGraph(const Function *F,
BlockFrequencyInfo &BFI) {
- if (!F || !computeSummary())
+ if (!F || !hasProfileSummary())
return false;
if (auto FunctionCount = F->getEntryCount())
if (isHotCount(FunctionCount.getCount()))
/// (for example, no profile data is available).
bool ProfileSummaryInfo::isFunctionColdInCallGraph(const Function *F,
BlockFrequencyInfo &BFI) {
- if (!F || !computeSummary())
+ if (!F || !hasProfileSummary())
return false;
if (auto FunctionCount = F->getEntryCount())
if (!isColdCount(FunctionCount.getCount()))
template<bool isHot>
bool ProfileSummaryInfo::isFunctionHotOrColdInCallGraphNthPercentile(
int PercentileCutoff, const Function *F, BlockFrequencyInfo &BFI) {
- if (!F || !computeSummary())
+ if (!F || !hasProfileSummary())
return false;
if (auto FunctionCount = F->getEntryCount()) {
if (isHot &&
return false;
if (F->hasFnAttribute(Attribute::Cold))
return true;
- if (!computeSummary())
+ if (!hasProfileSummary())
return false;
auto FunctionCount = F->getEntryCount();
// FIXME: The heuristic used below for determining coldness is based on
/// Compute the hot and cold thresholds.
void ProfileSummaryInfo::computeThresholds() {
- if (!computeSummary())
- return;
auto &DetailedSummary = Summary->getDetailedSummary();
auto &HotEntry =
getEntryForPercentile(DetailedSummary, ProfileSummaryCutoffHot);
}
Optional<uint64_t> ProfileSummaryInfo::computeThreshold(int PercentileCutoff) {
- if (!computeSummary())
+ if (!hasProfileSummary())
return None;
auto iter = ThresholdCache.find(PercentileCutoff);
if (iter != ThresholdCache.end()) {
}
bool ProfileSummaryInfo::hasHugeWorkingSetSize() {
- if (!HasHugeWorkingSetSize)
- computeThresholds();
return HasHugeWorkingSetSize && HasHugeWorkingSetSize.getValue();
}
bool ProfileSummaryInfo::hasLargeWorkingSetSize() {
- if (!HasLargeWorkingSetSize)
- computeThresholds();
return HasLargeWorkingSetSize && HasLargeWorkingSetSize.getValue();
}
bool ProfileSummaryInfo::isHotCount(uint64_t C) {
- if (!HotCountThreshold)
- computeThresholds();
return HotCountThreshold && C >= HotCountThreshold.getValue();
}
bool ProfileSummaryInfo::isColdCount(uint64_t C) {
- if (!ColdCountThreshold)
- computeThresholds();
return ColdCountThreshold && C <= ColdCountThreshold.getValue();
}
}
uint64_t ProfileSummaryInfo::getOrCompHotCountThreshold() {
- if (!HotCountThreshold)
- computeThresholds();
return HotCountThreshold ? HotCountThreshold.getValue() : UINT64_MAX;
}
uint64_t ProfileSummaryInfo::getOrCompColdCountThreshold() {
- if (!ColdCountThreshold)
- computeThresholds();
return ColdCountThreshold ? ColdCountThreshold.getValue() : 0;
}