diff options
author | Mircea Trofin <mtrofin@google.com> | 2025-09-10 15:34:35 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-09-10 15:34:35 -0700 |
commit | f2d827c444d07b722a94689b427d6ad2d1c6b1b7 (patch) | |
tree | 0889e7d5698d24a9f00b81a4d02a1e49357b45b8 /llvm/lib/IR/Verifier.cpp | |
parent | 613caa909c78f707e88960723c6a98364656a926 (diff) | |
download | llvm-f2d827c444d07b722a94689b427d6ad2d1c6b1b7.zip llvm-f2d827c444d07b722a94689b427d6ad2d1c6b1b7.tar.gz llvm-f2d827c444d07b722a94689b427d6ad2d1c6b1b7.tar.bz2 |
[profcheck] Require `unknown` metadata have an origin parameter (#157594)
Rather than passes using `!prof = !{!”unknown”}`for cases where don’t have enough information to emit profile values, this patch captures the pass (or some other information) that can help diagnostics - i.e. `!{!”unknown”, !”some-pass-name”}`.
For example, suppose we emitted a `select` with the unknown metadata, and, later, end up needing to lower that to a conditional branch. If we observe (via sample profiling, for example) that the branch is biased and would have benefitted from a valid profile, the extra information can help speed up debugging.
We can also (in a subsequent pass) generate optimization remarks about such lowered selects, with a similar aim - identify patterns lowering to `select` that may be worth some extra investment in extracting a more precise profile.
Diffstat (limited to 'llvm/lib/IR/Verifier.cpp')
-rw-r--r-- | llvm/lib/IR/Verifier.cpp | 25 |
1 files changed, 18 insertions, 7 deletions
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 81a5372..7d362ce 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -631,7 +631,7 @@ private: void verifyFunctionAttrs(FunctionType *FT, AttributeList Attrs, const Value *V, bool IsIntrinsic, bool IsInlineAsm); void verifyFunctionMetadata(ArrayRef<std::pair<unsigned, MDNode *>> MDs); - + void verifyUnknownProfileMetadata(MDNode *MD); void visitConstantExprsRecursively(const Constant *EntryC); void visitConstantExpr(const ConstantExpr *CE); void visitConstantPtrAuth(const ConstantPtrAuth *CPA); @@ -2515,19 +2515,31 @@ void Verifier::verifyFunctionAttrs(FunctionType *FT, AttributeList Attrs, V); } } +void Verifier::verifyUnknownProfileMetadata(MDNode *MD) { + Check(MD->getNumOperands() == 2, + "'unknown' !prof should have a single additional operand", MD); + auto *PassName = dyn_cast<MDString>(MD->getOperand(1)); + Check(PassName != nullptr, + "'unknown' !prof should have an additional operand of type " + "string"); + Check(!PassName->getString().empty(), + "the 'unknown' !prof operand should not be an empty string"); +} void Verifier::verifyFunctionMetadata( ArrayRef<std::pair<unsigned, MDNode *>> MDs) { for (const auto &Pair : MDs) { if (Pair.first == LLVMContext::MD_prof) { MDNode *MD = Pair.second; + Check(MD->getNumOperands() >= 2, + "!prof annotations should have no less than 2 operands", MD); // We may have functions that are synthesized by the compiler, e.g. in // WPD, that we can't currently determine the entry count. - if (isExplicitlyUnknownProfileMetadata(*MD)) + if (MD->getOperand(0).equalsStr( + MDProfLabels::UnknownBranchWeightsMarker)) { + verifyUnknownProfileMetadata(MD); continue; - - Check(MD->getNumOperands() >= 2, - "!prof annotations should have no less than 2 operands", MD); + } // Check first operand. Check(MD->getOperand(0) != nullptr, "first operand should not be null", @@ -5054,8 +5066,7 @@ void Verifier::visitProfMetadata(Instruction &I, MDNode *MD) { "'unknown' !prof should only appear on instructions on which " "'branch_weights' would", MD); - Check(MD->getNumOperands() == 1, - "'unknown' !prof should have no additional operands", MD); + verifyUnknownProfileMetadata(MD); return; } |