aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Kirth <paulkirth@google.com>2024-06-24 17:46:52 +0000
committerPaul Kirth <paulkirth@google.com>2024-06-24 17:46:52 +0000
commitb04ec84bd94de1ea990bcfe62a203ffceb4ac03f (patch)
tree2b59123b1b07a30faaf754e69540dd50a96c534a
parentf985a8826bfa4ca3d23e654185de35e30ea6dc79 (diff)
downloadllvm-users/ilovepi/spr/main.llvmmisexpect-enable-diagnostics-for-profitable-llvmexpect-annotations.zip
llvm-users/ilovepi/spr/main.llvmmisexpect-enable-diagnostics-for-profitable-llvmexpect-annotations.tar.gz
llvm-users/ilovepi/spr/main.llvmmisexpect-enable-diagnostics-for-profitable-llvmexpect-annotations.tar.bz2
Created using spr 1.3.4 [skip ci]
-rw-r--r--llvm/include/llvm/IR/ProfDataUtils.h2
-rw-r--r--llvm/lib/IR/Instructions.cpp6
-rw-r--r--llvm/lib/IR/ProfDataUtils.cpp8
-rw-r--r--llvm/lib/IR/Verifier.cpp12
-rw-r--r--llvm/lib/Transforms/Utils/MisExpect.cpp19
5 files changed, 24 insertions, 23 deletions
diff --git a/llvm/include/llvm/IR/ProfDataUtils.h b/llvm/include/llvm/IR/ProfDataUtils.h
index 1d7c97d..0bea517 100644
--- a/llvm/include/llvm/IR/ProfDataUtils.h
+++ b/llvm/include/llvm/IR/ProfDataUtils.h
@@ -66,6 +66,8 @@ bool hasBranchWeightOrigin(const MDNode *ProfileData);
/// Return the offset to the first branch weight data
unsigned getBranchWeightOffset(const MDNode *ProfileData);
+unsigned getNumBranchWeights(const MDNode &ProfileData);
+
/// Extract branch weights from MD_prof metadata
///
/// \param ProfileData A pointer to an MDNode.
diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp
index 445323f..52e25a8 100644
--- a/llvm/lib/IR/Instructions.cpp
+++ b/llvm/lib/IR/Instructions.cpp
@@ -4002,11 +4002,7 @@ void SwitchInstProfUpdateWrapper::init() {
if (!ProfileData)
return;
- // FIXME: This check belongs in ProfDataUtils. Its almost equivalent to
- // getValidBranchWeightMDNode(), but the need to use llvm_unreachable
- // makes them slightly different.
- if (ProfileData->getNumOperands() !=
- SI.getNumSuccessors() + getBranchWeightOffset(ProfileData)) {
+ if (getNumBranchWeights(*ProfileData) != SI.getNumSuccessors()) {
llvm_unreachable("number of prof branch_weights metadata operands does "
"not correspond to number of succesors");
}
diff --git a/llvm/lib/IR/ProfDataUtils.cpp b/llvm/lib/IR/ProfDataUtils.cpp
index 2f8e61c..992ce34 100644
--- a/llvm/lib/IR/ProfDataUtils.cpp
+++ b/llvm/lib/IR/ProfDataUtils.cpp
@@ -142,6 +142,10 @@ unsigned getBranchWeightOffset(const MDNode *ProfileData) {
return hasBranchWeightOrigin(ProfileData) ? 2 : 1;
}
+unsigned getNumBranchWeights(const MDNode &ProfileData) {
+ return ProfileData.getNumOperands() - getBranchWeightOffset(&ProfileData);
+}
+
MDNode *getBranchWeightMDNode(const Instruction &I) {
auto *ProfileData = I.getMetadata(LLVMContext::MD_prof);
if (!isBranchWeightMD(ProfileData))
@@ -151,9 +155,7 @@ MDNode *getBranchWeightMDNode(const Instruction &I) {
MDNode *getValidBranchWeightMDNode(const Instruction &I) {
auto *ProfileData = getBranchWeightMDNode(I);
- auto Offset = getBranchWeightOffset(ProfileData);
- if (ProfileData &&
- ProfileData->getNumOperands() == Offset + I.getNumSuccessors())
+ if (ProfileData && getNumBranchWeights(*ProfileData) == I.getNumSuccessors())
return ProfileData;
return nullptr;
}
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 0abd5f7..c98f61d 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -4818,10 +4818,9 @@ void Verifier::visitProfMetadata(Instruction &I, MDNode *MD) {
// Check consistency of !prof branch_weights metadata.
if (ProfName == "branch_weights") {
- unsigned int Offset = getBranchWeightOffset(MD);
+ unsigned NumBranchWeights = getNumBranchWeights(*MD);
if (isa<InvokeInst>(&I)) {
- Check(MD->getNumOperands() == (1 + Offset) ||
- MD->getNumOperands() == (2 + Offset),
+ Check(NumBranchWeights == 1 || NumBranchWeights == 2,
"Wrong number of InvokeInst branch_weights operands", MD);
} else {
unsigned ExpectedNumOperands = 0;
@@ -4841,10 +4840,11 @@ void Verifier::visitProfMetadata(Instruction &I, MDNode *MD) {
CheckFailed("!prof branch_weights are not allowed for this instruction",
MD);
- Check(MD->getNumOperands() == Offset + ExpectedNumOperands,
- "Wrong number of operands", MD);
+ Check(NumBranchWeights == ExpectedNumOperands, "Wrong number of operands",
+ MD);
}
- for (unsigned i = Offset; i < MD->getNumOperands(); ++i) {
+ for (unsigned i = getBranchWeightOffset(MD); i < MD->getNumOperands();
+ ++i) {
auto &MDO = MD->getOperand(i);
Check(MDO, "second operand should not be null", MD);
Check(mdconst::dyn_extract<ConstantInt>(MDO),
diff --git a/llvm/lib/Transforms/Utils/MisExpect.cpp b/llvm/lib/Transforms/Utils/MisExpect.cpp
index 7592893..aef9d82 100644
--- a/llvm/lib/Transforms/Utils/MisExpect.cpp
+++ b/llvm/lib/Transforms/Utils/MisExpect.cpp
@@ -151,15 +151,9 @@ void verifyMisExpect(Instruction &I, ArrayRef<uint32_t> RealWeights,
uint64_t TotalBranchWeight =
LikelyBranchWeight + (UnlikelyBranchWeight * NumUnlikelyTargets);
- // FIXME: When we've addressed sample profiling, restore the assertion
- //
- // We cannot calculate branch probability if either of these invariants aren't
- // met. However, MisExpect diagnostics should not prevent code from compiling,
- // so we simply forgo emitting diagnostics here, and return early.
- // assert((TotalBranchWeight >= LikelyBranchWeight) && (TotalBranchWeight > 0)
- // && "TotalBranchWeight is less than the Likely branch weight");
- if ((TotalBranchWeight == 0) || (TotalBranchWeight <= LikelyBranchWeight))
- return;
+ // Failing this assert means that we have corrupted metadata.
+ assert((TotalBranchWeight >= LikelyBranchWeight) && (TotalBranchWeight > 0) &&
+ "TotalBranchWeight is less than the Likely branch weight");
// To determine our threshold value we need to obtain the branch probability
// for the weights added by llvm.expect and use that proportion to calculate
@@ -186,6 +180,13 @@ void verifyMisExpect(Instruction &I, ArrayRef<uint32_t> RealWeights,
void checkBackendInstrumentation(Instruction &I,
const ArrayRef<uint32_t> RealWeights) {
+ // Backend checking assumes any existing weight comes from an `llvm.expect`
+ // intrinsic. However, SampleProfiling + ThinLTO add branch weights multiple
+ // times, leading to an invalid assumption in our checking. Backend checks
+ // should only operate on branch weights that carry the "!expected" field,
+ // since they are guaranteed to be added by the LowerExpectIntrinsic pass.
+ if (!hasBranchWeightOrigin(I))
+ return;
SmallVector<uint32_t> ExpectedWeights;
if (!extractBranchWeights(I, ExpectedWeights))
return;