[IR] Remove ProfileCount Abstraction
This only exists to differentiate between real and synthetic profiles. Remove the abstraction now that we plan to fully remove synthetic profiles. Reviewers: mtrofin, david-xl Reviewed By: mtrofin Pull Request: https://github.com/llvm/llvm-project/pull/204770
This commit is contained in:
parent
65a7ccf656
commit
37a71b650a
24 changed files with 63 additions and 125 deletions
|
|
@ -325,9 +325,7 @@ private:
|
|||
|
||||
template <typename FuncT>
|
||||
std::optional<uint64_t> getEntryCount(const FuncT *F) const {
|
||||
if (!F->getEntryCount().has_value())
|
||||
return std::nullopt;
|
||||
return F->getEntryCount()->getCount();
|
||||
return F->getEntryCount();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -291,41 +291,19 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
enum ProfileCountType { PCT_Real, PCT_Synthetic };
|
||||
|
||||
/// Class to represent profile counts.
|
||||
///
|
||||
/// This class represents both real and synthetic profile counts.
|
||||
class ProfileCount {
|
||||
private:
|
||||
uint64_t Count = 0;
|
||||
ProfileCountType PCT = PCT_Real;
|
||||
|
||||
public:
|
||||
ProfileCount(uint64_t Count, ProfileCountType PCT)
|
||||
: Count(Count), PCT(PCT) {}
|
||||
uint64_t getCount() const { return Count; }
|
||||
ProfileCountType getType() const { return PCT; }
|
||||
bool isSynthetic() const { return PCT == PCT_Synthetic; }
|
||||
};
|
||||
|
||||
/// Set the entry count for this function.
|
||||
///
|
||||
/// Entry count is the number of times this function was executed based on
|
||||
/// pgo data. \p Imports points to a set of GUIDs that needs to
|
||||
/// be imported by the function for sample PGO, to enable the same inlines as
|
||||
/// the profiled optimized binary.
|
||||
void setEntryCount(ProfileCount Count,
|
||||
const DenseSet<GlobalValue::GUID> *Imports = nullptr);
|
||||
|
||||
/// A convenience wrapper for setting entry count
|
||||
void setEntryCount(uint64_t Count, ProfileCountType Type = PCT_Real,
|
||||
void setEntryCount(uint64_t Count,
|
||||
const DenseSet<GlobalValue::GUID> *Imports = nullptr);
|
||||
|
||||
/// Get the entry count for this function.
|
||||
///
|
||||
/// Entry count is the number of times the function was executed.
|
||||
std::optional<ProfileCount> getEntryCount() const;
|
||||
std::optional<uint64_t> getEntryCount() const;
|
||||
|
||||
/// Return true if the function is annotated with profile data.
|
||||
///
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@
|
|||
namespace llvm {
|
||||
using namespace sampleprof;
|
||||
using namespace sampleprofutil;
|
||||
using ProfileCount = Function::ProfileCount;
|
||||
|
||||
namespace vfs {
|
||||
class FileSystem;
|
||||
|
|
@ -1069,9 +1068,7 @@ void SampleProfileLoaderBaseImpl<BT>::initWeightPropagation(
|
|||
// Sets the GUIDs that are inlined in the profiled binary. This is used
|
||||
// for ThinLink to make correct liveness analysis, and also make the IR
|
||||
// match the profiled binary before annotation.
|
||||
getFunction(F).setEntryCount(
|
||||
ProfileCount(Samples->getHeadSamples() + 1, Function::PCT_Real),
|
||||
&InlinedGUIDs);
|
||||
getFunction(F).setEntryCount(Samples->getHeadSamples() + 1, &InlinedGUIDs);
|
||||
|
||||
if (!SampleProfileUseProfi) {
|
||||
// Compute dominance and loop info needed for propagation.
|
||||
|
|
@ -1101,9 +1098,7 @@ void SampleProfileLoaderBaseImpl<BT>::finalizeWeightPropagation(
|
|||
if (SampleProfileUseProfi) {
|
||||
const BasicBlockT *EntryBB = getEntryBB(&F);
|
||||
if (BlockWeights[EntryBB] > 0) {
|
||||
getFunction(F).setEntryCount(
|
||||
ProfileCount(BlockWeights[EntryBB], Function::PCT_Real),
|
||||
&InlinedGUIDs);
|
||||
getFunction(F).setEntryCount(BlockWeights[EntryBB], &InlinedGUIDs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -593,7 +593,7 @@ BlockFrequencyInfoImplBase::getProfileCountFromFreq(const Function &F,
|
|||
if (!EntryCount)
|
||||
return std::nullopt;
|
||||
// Use 128 bit APInt to do the arithmetic to avoid overflow.
|
||||
APInt BlockCount(128, EntryCount->getCount());
|
||||
APInt BlockCount(128, *EntryCount);
|
||||
APInt BlockFreq(128, Freq.getFrequency());
|
||||
APInt EntryFreq(128, getEntryFreq().getFrequency());
|
||||
BlockCount *= BlockFreq;
|
||||
|
|
|
|||
|
|
@ -928,7 +928,7 @@ class InlineCostCallAnalyzer final : public CallAnalyzer {
|
|||
|
||||
// Make sure we have a nonzero entry count.
|
||||
auto EntryCount = F.getEntryCount();
|
||||
if (!EntryCount || !EntryCount->getCount())
|
||||
if (!EntryCount || *EntryCount == 0)
|
||||
return false;
|
||||
|
||||
BlockFrequencyInfo *CalleeBFI = &(GetBFI(F));
|
||||
|
|
@ -1017,10 +1017,9 @@ class InlineCostCallAnalyzer final : public CallAnalyzer {
|
|||
|
||||
// Compute the cycle savings per call.
|
||||
auto EntryProfileCount = F.getEntryCount();
|
||||
assert(EntryProfileCount && EntryProfileCount->getCount());
|
||||
auto EntryCount = EntryProfileCount->getCount();
|
||||
CycleSavings += EntryCount / 2;
|
||||
CycleSavings = CycleSavings.udiv(EntryCount);
|
||||
assert(EntryProfileCount && *EntryProfileCount);
|
||||
CycleSavings += *EntryProfileCount / 2;
|
||||
CycleSavings = CycleSavings.udiv(*EntryProfileCount);
|
||||
|
||||
// Compute the total savings for the call site.
|
||||
auto *CallerBB = CandidateCall.getParent();
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ bool ProfileSummaryInfo::isFunctionEntryCold(const Function *F) const {
|
|||
// FIXME: The heuristic used below for determining coldness is based on
|
||||
// preliminary SPEC tuning for inliner. This will eventually be a
|
||||
// convenience method that calls isHotCount.
|
||||
return FunctionCount && isColdCount(FunctionCount->getCount());
|
||||
return FunctionCount && isColdCount(*FunctionCount);
|
||||
}
|
||||
|
||||
/// Compute the hot and cold thresholds.
|
||||
|
|
|
|||
|
|
@ -1608,8 +1608,7 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
|
|||
if (Features.FuncEntryCount) {
|
||||
OutStreamer->AddComment("function entry count");
|
||||
auto MaybeEntryCount = MF.getFunction().getEntryCount();
|
||||
OutStreamer->emitULEB128IntValue(
|
||||
MaybeEntryCount ? MaybeEntryCount->getCount() : 0);
|
||||
OutStreamer->emitULEB128IntValue(MaybeEntryCount ? *MaybeEntryCount : 0);
|
||||
}
|
||||
const MachineBlockFrequencyInfo *MBFI =
|
||||
Features.BBFreq
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@
|
|||
using namespace llvm;
|
||||
using namespace sampleprof;
|
||||
using namespace llvm::sampleprofutil;
|
||||
using ProfileCount = Function::ProfileCount;
|
||||
|
||||
#define DEBUG_TYPE "fs-profile-loader"
|
||||
|
||||
|
|
|
|||
|
|
@ -1669,9 +1669,7 @@ template <>
|
|||
std::optional<uint64_t>
|
||||
ProfileSummaryInfo::getEntryCount<llvm::MachineFunction>(
|
||||
const llvm::MachineFunction *F) const {
|
||||
if (!F->getFunction().getEntryCount().has_value())
|
||||
return std::nullopt;
|
||||
return F->getFunction().getEntryCount()->getCount();
|
||||
return F->getFunction().getEntryCount();
|
||||
}
|
||||
|
||||
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
|
||||
|
|
|
|||
|
|
@ -56,7 +56,6 @@
|
|||
#include <string>
|
||||
|
||||
using namespace llvm;
|
||||
using ProfileCount = Function::ProfileCount;
|
||||
|
||||
// Explicit instantiations of SymbolTableListTraits since some of the methods
|
||||
// are not in the public header file...
|
||||
|
|
@ -1079,29 +1078,18 @@ void Function::setValueSubclassDataBit(unsigned Bit, bool On) {
|
|||
setValueSubclassData(getSubclassDataFromValue() & ~(1 << Bit));
|
||||
}
|
||||
|
||||
void Function::setEntryCount(ProfileCount Count,
|
||||
void Function::setEntryCount(uint64_t Count,
|
||||
const DenseSet<GlobalValue::GUID> *S) {
|
||||
#if !defined(NDEBUG)
|
||||
auto PrevCount = getEntryCount();
|
||||
assert(!PrevCount || PrevCount->getType() == Count.getType());
|
||||
#endif
|
||||
|
||||
auto ImportGUIDs = getImportGUIDs();
|
||||
if (S == nullptr && ImportGUIDs.size())
|
||||
S = &ImportGUIDs;
|
||||
|
||||
MDBuilder MDB(getContext());
|
||||
setMetadata(
|
||||
LLVMContext::MD_prof,
|
||||
MDB.createFunctionEntryCount(Count.getCount(), Count.isSynthetic(), S));
|
||||
setMetadata(LLVMContext::MD_prof,
|
||||
MDB.createFunctionEntryCount(Count, false, S));
|
||||
}
|
||||
|
||||
void Function::setEntryCount(uint64_t Count, Function::ProfileCountType Type,
|
||||
const DenseSet<GlobalValue::GUID> *Imports) {
|
||||
setEntryCount(ProfileCount(Count, Type), Imports);
|
||||
}
|
||||
|
||||
std::optional<ProfileCount> Function::getEntryCount() const {
|
||||
std::optional<uint64_t> Function::getEntryCount() const {
|
||||
MDNode *MD = getMetadata(LLVMContext::MD_prof);
|
||||
if (MD && MD->getOperand(0))
|
||||
if (MDString *MDS = dyn_cast<MDString>(MD->getOperand(0))) {
|
||||
|
|
@ -1113,7 +1101,7 @@ std::optional<ProfileCount> Function::getEntryCount() const {
|
|||
// Treat this the same as unknown.
|
||||
if (Count == static_cast<uint64_t>(-1))
|
||||
return std::nullopt;
|
||||
return ProfileCount(Count, PCT_Real);
|
||||
return Count;
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -282,15 +282,13 @@ void llvm::setExplicitlyUnknownBranchWeightsIfProfiled(Instruction &I,
|
|||
F = F ? F : I.getFunction();
|
||||
assert(F && "Either pass a instruction attached to a Function, or explicitly "
|
||||
"pass the Function that it will be attached to");
|
||||
if (std::optional<Function::ProfileCount> EC = F->getEntryCount();
|
||||
EC && EC->getCount() > 0)
|
||||
if (std::optional<uint64_t> EC = F->getEntryCount(); EC && *EC > 0)
|
||||
setExplicitlyUnknownBranchWeights(I, PassName);
|
||||
}
|
||||
|
||||
MDNode *llvm::getExplicitlyUnknownBranchWeightsIfProfiled(Function &F,
|
||||
StringRef PassName) {
|
||||
if (std::optional<Function::ProfileCount> EC = F.getEntryCount();
|
||||
!EC || EC->getCount() == 0)
|
||||
if (std::optional<uint64_t> EC = F.getEntryCount(); !EC || *EC == 0)
|
||||
return nullptr;
|
||||
MDBuilder MDB(F.getContext());
|
||||
return MDNode::get(
|
||||
|
|
|
|||
|
|
@ -1953,8 +1953,8 @@ void StrNCmpInliner::inlineCompare(Value *LHS, StringRef RHS, uint64_t N,
|
|||
|
||||
Function *F = CI->getFunction();
|
||||
assert(F && "Instruction does not belong to a function!");
|
||||
std::optional<Function::ProfileCount> EC = F->getEntryCount();
|
||||
if (EC && EC->getCount() > 0)
|
||||
std::optional<uint64_t> EC = F->getEntryCount();
|
||||
if (EC && *EC > 0)
|
||||
setExplicitlyUnknownBranchWeights(*CondBrInst, DEBUG_TYPE);
|
||||
} else {
|
||||
B.CreateBr(BBNE);
|
||||
|
|
|
|||
|
|
@ -795,14 +795,13 @@ bool FunctionSpecializer::run() {
|
|||
std::optional<uint64_t> Count =
|
||||
BFI.getBlockProfileCount(Call->getParent());
|
||||
if (Count && !ProfcheckDisableMetadataFixes) {
|
||||
std::optional<llvm::Function::ProfileCount> MaybeCloneCount =
|
||||
Clone->getEntryCount();
|
||||
std::optional<uint64_t> MaybeCloneCount = Clone->getEntryCount();
|
||||
if (MaybeCloneCount) {
|
||||
uint64_t CallCount = *Count + MaybeCloneCount->getCount();
|
||||
uint64_t CallCount = *Count + *MaybeCloneCount;
|
||||
Clone->setEntryCount(CallCount);
|
||||
if (std::optional<llvm::Function::ProfileCount> MaybeOriginalCount =
|
||||
if (std::optional<uint64_t> MaybeOriginalCount =
|
||||
S.F->getEntryCount()) {
|
||||
uint64_t OriginalCount = MaybeOriginalCount->getCount();
|
||||
uint64_t OriginalCount = *MaybeOriginalCount;
|
||||
if (OriginalCount >= *Count) {
|
||||
S.F->setEntryCount(OriginalCount - *Count);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -1355,8 +1355,7 @@ bool PartialInlinerImpl::tryPartialInline(FunctionCloner &Cloner) {
|
|||
if (CalleeEntryCount)
|
||||
computeCallsiteToProfCountMap(Cloner.ClonedFunc, CallSiteToProfCountMap);
|
||||
|
||||
uint64_t CalleeEntryCountV =
|
||||
(CalleeEntryCount ? CalleeEntryCount->getCount() : 0);
|
||||
uint64_t CalleeEntryCountV = (CalleeEntryCount ? *CalleeEntryCount : 0);
|
||||
|
||||
bool AnyInline = false;
|
||||
for (User *User : Users) {
|
||||
|
|
@ -1408,8 +1407,7 @@ bool PartialInlinerImpl::tryPartialInline(FunctionCloner &Cloner) {
|
|||
if (AnyInline) {
|
||||
Cloner.IsFunctionInlined = true;
|
||||
if (CalleeEntryCount)
|
||||
Cloner.OrigFunc->setEntryCount(Function::ProfileCount(
|
||||
CalleeEntryCountV, CalleeEntryCount->getType()));
|
||||
Cloner.OrigFunc->setEntryCount(CalleeEntryCountV);
|
||||
OptimizationRemarkEmitter OrigFuncORE(Cloner.OrigFunc);
|
||||
OrigFuncORE.emit([&]() {
|
||||
return OptimizationRemark(DEBUG_TYPE, "PartiallyInlined", Cloner.OrigFunc)
|
||||
|
|
|
|||
|
|
@ -93,7 +93,6 @@
|
|||
using namespace llvm;
|
||||
using namespace sampleprof;
|
||||
using namespace llvm::sampleprofutil;
|
||||
using ProfileCount = Function::ProfileCount;
|
||||
#define DEBUG_TYPE "sample-profile"
|
||||
#define CSINLINE_DEBUG DEBUG_TYPE "-inline"
|
||||
|
||||
|
|
@ -2291,7 +2290,7 @@ bool SampleProfileLoader::runOnFunction(Function &F,
|
|||
// Initialize entry count when the function has no existing entry
|
||||
// count value.
|
||||
if (!F.getEntryCount())
|
||||
F.setEntryCount(ProfileCount(initialEntryCount, Function::PCT_Real));
|
||||
F.setEntryCount(initialEntryCount);
|
||||
auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(*F.getParent())
|
||||
.getManager();
|
||||
ORE = &FAM.getResult<OptimizationRemarkEmitterAnalysis>(F);
|
||||
|
|
|
|||
|
|
@ -1581,12 +1581,12 @@ void DevirtModule::applyICallBranchFunnel(VTableSlotInfo &SlotInfo,
|
|||
auto EC = BFI.getBlockFreq(&F.getEntryBlock());
|
||||
auto CC = F.getEntryCount();
|
||||
double CallCount = 0.0;
|
||||
if (EC.getFrequency() != 0 && CC && CC->getCount() != 0) {
|
||||
if (EC.getFrequency() != 0 && CC && *CC != 0) {
|
||||
double CallFreq =
|
||||
static_cast<double>(
|
||||
BFI.getBlockFreq(CB.getParent()).getFrequency()) /
|
||||
EC.getFrequency();
|
||||
CallCount = CallFreq * CC->getCount();
|
||||
CallCount = CallFreq * *CC;
|
||||
}
|
||||
FunctionEntryCounts[&JT] += CallCount;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -128,7 +128,6 @@
|
|||
#include <vector>
|
||||
|
||||
using namespace llvm;
|
||||
using ProfileCount = Function::ProfileCount;
|
||||
using VPCandidateInfo = ValueProfileCollector::CandidateInfo;
|
||||
|
||||
#define DEBUG_TYPE "pgo-instrumentation"
|
||||
|
|
@ -1675,7 +1674,7 @@ void PGOUseFunc::populateCounters() {
|
|||
// Fix the obviously inconsistent entry count.
|
||||
if (FuncMaxCount > 0 && FuncEntryCount == 0)
|
||||
FuncEntryCount = 1;
|
||||
F.setEntryCount(ProfileCount(FuncEntryCount, Function::PCT_Real));
|
||||
F.setEntryCount(FuncEntryCount);
|
||||
markFunctionAttributes(FuncEntryCount, FuncMaxCount);
|
||||
|
||||
LLVM_DEBUG(FuncInfo.dumpInfo("after reading profile."));
|
||||
|
|
@ -1943,7 +1942,7 @@ static bool skipPGOGen(const Function &F) {
|
|||
return true;
|
||||
if (PGOInstrumentColdFunctionOnly) {
|
||||
if (auto EntryCount = F.getEntryCount())
|
||||
return EntryCount->getCount() > PGOColdInstrumentEntryThreshold;
|
||||
return *EntryCount > PGOColdInstrumentEntryThreshold;
|
||||
return !PGOTreatUnknownAsCold;
|
||||
}
|
||||
return false;
|
||||
|
|
@ -2031,8 +2030,7 @@ static void fixFuncEntryCount(PGOUseFunc &Func, LoopInfo &LI,
|
|||
BlockFrequencyInfo NBFI(F, NBPI, LI);
|
||||
#ifndef NDEBUG
|
||||
auto BFIEntryCount = F.getEntryCount();
|
||||
assert(BFIEntryCount && (BFIEntryCount->getCount() > 0) &&
|
||||
"Invalid BFI Entrycount");
|
||||
assert(BFIEntryCount && (*BFIEntryCount > 0) && "Invalid BFI Entrycount");
|
||||
#endif
|
||||
auto SumCount = APFloat::getZero(APFloat::IEEEdouble());
|
||||
auto SumBFICount = APFloat::getZero(APFloat::IEEEdouble());
|
||||
|
|
@ -2063,7 +2061,7 @@ static void fixFuncEntryCount(PGOUseFunc &Func, LoopInfo &LI,
|
|||
if (NewEntryCount == 0)
|
||||
NewEntryCount = 1;
|
||||
if (NewEntryCount != FuncEntryCount) {
|
||||
F.setEntryCount(ProfileCount(NewEntryCount, Function::PCT_Real));
|
||||
F.setEntryCount(NewEntryCount);
|
||||
LLVM_DEBUG(dbgs() << "FixFuncEntryCount: in " << F.getName()
|
||||
<< ", entry_count " << FuncEntryCount << " --> "
|
||||
<< NewEntryCount << "\n");
|
||||
|
|
@ -2255,7 +2253,7 @@ static bool annotateAllFunctions(
|
|||
if (!Func.readCounters(AllZeros, PseudoKind))
|
||||
continue;
|
||||
if (AllZeros) {
|
||||
F.setEntryCount(ProfileCount(0, Function::PCT_Real));
|
||||
F.setEntryCount(0);
|
||||
if (Func.getProgramMaxCount() != 0)
|
||||
ColdFunctions.push_back(&F);
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -442,7 +442,7 @@ class TailRecursionEliminator {
|
|||
: F(F), TTI(TTI), AA(AA), ORE(ORE), DTU(DTU), BFI(BFI),
|
||||
OrigEntryBBFreq(
|
||||
BFI ? BFI->getBlockFreq(&F.getEntryBlock()).getFrequency() : 0U),
|
||||
OrigEntryCount(F.getEntryCount() ? F.getEntryCount()->getCount() : 0) {
|
||||
OrigEntryCount(F.getEntryCount() ? *F.getEntryCount() : 0) {
|
||||
if (BFI) {
|
||||
// The assert is meant as API documentation for the caller.
|
||||
assert((OrigEntryCount != 0 && OrigEntryBBFreq != 0) &&
|
||||
|
|
@ -771,7 +771,7 @@ bool TailRecursionEliminator::eliminateCall(CallInst *CI) {
|
|||
static_cast<double>(OrigEntryBBFreq);
|
||||
auto ToSubtract =
|
||||
static_cast<uint64_t>(std::round(RelativeBBFreq * OrigEntryCount));
|
||||
auto OldEntryCount = F.getEntryCount()->getCount();
|
||||
auto OldEntryCount = *F.getEntryCount();
|
||||
if (OldEntryCount <= ToSubtract) {
|
||||
LLVM_DEBUG(
|
||||
errs() << "[TRE] The entrycount attributable to the recursive call, "
|
||||
|
|
@ -779,7 +779,7 @@ bool TailRecursionEliminator::eliminateCall(CallInst *CI) {
|
|||
<< ", should be strictly lower than the function entry count, "
|
||||
<< OldEntryCount << "\n");
|
||||
} else {
|
||||
F.setEntryCount(OldEntryCount - ToSubtract, F.getEntryCount()->getType());
|
||||
F.setEntryCount(OldEntryCount - ToSubtract);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
@ -992,7 +992,7 @@ PreservedAnalyses TailCallElimPass::run(Function &F,
|
|||
// the lines asking for the cached result, should they be nullptr (which, in
|
||||
// the case of the PDT, is likely), updates to the trees would be missed.
|
||||
auto *BFI = (!ForceDisableBFI && UpdateFunctionEntryCount &&
|
||||
F.getEntryCount().has_value() && F.getEntryCount()->getCount())
|
||||
F.getEntryCount().has_value() && *F.getEntryCount())
|
||||
? &AM.getResult<BlockFrequencyAnalysis>(F)
|
||||
: nullptr;
|
||||
auto &ORE = AM.getResult<OptimizationRemarkEmitterAnalysis>(F);
|
||||
|
|
|
|||
|
|
@ -66,7 +66,6 @@
|
|||
|
||||
using namespace llvm;
|
||||
using namespace llvm::PatternMatch;
|
||||
using ProfileCount = Function::ProfileCount;
|
||||
|
||||
#define DEBUG_TYPE "code-extractor"
|
||||
|
||||
|
|
@ -1092,8 +1091,7 @@ Function *CodeExtractor::constructFunctionDeclaration(
|
|||
if (BFI) {
|
||||
auto Count = BFI->getProfileCountFromFreq(EntryFreq);
|
||||
if (Count.has_value())
|
||||
newFunction->setEntryCount(
|
||||
ProfileCount(*Count, Function::PCT_Real)); // FIXME
|
||||
newFunction->setEntryCount(*Count);
|
||||
}
|
||||
|
||||
return newFunction;
|
||||
|
|
|
|||
|
|
@ -86,7 +86,6 @@
|
|||
|
||||
using namespace llvm;
|
||||
using namespace llvm::memprof;
|
||||
using ProfileCount = Function::ProfileCount;
|
||||
|
||||
static cl::opt<bool>
|
||||
EnableNoAliasConversion("enable-noalias-to-md-conversion", cl::init(true),
|
||||
|
|
@ -2162,15 +2161,14 @@ static void updateCallerBFI(BasicBlock *CallSiteBlock,
|
|||
|
||||
/// Update the branch metadata for cloned call instructions.
|
||||
static void updateCallProfile(Function *Callee, const ValueToValueMapTy &VMap,
|
||||
const ProfileCount &CalleeEntryCount,
|
||||
const uint64_t &CalleeEntryCount,
|
||||
const CallBase &TheCall, ProfileSummaryInfo *PSI,
|
||||
BlockFrequencyInfo *CallerBFI) {
|
||||
if (CalleeEntryCount.isSynthetic() || CalleeEntryCount.getCount() < 1)
|
||||
if (CalleeEntryCount < 1)
|
||||
return;
|
||||
auto CallSiteCount =
|
||||
PSI ? PSI->getProfileCount(TheCall, CallerBFI) : std::nullopt;
|
||||
int64_t CallCount =
|
||||
std::min(CallSiteCount.value_or(0), CalleeEntryCount.getCount());
|
||||
int64_t CallCount = std::min(CallSiteCount.value_or(0), CalleeEntryCount);
|
||||
updateProfileCallee(Callee, -CallCount, &VMap);
|
||||
}
|
||||
|
||||
|
|
@ -2181,14 +2179,12 @@ void llvm::updateProfileCallee(
|
|||
if (!CalleeCount)
|
||||
return;
|
||||
|
||||
const uint64_t PriorEntryCount = CalleeCount->getCount();
|
||||
|
||||
// Since CallSiteCount is an estimate, it could exceed the original callee
|
||||
// count and has to be set to 0 so guard against underflow.
|
||||
const uint64_t NewEntryCount =
|
||||
(EntryDelta < 0 && static_cast<uint64_t>(-EntryDelta) > PriorEntryCount)
|
||||
(EntryDelta < 0 && static_cast<uint64_t>(-EntryDelta) > *CalleeCount)
|
||||
? 0
|
||||
: PriorEntryCount + EntryDelta;
|
||||
: *CalleeCount + EntryDelta;
|
||||
|
||||
auto updateVTableProfWeight = [](CallBase *CB, const uint64_t NewEntryCount,
|
||||
const uint64_t PriorEntryCount) {
|
||||
|
|
@ -2199,18 +2195,18 @@ void llvm::updateProfileCallee(
|
|||
|
||||
// During inlining ?
|
||||
if (VMap) {
|
||||
uint64_t CloneEntryCount = PriorEntryCount - NewEntryCount;
|
||||
uint64_t CloneEntryCount = *CalleeCount - NewEntryCount;
|
||||
for (auto Entry : *VMap) {
|
||||
if (isa<CallInst>(Entry.first))
|
||||
if (auto *CI = dyn_cast_or_null<CallInst>(Entry.second)) {
|
||||
CI->updateProfWeight(CloneEntryCount, PriorEntryCount);
|
||||
updateVTableProfWeight(CI, CloneEntryCount, PriorEntryCount);
|
||||
CI->updateProfWeight(CloneEntryCount, *CalleeCount);
|
||||
updateVTableProfWeight(CI, CloneEntryCount, *CalleeCount);
|
||||
}
|
||||
|
||||
if (isa<InvokeInst>(Entry.first))
|
||||
if (auto *II = dyn_cast_or_null<InvokeInst>(Entry.second)) {
|
||||
II->updateProfWeight(CloneEntryCount, PriorEntryCount);
|
||||
updateVTableProfWeight(II, CloneEntryCount, PriorEntryCount);
|
||||
II->updateProfWeight(CloneEntryCount, *CalleeCount);
|
||||
updateVTableProfWeight(II, CloneEntryCount, *CalleeCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2223,12 +2219,12 @@ void llvm::updateProfileCallee(
|
|||
if (!VMap || VMap->count(&BB))
|
||||
for (Instruction &I : BB) {
|
||||
if (CallInst *CI = dyn_cast<CallInst>(&I)) {
|
||||
CI->updateProfWeight(NewEntryCount, PriorEntryCount);
|
||||
updateVTableProfWeight(CI, NewEntryCount, PriorEntryCount);
|
||||
CI->updateProfWeight(NewEntryCount, *CalleeCount);
|
||||
updateVTableProfWeight(CI, NewEntryCount, *CalleeCount);
|
||||
}
|
||||
if (InvokeInst *II = dyn_cast<InvokeInst>(&I)) {
|
||||
II->updateProfWeight(NewEntryCount, PriorEntryCount);
|
||||
updateVTableProfWeight(II, NewEntryCount, PriorEntryCount);
|
||||
II->updateProfWeight(NewEntryCount, *CalleeCount);
|
||||
updateVTableProfWeight(II, NewEntryCount, *CalleeCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,9 +72,8 @@ struct LoopExpansionInfo {
|
|||
std::optional<uint64_t> getAverageMemOpLoopTripCount(const MemIntrinsic &I) {
|
||||
if (ProfcheckDisableMetadataFixes)
|
||||
return std::nullopt;
|
||||
if (std::optional<Function::ProfileCount> EC =
|
||||
I.getFunction()->getEntryCount();
|
||||
!EC || !EC->getCount())
|
||||
if (std::optional<uint64_t> EC = I.getFunction()->getEntryCount();
|
||||
!EC || *EC == 0)
|
||||
return std::nullopt;
|
||||
if (const auto Len = I.getLengthInBytes())
|
||||
return Len->getZExtValue();
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ bool ProfileInjector::inject() {
|
|||
F.setEntryCount(DefaultFunctionEntryCount);
|
||||
// If there is an entry count that's 0, then don't bother injecting. We won't
|
||||
// verify these either.
|
||||
if (F.getEntryCount()->getCount() == 0)
|
||||
if (*F.getEntryCount() == 0)
|
||||
return false;
|
||||
bool Changed = false;
|
||||
// Cycle through the weights list. If we didn't, tests with more than (say)
|
||||
|
|
@ -248,7 +248,7 @@ PreservedAnalyses ProfileVerifierPass::run(Function &F,
|
|||
emitProfileError("function entry count missing (set to 0 if cold)", F);
|
||||
return PreservedAnalyses::all();
|
||||
}
|
||||
} else if (EntryCount->getCount() == 0) {
|
||||
} else if (*EntryCount == 0) {
|
||||
return PreservedAnalyses::all();
|
||||
}
|
||||
for (const auto &BB : F) {
|
||||
|
|
|
|||
|
|
@ -1796,7 +1796,7 @@ void LoopVectorizationPlanner::updateLoopMetadataAndProfileInfo(
|
|||
unsigned AverageVectorTripCount = 0;
|
||||
unsigned RemainderAverageTripCount = 0;
|
||||
auto EC = VectorLoop->getLoopPreheader()->getParent()->getEntryCount();
|
||||
auto IsProfiled = EC && EC->getCount();
|
||||
auto IsProfiled = EC && *EC != 0;
|
||||
if (!OrigAverageTripCount) {
|
||||
if (!IsProfiled)
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -5215,14 +5215,13 @@ TEST_F(FunctionAttachmentTest, Verifier) {
|
|||
EXPECT_FALSE(verifyFunction(*F));
|
||||
}
|
||||
|
||||
TEST_F(FunctionAttachmentTest, RealEntryCount) {
|
||||
TEST_F(FunctionAttachmentTest, EntryCount) {
|
||||
Function *F = getFunction("foo");
|
||||
EXPECT_FALSE(F->getEntryCount().has_value());
|
||||
F->setEntryCount(12304, Function::PCT_Real);
|
||||
F->setEntryCount(12304);
|
||||
auto Count = F->getEntryCount();
|
||||
EXPECT_TRUE(Count.has_value());
|
||||
EXPECT_EQ(12304u, Count->getCount());
|
||||
EXPECT_EQ(Function::PCT_Real, Count->getType());
|
||||
EXPECT_EQ(12304u, *Count);
|
||||
}
|
||||
|
||||
TEST_F(FunctionAttachmentTest, SubprogramAttachment) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue