diff --git a/llvm/include/llvm/Target/TargetOptions.h b/llvm/include/llvm/Target/TargetOptions.h --- a/llvm/include/llvm/Target/TargetOptions.h +++ b/llvm/include/llvm/Target/TargetOptions.h @@ -363,6 +363,7 @@ /// When set to true, enable MisExpect Diagnostics /// By default, it is set to false unsigned MisExpect : 1; + unsigned MissingAnnotations : 1; /// Name of the stack usage file (i.e., .su file) if user passes /// -fstack-usage. If empty, it can be implied that -fstack-usage is not diff --git a/llvm/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp b/llvm/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp --- a/llvm/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp +++ b/llvm/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp @@ -21,6 +21,7 @@ #include "llvm/IR/Intrinsics.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/MDBuilder.h" +#include "llvm/IR/ProfDataUtils.h" #include "llvm/InitializePasses.h" #include "llvm/Pass.h" #include "llvm/Support/CommandLine.h" @@ -361,8 +362,13 @@ static bool handleBranchExpect(BranchInst &BI) { if (BI.isUnconditional()) return false; - - return handleBrSelExpect(BI); + auto ret = handleBrSelExpect(BI); + if (!ret) { + SmallVector Weights; + if (extractBranchWeights(BI, Weights)) + misexpect::checkMissingAnnotations(BI, Weights, /*isFrontend=*/true); + } + return ret; } static bool lowerExpectIntrinsic(Function &F) { @@ -376,6 +382,11 @@ } else if (SwitchInst *SI = dyn_cast(BB.getTerminator())) { if (handleSwitchExpect(*SI)) ExpectIntrinsicsHandled++; + else { + SmallVector Weights; + if (extractBranchWeights(*SI, Weights)) + misexpect::checkMissingAnnotations(*SI, Weights, /*isFrontend=*/true); + } } // Remove llvm.expect intrinsics. Iterate backwards in order diff --git a/llvm/lib/Transforms/Utils/MisExpect.cpp b/llvm/lib/Transforms/Utils/MisExpect.cpp --- a/llvm/lib/Transforms/Utils/MisExpect.cpp +++ b/llvm/lib/Transforms/Utils/MisExpect.cpp @@ -64,7 +64,7 @@ cl::desc("Prevents emiting diagnostics when profile counts are " "within N% of the threshold..")); -// Command line option to enable/disable the Remparks when profile data suggests +// Command line option to enable/disable the Remarks when profile data suggests // that the llvm.expect intrinsic may be profitable static cl::opt PGOMissingAnnotations("pgo-missing-annotations", cl::init(false), @@ -173,8 +173,9 @@ "Extremely hot condition. Consider adding llvm.expect intrinsic"; Instruction *Cond = getInstCondition(I); OptimizationRemarkEmitter ORE(I->getParent()->getParent()); - ORE.emit(OptimizationRemark("missing-annotation", "missing-annotation", Cond) - << RemStr); + ORE.emit( + OptimizationRemark("missing-annotations", "missing-annotations", Cond) + << RemStr); } uint64_t totalWeight(const ArrayRef Weights) { @@ -235,7 +236,7 @@ // To determine if we emit a diagnostic, we need to compare the branch weights // from the profile to those added by the llvm.expect intrinsic. // So first, we extract the "likely" and "unlikely" weights from - // ExpectedWeights And determine the correct weight in the profile to compare + // ExpectedWeights and determine the correct weight in the profile to compare // against. uint64_t LikelyBranchWeight = 0, UnlikelyBranchWeight = std::numeric_limits::max(); @@ -285,7 +286,7 @@ void verifyMissingAnnotations(Instruction &I, ArrayRef RealWeights) { // To determine if we emit a diagnostic, we need to compare the branch weights // from the profile to those that would be added by the llvm.expect intrinsic. - // And compare it to the real profile to see if it would be profitable. + // to see if adding an annotation would be profitable. uint32_t ProfiledWeight = *std::max_element(RealWeights.begin(), RealWeights.end()); @@ -300,15 +301,14 @@ void checkMissingAnnotations(Instruction &I, const ArrayRef ExistingWeights, bool IsFrontendInstr) { - - // TODO: Ironically, this is probably a branch that should be marked UNLIKELY // exit early if these diagnostics weren't requested - if (!isAnnotationDiagEnabled(I.getContext())) + if (LLVM_LIKELY(!isAnnotationDiagEnabled(I.getContext()))) return; if (IsFrontendInstr) { - // TODO: Fronend checking will have to be thought through, since we need + // TODO: Frontend checking will have to be thought through, since we need // to do the check on branches that don't have expect intrinsics + verifyMissingAnnotations(I, ExistingWeights); // auto RealWeightsOpt = extractWeights(&I, I.getContext()); // if (!RealWeightsOpt) diff --git a/llvm/test/Transforms/PGOProfile/missing-annotation.ll b/llvm/test/Transforms/PGOProfile/missing-annotation.ll --- a/llvm/test/Transforms/PGOProfile/missing-annotation.ll +++ b/llvm/test/Transforms/PGOProfile/missing-annotation.ll @@ -3,7 +3,7 @@ ; RUN: llvm-profdata merge %S/Inputs/misexpect-branch-correct.proftext -o %t.profdata -; RUN: opt < %s -passes="function(lower-expect),pgo-instr-use" -pgo-test-profile-file=%t.profdata -pgo-missing-annotations -pass-remarks=missing-annotation -S 2>&1 | FileCheck %s --check-prefix=MISSING_ANNOTATION +; RUN: opt < %s -passes="function(lower-expect),pgo-instr-use" -pgo-test-profile-file=%t.profdata -pgo-missing-annotations -pass-remarks=missing-annotations -S 2>&1 | FileCheck %s --check-prefix=MISSING_ANNOTATION ; MISSING_ANNOTATION: remark: misexpect-branch.c:22:0: Extremely hot condition. Consider adding llvm.expect intrinsic