https://github.com/minglotus-6 created
https://github.com/llvm/llvm-project/pull/83769
None
>From 04a2bca6ee0fbea6a9dc84f59e8bf4a41f8ae230 Mon Sep 17 00:00:00 2001
From: mingmingl
Date: Sun, 3 Mar 2024 22:16:03 -0800
Subject: [PATCH] [Inline]Update value profile for non-call instructions
---
llvm/include/llvm/IR/ProfDataUtils.h | 3 +
llvm/lib/IR/ProfDataUtils.cpp | 32 +++
llvm/lib/Transforms/Utils/InlineFunction.cpp | 26 +-
.../Transforms/Inline/update_value_profile.ll | 89 +++
4 files changed, 147 insertions(+), 3 deletions(-)
create mode 100644 llvm/test/Transforms/Inline/update_value_profile.ll
diff --git a/llvm/include/llvm/IR/ProfDataUtils.h
b/llvm/include/llvm/IR/ProfDataUtils.h
index 255fa2ff1c7906..2010c4bc1e8b34 100644
--- a/llvm/include/llvm/IR/ProfDataUtils.h
+++ b/llvm/include/llvm/IR/ProfDataUtils.h
@@ -108,5 +108,8 @@ bool extractProfTotalWeight(const Instruction , uint64_t
);
/// a `prof` metadata reference to instruction `I`.
void setBranchWeights(Instruction , ArrayRef Weights);
+/// Scaling value profile 'ProfData' using the ratio of S/T.
+MDNode *scaleValueProfile(const MDNode *ProfData, uint64_t S, uint64_t T);
+
} // namespace llvm
#endif
diff --git a/llvm/lib/IR/ProfDataUtils.cpp b/llvm/lib/IR/ProfDataUtils.cpp
index dcb057c1b25fd8..db91a66bf493ec 100644
--- a/llvm/lib/IR/ProfDataUtils.cpp
+++ b/llvm/lib/IR/ProfDataUtils.cpp
@@ -190,4 +190,36 @@ void setBranchWeights(Instruction , ArrayRef
Weights) {
I.setMetadata(LLVMContext::MD_prof, BranchWeights);
}
+MDNode *scaleValueProfile(const MDNode *ProfData, uint64_t S, uint64_t T) {
+ if (ProfData == nullptr)
+return nullptr;
+ assert(
+ dyn_cast(ProfData->getOperand(0))->getString().equals("VP") &&
+ "Expects value profile metadata");
+ LLVMContext = ProfData->getContext();
+ MDBuilder MDB(C);
+ APInt APS(128, S), APT(128, T);
+
+ SmallVector Vals;
+ Vals.push_back(ProfData->getOperand(0));
+ for (unsigned i = 1; i < ProfData->getNumOperands(); i += 2) {
+Vals.push_back(ProfData->getOperand(i));
+uint64_t Count =
+mdconst::dyn_extract(ProfData->getOperand(i + 1))
+->getValue()
+.getZExtValue();
+// Don't scale the magic number.
+if (Count == NOMORE_ICP_MAGICNUM) {
+ Vals.push_back(ProfData->getOperand(i + 1));
+ continue;
+}
+// Using APInt::div may be expensive, but most cases should fit 64 bits.
+APInt Val(128, Count);
+Val *= APS;
+Vals.push_back(MDB.createConstant(ConstantInt::get(
+Type::getInt64Ty(C), Val.udiv(APT).getLimitedValue(;
+ }
+ return MDNode::get(C, Vals);
+}
+
} // namespace llvm
diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp
b/llvm/lib/Transforms/Utils/InlineFunction.cpp
index d4d4bf5ebdf36e..7cc1641a207aef 100644
--- a/llvm/lib/Transforms/Utils/InlineFunction.cpp
+++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp
@@ -23,6 +23,7 @@
#include "llvm/Analysis/BlockFrequencyInfo.h"
#include "llvm/Analysis/CallGraph.h"
#include "llvm/Analysis/CaptureTracking.h"
+#include "llvm/Analysis/IndirectCallVisitor.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/MemoryProfileInfo.h"
#include "llvm/Analysis/ObjCARCAnalysisUtils.h"
@@ -30,8 +31,8 @@
#include "llvm/Analysis/ProfileSummaryInfo.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/Analysis/VectorUtils.h"
-#include "llvm/IR/AttributeMask.h"
#include "llvm/IR/Argument.h"
+#include "llvm/IR/AttributeMask.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CFG.h"
#include "llvm/IR/Constant.h"
@@ -55,6 +56,7 @@
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
+#include "llvm/IR/ProfDataUtils.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
@@ -1910,9 +1912,18 @@ void llvm::updateProfileCallee(
if (VMap) {
uint64_t CloneEntryCount = PriorEntryCount - NewEntryCount;
for (auto Entry : *VMap)
+ // FIXME: Update the profiles for invoke instruction after inline
if (isa(Entry.first))
-if (auto *CI = dyn_cast_or_null(Entry.second))
+if (auto *CI = dyn_cast_or_null(Entry.second)) {
CI->updateProfWeight(CloneEntryCount, PriorEntryCount);
+ Instruction *VPtr =
+ PGOIndirectCallVisitor::tryGetVTableInstruction(CI);
+ if (VPtr)
+VPtr->setMetadata(
+LLVMContext::MD_prof,
+scaleValueProfile(VPtr->getMetadata(LLVMContext::MD_prof),
+ CloneEntryCount, PriorEntryCount));
+}
}
if (EntryDelta) {
@@ -1922,8 +1933,17 @@ void llvm::updateProfileCallee(
// No need to update the callsite if it is pruned during inlining.
if (!VMap || VMap->count())
for (Instruction : BB)
- if (CallInst *CI = dyn_cast())
+ // FIXME: Update the profiles for invoke instruction after