aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/IR/DiagnosticInfo.cpp11
-rw-r--r--llvm/lib/IR/LLVMContext.cpp14
-rw-r--r--llvm/lib/IR/LLVMContextImpl.h5
-rw-r--r--llvm/lib/Transforms/IPO/SampleProfile.cpp4
-rw-r--r--llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp3
-rw-r--r--llvm/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp10
-rw-r--r--llvm/lib/Transforms/Utils/CMakeLists.txt1
-rw-r--r--llvm/lib/Transforms/Utils/MisExpect.cpp234
8 files changed, 2 insertions, 280 deletions
diff --git a/llvm/lib/IR/DiagnosticInfo.cpp b/llvm/lib/IR/DiagnosticInfo.cpp
index 50fe682..f46f0fd 100644
--- a/llvm/lib/IR/DiagnosticInfo.cpp
+++ b/llvm/lib/IR/DiagnosticInfo.cpp
@@ -393,17 +393,6 @@ std::string DiagnosticInfoOptimizationBase::getMsg() const {
return OS.str();
}
-DiagnosticInfoMisExpect::DiagnosticInfoMisExpect(const Instruction *Inst,
- Twine &Msg)
- : DiagnosticInfoWithLocationBase(DK_MisExpect, DS_Warning,
- *Inst->getParent()->getParent(),
- Inst->getDebugLoc()),
- Msg(Msg) {}
-
-void DiagnosticInfoMisExpect::print(DiagnosticPrinter &DP) const {
- DP << getLocationStr() << ": " << getMsg();
-}
-
void OptimizationRemarkAnalysisFPCommute::anchor() {}
void OptimizationRemarkAnalysisAliasing::anchor() {}
diff --git a/llvm/lib/IR/LLVMContext.cpp b/llvm/lib/IR/LLVMContext.cpp
index df4a007..f4e917c 100644
--- a/llvm/lib/IR/LLVMContext.cpp
+++ b/llvm/lib/IR/LLVMContext.cpp
@@ -138,22 +138,10 @@ bool LLVMContext::getDiagnosticsHotnessRequested() const {
void LLVMContext::setDiagnosticsHotnessThreshold(Optional<uint64_t> Threshold) {
pImpl->DiagnosticsHotnessThreshold = Threshold;
}
-void LLVMContext::setMisExpectWarningRequested(bool Requested) {
- pImpl->MisExpectWarningRequested = Requested;
-}
-bool LLVMContext::getMisExpectWarningRequested() const {
- return pImpl->MisExpectWarningRequested;
-}
+
uint64_t LLVMContext::getDiagnosticsHotnessThreshold() const {
return pImpl->DiagnosticsHotnessThreshold.getValueOr(UINT64_MAX);
}
-void LLVMContext::setDiagnosticsMisExpectTolerance(
- Optional<uint64_t> Tolerance) {
- pImpl->DiagnosticsMisExpectTolerance = Tolerance;
-}
-uint64_t LLVMContext::getDiagnosticsMisExpectTolerance() const {
- return pImpl->DiagnosticsMisExpectTolerance.getValueOr(0);
-}
bool LLVMContext::isDiagnosticsHotnessThresholdSetFromPSI() const {
return !pImpl->DiagnosticsHotnessThreshold.hasValue();
diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h
index 0b39029..b87d285 100644
--- a/llvm/lib/IR/LLVMContextImpl.h
+++ b/llvm/lib/IR/LLVMContextImpl.h
@@ -1380,11 +1380,6 @@ public:
/// If threshold option is not specified, it is disabled (0) by default.
Optional<uint64_t> DiagnosticsHotnessThreshold = 0;
- /// The percentage of difference between profiling branch weights and
- // llvm.expect branch weights to tolerate when emiting MisExpect diagnostics
- Optional<uint64_t> DiagnosticsMisExpectTolerance = 0;
- bool MisExpectWarningRequested = false;
-
/// The specialized remark streamer used by LLVM's OptimizationRemarkEmitter.
std::unique_ptr<LLVMRemarkStreamer> LLVMRS;
diff --git a/llvm/lib/Transforms/IPO/SampleProfile.cpp b/llvm/lib/Transforms/IPO/SampleProfile.cpp
index 4bd7900..8232406 100644
--- a/llvm/lib/Transforms/IPO/SampleProfile.cpp
+++ b/llvm/lib/Transforms/IPO/SampleProfile.cpp
@@ -74,8 +74,6 @@
#include "llvm/Transforms/Instrumentation.h"
#include "llvm/Transforms/Utils/CallPromotionUtils.h"
#include "llvm/Transforms/Utils/Cloning.h"
-#include "llvm/Transforms/Utils/MisExpect.h"
-#include "llvm/Transforms/Utils/SampleProfileInference.h"
#include "llvm/Transforms/Utils/SampleProfileLoaderBaseImpl.h"
#include "llvm/Transforms/Utils/SampleProfileLoaderBaseUtil.h"
#include <algorithm>
@@ -1741,8 +1739,6 @@ void SampleProfileLoader::generateMDProfMetadata(Function &F) {
}
}
- misexpect::checkExpectAnnotations(*TI, Weights, /*IsFrontend=*/false);
-
uint64_t TempWeight;
// Only set weights if there is at least one non-zero weight.
// In any other case, let the analyzer set weights.
diff --git a/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp b/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp
index 35ea646..d421894 100644
--- a/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp
+++ b/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp
@@ -110,7 +110,6 @@
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Instrumentation.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
-#include "llvm/Transforms/Utils/MisExpect.h"
#include "llvm/Transforms/Utils/ModuleUtils.h"
#include <algorithm>
#include <cassert>
@@ -2118,8 +2117,6 @@ void llvm::setProfMetadata(Module *M, Instruction *TI,
dbgs() << W << " ";
} dbgs() << "\n";);
- misexpect::checkExpectAnnotations(*TI, Weights, /*IsFrontend=*/false);
-
TI->setMetadata(LLVMContext::MD_prof, MDB.createBranchWeights(Weights));
if (EmitBranchProbability) {
std::string BrCondStr = getBranchCondString(TI);
diff --git a/llvm/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp b/llvm/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp
index 88fad98..97c8f33 100644
--- a/llvm/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp
+++ b/llvm/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp
@@ -25,7 +25,6 @@
#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Transforms/Scalar.h"
-#include "llvm/Transforms/Utils/MisExpect.h"
using namespace llvm;
@@ -100,8 +99,6 @@ static bool handleSwitchExpect(SwitchInst &SI) {
uint64_t Index = (Case == *SI.case_default()) ? 0 : Case.getCaseIndex() + 1;
Weights[Index] = LikelyBranchWeightVal;
- misexpect::checkExpectAnnotations(SI, Weights, /*IsFrontend=*/true);
-
SI.setCondition(ArgValue);
SI.setMetadata(LLVMContext::MD_prof,
@@ -316,16 +313,13 @@ template <class BrSelInst> static bool handleBrSelExpect(BrSelInst &BSI) {
std::tie(LikelyBranchWeightVal, UnlikelyBranchWeightVal) =
getBranchWeight(Fn->getIntrinsicID(), CI, 2);
- SmallVector<uint32_t, 4> ExpectedWeights;
if ((ExpectedValue->getZExtValue() == ValueComparedTo) ==
(Predicate == CmpInst::ICMP_EQ)) {
Node =
MDB.createBranchWeights(LikelyBranchWeightVal, UnlikelyBranchWeightVal);
- ExpectedWeights = {LikelyBranchWeightVal, UnlikelyBranchWeightVal};
} else {
Node =
MDB.createBranchWeights(UnlikelyBranchWeightVal, LikelyBranchWeightVal);
- ExpectedWeights = {UnlikelyBranchWeightVal, LikelyBranchWeightVal};
}
if (CmpI)
@@ -333,8 +327,6 @@ template <class BrSelInst> static bool handleBrSelExpect(BrSelInst &BSI) {
else
BSI.setCondition(ArgValue);
- misexpect::checkFrontendInstrumentation(BSI, ExpectedWeights);
-
BSI.setMetadata(LLVMContext::MD_prof, Node);
return true;
@@ -415,7 +407,7 @@ public:
bool runOnFunction(Function &F) override { return lowerExpectIntrinsic(F); }
};
-} // namespace
+}
char LowerExpectIntrinsic::ID = 0;
INITIALIZE_PASS(LowerExpectIntrinsic, "lower-expect",
diff --git a/llvm/lib/Transforms/Utils/CMakeLists.txt b/llvm/lib/Transforms/Utils/CMakeLists.txt
index 3462f89..58eddb7 100644
--- a/llvm/lib/Transforms/Utils/CMakeLists.txt
+++ b/llvm/lib/Transforms/Utils/CMakeLists.txt
@@ -53,7 +53,6 @@ add_llvm_component_library(LLVMTransformUtils
MemoryTaggingSupport.cpp
Mem2Reg.cpp
MetaRenamer.cpp
- MisExpect.cpp
ModuleUtils.cpp
NameAnonGlobals.cpp
PredicateInfo.cpp
diff --git a/llvm/lib/Transforms/Utils/MisExpect.cpp b/llvm/lib/Transforms/Utils/MisExpect.cpp
deleted file mode 100644
index 044a2ca..0000000
--- a/llvm/lib/Transforms/Utils/MisExpect.cpp
+++ /dev/null
@@ -1,234 +0,0 @@
-//===--- MisExpect.cpp - Check the use of llvm.expect with PGO data -------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This contains code to emit warnings for potentially incorrect usage of the
-// llvm.expect intrinsic. This utility extracts the threshold values from
-// metadata associated with the instrumented Branch or Switch instruction. The
-// threshold values are then used to determine if a warning should be emmited.
-//
-// MisExpect's implementation relies on two assumptions about how branch weights
-// are managed in LLVM.
-//
-// 1) Frontend profiling weights are always in place before llvm.expect is
-// lowered in LowerExpectIntrinsic.cpp. Frontend based instrumentation therefore
-// needs to extract the branch weights and then compare them to the weights
-// being added by the llvm.expect intrinsic lowering.
-//
-// 2) Sampling and IR based profiles will *only* have branch weight metadata
-// before profiling data is consulted if they are from a lowered llvm.expect
-// intrinsic. These profiles thus always extract the expected weights and then
-// compare them to the weights collected during profiling to determine if a
-// diagnostic message is warranted.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Transforms/Utils/MisExpect.h"
-#include "llvm/ADT/Twine.h"
-#include "llvm/Analysis/OptimizationRemarkEmitter.h"
-#include "llvm/IR/Constants.h"
-#include "llvm/IR/DiagnosticInfo.h"
-#include "llvm/IR/Instruction.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/IR/LLVMContext.h"
-#include "llvm/Support/BranchProbability.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/FormatVariadic.h"
-#include <cstdint>
-#include <functional>
-#include <numeric>
-
-#define DEBUG_TYPE "misexpect"
-
-using namespace llvm;
-using namespace misexpect;
-
-namespace llvm {
-
-// Command line option to enable/disable the warning when profile data suggests
-// a mismatch with the use of the llvm.expect intrinsic
-static cl::opt<bool> PGOWarnMisExpect(
- "pgo-warn-misexpect", cl::init(false), cl::Hidden,
- cl::desc("Use this option to turn on/off "
- "warnings about incorrect usage of llvm.expect intrinsics."));
-
-static cl::opt<unsigned> MisExpectTolerance(
- "misexpect-tolerance", cl::init(0),
- cl::desc("Prevents emiting diagnostics when profile counts are "
- "within N% of the threshold.."));
-
-} // namespace llvm
-
-namespace {
-
-bool isMisExpectDiagEnabled(LLVMContext &Ctx) {
- return PGOWarnMisExpect || Ctx.getMisExpectWarningRequested();
-}
-
-uint64_t getMisExpectTolerance(LLVMContext &Ctx) {
- return std::max(static_cast<uint64_t>(MisExpectTolerance),
- Ctx.getDiagnosticsMisExpectTolerance());
-}
-
-Instruction *getInstCondition(Instruction *I) {
- assert(I != nullptr && "MisExpect target Instruction cannot be nullptr");
- Instruction *Ret = nullptr;
- if (auto *B = dyn_cast<BranchInst>(I)) {
- Ret = dyn_cast<Instruction>(B->getCondition());
- }
- // TODO: Find a way to resolve condition location for switches
- // Using the condition of the switch seems to often resolve to an earlier
- // point in the program, i.e. the calculation of the switch condition, rather
- // than the switch's location in the source code. Thus, we should use the
- // instruction to get source code locations rather than the condition to
- // improve diagnostic output, such as the caret. If the same problem exists
- // for branch instructions, then we should remove this function and directly
- // use the instruction
- //
- else if (auto *S = dyn_cast<SwitchInst>(I)) {
- Ret = dyn_cast<Instruction>(S->getCondition());
- }
- return Ret ? Ret : I;
-}
-
-void emitMisexpectDiagnostic(Instruction *I, LLVMContext &Ctx,
- uint64_t ProfCount, uint64_t TotalCount) {
- double PercentageCorrect = (double)ProfCount / TotalCount;
- auto PerString =
- formatv("{0:P} ({1} / {2})", PercentageCorrect, ProfCount, TotalCount);
- auto RemStr = formatv(
- "Potential performance regression from use of the llvm.expect intrinsic: "
- "Annotation was correct on {0} of profiled executions.",
- PerString);
- Twine Msg(PerString);
- Instruction *Cond = getInstCondition(I);
- if (isMisExpectDiagEnabled(Ctx))
- Ctx.diagnose(DiagnosticInfoMisExpect(Cond, Msg));
- OptimizationRemarkEmitter ORE(I->getParent()->getParent());
- ORE.emit(OptimizationRemark(DEBUG_TYPE, "misexpect", Cond) << RemStr.str());
-}
-
-} // namespace
-
-namespace llvm {
-namespace misexpect {
-
-// Helper function to extract branch weights into a vector
-Optional<SmallVector<uint32_t, 4>> extractWeights(Instruction *I,
- LLVMContext &Ctx) {
- assert(I && "MisExpect::extractWeights given invalid pointer");
-
- auto *ProfileData = I->getMetadata(LLVMContext::MD_prof);
- if (!ProfileData)
- return None;
-
- unsigned NOps = ProfileData->getNumOperands();
- if (NOps < 3)
- return None;
-
- auto *ProfDataName = dyn_cast<MDString>(ProfileData->getOperand(0));
- if (!ProfDataName || !ProfDataName->getString().equals("branch_weights"))
- return None;
-
- SmallVector<uint32_t, 4> Weights(NOps - 1);
- for (unsigned Idx = 1; Idx < NOps; Idx++) {
- ConstantInt *Value =
- mdconst::dyn_extract<ConstantInt>(ProfileData->getOperand(Idx));
- uint32_t V = Value->getZExtValue();
- Weights[Idx - 1] = V;
- }
-
- return Weights;
-}
-
-void verifyMisExpect(Instruction &I, ArrayRef<uint32_t> RealWeights,
- ArrayRef<uint32_t> ExpectedWeights) {
- // 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
- // against.
- uint64_t LikelyBranchWeight = 0,
- UnlikelyBranchWeight = std::numeric_limits<uint32_t>::max();
- size_t MaxIndex = 0;
- for (size_t Idx = 0, End = ExpectedWeights.size(); Idx < End; Idx++) {
- uint32_t V = ExpectedWeights[Idx];
- if (LikelyBranchWeight < V) {
- LikelyBranchWeight = V;
- MaxIndex = Idx;
- }
- if (UnlikelyBranchWeight > V) {
- UnlikelyBranchWeight = V;
- }
- }
-
- const uint64_t ProfiledWeight = RealWeights[MaxIndex];
- const uint64_t RealWeightsTotal =
- std::accumulate(RealWeights.begin(), RealWeights.end(), (uint64_t)0,
- std::plus<uint64_t>());
- const uint64_t NumUnlikelyTargets = RealWeights.size() - 1;
-
- const uint64_t TotalBranchWeight =
- LikelyBranchWeight + (UnlikelyBranchWeight * NumUnlikelyTargets);
-
- // 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
- // our threshold based on the collected profile data.
- const llvm::BranchProbability LikelyProbablilty(LikelyBranchWeight,
- TotalBranchWeight);
- uint64_t ScaledThreshold = LikelyProbablilty.scale(RealWeightsTotal);
-
- // clamp tolerance range to [0, 100)
- auto Tolerance = getMisExpectTolerance(I.getContext());
- if (Tolerance < 0)
- Tolerance = 0;
- else if (MisExpectTolerance > 99)
- Tolerance = 99;
-
- // Allow users to relax checking by N% i.e., if they use a 5% tolerance,
- // then we check against 0.95*ScaledThreshold
- if (Tolerance > 0)
- ScaledThreshold *= (1.0 - Tolerance / 100.0);
-
- // When the profile weight is below the threshold, we emit the diagnostic
- if (ProfiledWeight < ScaledThreshold)
- emitMisexpectDiagnostic(&I, I.getContext(), ProfiledWeight,
- RealWeightsTotal);
-}
-
-void checkBackendInstrumentation(Instruction &I,
- const ArrayRef<uint32_t> RealWeights) {
- auto ExpectedWeightsOpt = extractWeights(&I, I.getContext());
- if (!ExpectedWeightsOpt.hasValue())
- return;
- auto ExpectedWeights = ExpectedWeightsOpt.getValue();
- verifyMisExpect(I, RealWeights, ExpectedWeights);
-}
-
-void checkFrontendInstrumentation(Instruction &I,
- const ArrayRef<uint32_t> ExpectedWeights) {
- auto RealWeightsOpt = extractWeights(&I, I.getContext());
- if (!RealWeightsOpt.hasValue())
- return;
- auto RealWeights = RealWeightsOpt.getValue();
- verifyMisExpect(I, RealWeights, ExpectedWeights);
-}
-
-void checkExpectAnnotations(Instruction &I,
- const ArrayRef<uint32_t> ExistingWeights,
- bool IsFrontendInstr) {
- if (IsFrontendInstr) {
- checkFrontendInstrumentation(I, ExistingWeights);
- } else {
- checkBackendInstrumentation(I, ExistingWeights);
- }
-}
-
-} // namespace misexpect
-} // namespace llvm
-#undef DEBUG_TYPE