From b0ae923ada836fa2c9114ac2c5afb39466f49fe0 Mon Sep 17 00:00:00 2001 From: Kazu Hirata Date: Sat, 22 Jun 2024 00:40:36 -0700 Subject: [ProfileData] Add a variant of getValueProfDataFromInst (#95993) This patch adds a variant of getValueProfDataFromInst that returns std::vector instead of std::unique. The new return type carries the length with it, so we can drop out parameter ActualNumValueData. Also, the caller can directly feed the return value into a range-based for loop as shown in the patch. I'm planning to migrate other callers of getValueProfDataFromInst to the new variant in follow-up patches. --- llvm/include/llvm/ProfileData/InstrProf.h | 7 ++++++ llvm/lib/Analysis/ModuleSummaryAnalysis.cpp | 17 +++++-------- llvm/lib/ProfileData/InstrProf.cpp | 39 +++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 11 deletions(-) diff --git a/llvm/include/llvm/ProfileData/InstrProf.h b/llvm/include/llvm/ProfileData/InstrProf.h index d5ddf169..9bb1d8c 100644 --- a/llvm/include/llvm/ProfileData/InstrProf.h +++ b/llvm/include/llvm/ProfileData/InstrProf.h @@ -294,6 +294,13 @@ getValueProfDataFromInst(const Instruction &Inst, InstrProfValueKind ValueKind, uint32_t MaxNumValueData, uint32_t &ActualNumValueData, uint64_t &TotalC, bool GetNoICPValue = false); +/// Extract the value profile data from \p Inst and returns them if \p Inst is +/// annotated with value profile data. Returns an empty vector otherwise. +SmallVector +getValueProfDataFromInst(const Instruction &Inst, InstrProfValueKind ValueKind, + uint32_t MaxNumValueData, uint64_t &TotalC, + bool GetNoICPValue = false); + inline StringRef getPGOFuncNameMetadataName() { return "PGOFuncName"; } /// Return the PGOFuncName meta data associated with a function. diff --git a/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp index c6934f5..94ac048 100644 --- a/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp +++ b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp @@ -143,20 +143,15 @@ static bool findRefEdges(ModuleSummaryIndex &Index, const User *CurUser, const Instruction *I = dyn_cast(CurUser); if (I) { - uint32_t ActualNumValueData = 0; uint64_t TotalCount = 0; // MaxNumVTableAnnotations is the maximum number of vtables annotated on // the instruction. - auto ValueDataArray = - getValueProfDataFromInst(*I, IPVK_VTableTarget, MaxNumVTableAnnotations, - ActualNumValueData, TotalCount); - - if (ValueDataArray.get()) { - for (uint32_t j = 0; j < ActualNumValueData; j++) { - RefEdges.insert(Index.getOrInsertValueInfo(/* VTableGUID = */ - ValueDataArray[j].Value)); - } - } + auto ValueDataArray = getValueProfDataFromInst( + *I, IPVK_VTableTarget, MaxNumVTableAnnotations, TotalCount); + + for (const auto &V : ValueDataArray) + RefEdges.insert(Index.getOrInsertValueInfo(/* VTableGUID = */ + V.Value)); } return HasBlockAddress; } diff --git a/llvm/lib/ProfileData/InstrProf.cpp b/llvm/lib/ProfileData/InstrProf.cpp index 3e0e2b2..c7749f3 100644 --- a/llvm/lib/ProfileData/InstrProf.cpp +++ b/llvm/lib/ProfileData/InstrProf.cpp @@ -1382,6 +1382,45 @@ getValueProfDataFromInst(const Instruction &Inst, InstrProfValueKind ValueKind, return ValueDataArray; } +SmallVector +getValueProfDataFromInst(const Instruction &Inst, InstrProfValueKind ValueKind, + uint32_t MaxNumValueData, uint64_t &TotalC, + bool GetNoICPValue) { + // Four inline elements seem to work well in practice. With MaxNumValueData, + // this array won't grow very big anyway. + SmallVector ValueData; + MDNode *MD = mayHaveValueProfileOfKind(Inst, ValueKind); + if (!MD) + return ValueData; + const unsigned NOps = MD->getNumOperands(); + // Get total count + ConstantInt *TotalCInt = mdconst::dyn_extract(MD->getOperand(2)); + if (!TotalCInt) + return ValueData; + TotalC = TotalCInt->getZExtValue(); + + ValueData.reserve((NOps - 3) / 2); + for (unsigned I = 3; I < NOps; I += 2) { + if (ValueData.size() >= MaxNumValueData) + break; + ConstantInt *Value = mdconst::dyn_extract(MD->getOperand(I)); + ConstantInt *Count = + mdconst::dyn_extract(MD->getOperand(I + 1)); + if (!Value || !Count) { + ValueData.clear(); + return ValueData; + } + uint64_t CntValue = Count->getZExtValue(); + if (!GetNoICPValue && (CntValue == NOMORE_ICP_MAGICNUM)) + continue; + InstrProfValueData V; + V.Value = Value->getZExtValue(); + V.Count = CntValue; + ValueData.push_back(V); + } + return ValueData; +} + MDNode *getPGOFuncNameMetadata(const Function &F) { return F.getMetadata(getPGOFuncNameMetadataName()); } -- cgit v1.1