diff options
author | Mircea Trofin <mtrofin@google.com> | 2025-06-30 16:57:11 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-06-30 16:57:11 -0700 |
commit | d2500e639b641b0cfdd1564cc6ff4705b118f10c (patch) | |
tree | 18ec37f4aaf25a2008d6bee8b81049518492be42 /llvm/lib/IR/Verifier.cpp | |
parent | 12409a18f609f965fbd40aba77a0b50dcdba147f (diff) | |
download | llvm-d2500e639b641b0cfdd1564cc6ff4705b118f10c.zip llvm-d2500e639b641b0cfdd1564cc6ff4705b118f10c.tar.gz llvm-d2500e639b641b0cfdd1564cc6ff4705b118f10c.tar.bz2 |
[pgo] add means to specify "unknown" MD_prof (#145578)
This PR is part of https://discourse.llvm.org/t/rfc-profile-information-propagation-unittesting/73595
In a slight departure from the RFC, instead of a brand-new `MD_prof_unknown` kind, this adds a first operand to `MD_prof` metadata. This makes it easy to replace with valid metadata (only one `MD_prof`), otherwise sites inserting valid `MD_prof` would also have to check to remove the `unknown` one.
The patch just introduces the notion and fixes the verifier accordingly. Existing APIs working (esp. reading) `MD_prof` will be updated subsequently.
Diffstat (limited to 'llvm/lib/IR/Verifier.cpp')
-rw-r--r-- | llvm/lib/IR/Verifier.cpp | 56 |
1 files changed, 39 insertions, 17 deletions
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 853f3b4..227afe2b 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -2527,6 +2527,12 @@ void Verifier::verifyFunctionMetadata( for (const auto &Pair : MDs) { if (Pair.first == LLVMContext::MD_prof) { MDNode *MD = Pair.second; + if (isExplicitlyUnknownBranchWeightsMetadata(*MD)) { + CheckFailed("'unknown' !prof metadata should appear only on " + "instructions supporting the 'branch_weights' metadata", + MD); + continue; + } Check(MD->getNumOperands() >= 2, "!prof annotations should have no less than 2 operands", MD); @@ -4989,9 +4995,24 @@ void Verifier::visitDereferenceableMetadata(Instruction& I, MDNode* MD) { } void Verifier::visitProfMetadata(Instruction &I, MDNode *MD) { - Check(MD->getNumOperands() >= 2, - "!prof annotations should have no less than 2 operands", MD); - + auto GetBranchingTerminatorNumOperands = [&]() { + unsigned ExpectedNumOperands = 0; + if (BranchInst *BI = dyn_cast<BranchInst>(&I)) + ExpectedNumOperands = BI->getNumSuccessors(); + else if (SwitchInst *SI = dyn_cast<SwitchInst>(&I)) + ExpectedNumOperands = SI->getNumSuccessors(); + else if (isa<CallInst>(&I)) + ExpectedNumOperands = 1; + else if (IndirectBrInst *IBI = dyn_cast<IndirectBrInst>(&I)) + ExpectedNumOperands = IBI->getNumDestinations(); + else if (isa<SelectInst>(&I)) + ExpectedNumOperands = 2; + else if (CallBrInst *CI = dyn_cast<CallBrInst>(&I)) + ExpectedNumOperands = CI->getNumSuccessors(); + return ExpectedNumOperands; + }; + Check(MD->getNumOperands() >= 1, + "!prof annotations should have at least 1 operand", MD); // Check first operand. Check(MD->getOperand(0) != nullptr, "first operand should not be null", MD); Check(isa<MDString>(MD->getOperand(0)), @@ -4999,6 +5020,19 @@ void Verifier::visitProfMetadata(Instruction &I, MDNode *MD) { MDString *MDS = cast<MDString>(MD->getOperand(0)); StringRef ProfName = MDS->getString(); + if (ProfName == MDProfLabels::UnknownBranchWeightsMarker) { + Check(GetBranchingTerminatorNumOperands() != 0 || isa<InvokeInst>(I), + "'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); + return; + } + + Check(MD->getNumOperands() >= 2, + "!prof annotations should have no less than 2 operands", MD); + // Check consistency of !prof branch_weights metadata. if (ProfName == MDProfLabels::BranchWeights) { unsigned NumBranchWeights = getNumBranchWeights(*MD); @@ -5006,20 +5040,8 @@ void Verifier::visitProfMetadata(Instruction &I, MDNode *MD) { Check(NumBranchWeights == 1 || NumBranchWeights == 2, "Wrong number of InvokeInst branch_weights operands", MD); } else { - unsigned ExpectedNumOperands = 0; - if (BranchInst *BI = dyn_cast<BranchInst>(&I)) - ExpectedNumOperands = BI->getNumSuccessors(); - else if (SwitchInst *SI = dyn_cast<SwitchInst>(&I)) - ExpectedNumOperands = SI->getNumSuccessors(); - else if (isa<CallInst>(&I)) - ExpectedNumOperands = 1; - else if (IndirectBrInst *IBI = dyn_cast<IndirectBrInst>(&I)) - ExpectedNumOperands = IBI->getNumDestinations(); - else if (isa<SelectInst>(&I)) - ExpectedNumOperands = 2; - else if (CallBrInst *CI = dyn_cast<CallBrInst>(&I)) - ExpectedNumOperands = CI->getNumSuccessors(); - else + const unsigned ExpectedNumOperands = GetBranchingTerminatorNumOperands(); + if (ExpectedNumOperands == 0) CheckFailed("!prof branch_weights are not allowed for this instruction", MD); |