|
20 | 20 | #include "llvm/IR/MDBuilder.h" |
21 | 21 | #include "llvm/IR/ProfDataUtils.h" |
22 | 22 | #include "llvm/Support/BranchProbability.h" |
| 23 | +#include "llvm/Support/CommandLine.h" |
23 | 24 |
|
24 | 25 | using namespace llvm; |
| 26 | +static cl::opt<int64_t> |
| 27 | + DefaultFunctionEntryCount("profcheck-default-fct-entry-count", |
| 28 | + cl::init(1000)); |
25 | 29 | namespace { |
26 | 30 | class ProfileInjector { |
27 | 31 | Function &F; |
@@ -63,6 +67,17 @@ bool ProfileInjector::inject() { |
63 | 67 | // will get the same BPI it does if the injector wasn't running. |
64 | 68 | auto &BPI = FAM.getResult<BranchProbabilityAnalysis>(F); |
65 | 69 |
|
| 70 | + // Inject a function count if there's none. It's reasonable for a pass to |
| 71 | + // want to clear the MD_prof of a function with zero entry count. From a |
| 72 | + // metadata economy perspective, if a profile comes empty for a function, it's |
| 73 | + // cheaper to assign it the 0-entry count explicitly than to mark every branch |
| 74 | + // as cold. |
| 75 | + if (!F.getEntryCount(true)) |
| 76 | + F.setEntryCount(DefaultFunctionEntryCount); |
| 77 | + // If there is an entry count that's 0, then don't bother injecting. We won't |
| 78 | + // verify these either. |
| 79 | + if (F.getEntryCount(true)->getCount() == 0) |
| 80 | + return false; |
66 | 81 | bool Changed = false; |
67 | 82 | for (auto &BB : F) { |
68 | 83 | auto *Term = getTerminatorBenefitingFromMDProf(BB); |
@@ -119,11 +134,19 @@ PreservedAnalyses ProfileInjectorPass::run(Function &F, |
119 | 134 |
|
120 | 135 | PreservedAnalyses ProfileVerifierPass::run(Function &F, |
121 | 136 | FunctionAnalysisManager &FAM) { |
| 137 | + if (!F.getEntryCount(true)) { |
| 138 | + F.getContext().emitError("Profile verification failed: function entry " |
| 139 | + "count missing (set to 0 if cold)"); |
| 140 | + return PreservedAnalyses::all(); |
| 141 | + } |
| 142 | + if (F.getEntryCount(true)->getCount() == 0) |
| 143 | + return PreservedAnalyses::all(); |
122 | 144 | for (const auto &BB : F) |
123 | 145 | if (const auto *Term = |
124 | 146 | ProfileInjector::getTerminatorBenefitingFromMDProf(BB)) |
125 | 147 | if (!Term->getMetadata(LLVMContext::MD_prof)) |
126 | | - F.getContext().emitError("Profile verification failed"); |
| 148 | + F.getContext().emitError( |
| 149 | + "Profile verification failed: branch annotation missing"); |
127 | 150 |
|
128 | | - return PreservedAnalyses::none(); |
| 151 | + return PreservedAnalyses::all(); |
129 | 152 | } |
0 commit comments