diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/IR/DiagnosticInfo.cpp | 11 | ||||
| -rw-r--r-- | llvm/lib/IR/MDBuilder.cpp | 12 | ||||
| -rw-r--r-- | llvm/lib/Transforms/IPO/SampleProfile.cpp | 3 | ||||
| -rw-r--r-- | llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp | 4 | ||||
| -rw-r--r-- | llvm/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp | 31 | ||||
| -rw-r--r-- | llvm/lib/Transforms/Utils/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | llvm/lib/Transforms/Utils/MisExpect.cpp | 177 |
7 files changed, 8 insertions, 231 deletions
diff --git a/llvm/lib/IR/DiagnosticInfo.cpp b/llvm/lib/IR/DiagnosticInfo.cpp index 99d5aec3f04..4a8e3cca349 100644 --- a/llvm/lib/IR/DiagnosticInfo.cpp +++ b/llvm/lib/IR/DiagnosticInfo.cpp @@ -370,16 +370,5 @@ 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/MDBuilder.cpp b/llvm/lib/IR/MDBuilder.cpp index 7bdb85ace52..14bcb3a29b0 100644 --- a/llvm/lib/IR/MDBuilder.cpp +++ b/llvm/lib/IR/MDBuilder.cpp @@ -309,15 +309,3 @@ MDNode *MDBuilder::createIrrLoopHeaderWeight(uint64_t Weight) { }; return MDNode::get(Context, Vals); } - -MDNode *MDBuilder::createMisExpect(uint64_t Index, uint64_t LikleyWeight, - uint64_t UnlikleyWeight) { - auto *IntType = Type::getInt64Ty(Context); - Metadata *Vals[] = { - createString("misexpect"), - createConstant(ConstantInt::get(IntType, Index)), - createConstant(ConstantInt::get(IntType, LikleyWeight)), - createConstant(ConstantInt::get(IntType, UnlikleyWeight)), - }; - return MDNode::get(Context, Vals); -} diff --git a/llvm/lib/Transforms/IPO/SampleProfile.cpp b/llvm/lib/Transforms/IPO/SampleProfile.cpp index d0cf63b35f4..eb4ddfd179b 100644 --- a/llvm/lib/Transforms/IPO/SampleProfile.cpp +++ b/llvm/lib/Transforms/IPO/SampleProfile.cpp @@ -72,7 +72,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 <algorithm> #include <cassert> #include <cstdint> @@ -1447,8 +1446,6 @@ void SampleProfileLoader::propagateWeights(Function &F) { } } - misexpect::verifyMisExpect(TI, Weights, TI->getContext()); - 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 c8cf1805c66..73a91d909a9 100644 --- a/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp +++ b/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp @@ -108,7 +108,6 @@ #include "llvm/Transforms/Instrumentation.h" #include "llvm/Transforms/Instrumentation/PGOInstrumentation.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" -#include "llvm/Transforms/Utils/MisExpect.h" #include <algorithm> #include <cassert> #include <cstdint> @@ -1777,9 +1776,6 @@ void llvm::setProfMetadata(Module *M, Instruction *TI, : Weights) { dbgs() << W << " "; } dbgs() << "\n";); - - misexpect::verifyMisExpect(TI, Weights, TI->getContext()); - 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 cdb1d790667..0d67c0d740e 100644 --- a/llvm/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp +++ b/llvm/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp @@ -26,7 +26,6 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Transforms/Scalar.h" -#include "llvm/Transforms/Utils/MisExpect.h" using namespace llvm; @@ -72,20 +71,15 @@ static bool handleSwitchExpect(SwitchInst &SI) { unsigned n = SI.getNumCases(); // +1 for default case. SmallVector<uint32_t, 16> Weights(n + 1, UnlikelyBranchWeight); - uint64_t Index = (Case == *SI.case_default()) ? 0 : Case.getCaseIndex() + 1; - Weights[Index] = LikelyBranchWeight; - - SI.setMetadata( - LLVMContext::MD_misexpect, - MDBuilder(CI->getContext()) - .createMisExpect(Index, LikelyBranchWeight, UnlikelyBranchWeight)); - - SI.setCondition(ArgValue); - misexpect::checkFrontendInstrumentation(SI); + if (Case == *SI.case_default()) + Weights[0] = LikelyBranchWeight; + else + Weights[Case.getCaseIndex() + 1] = LikelyBranchWeight; SI.setMetadata(LLVMContext::MD_prof, MDBuilder(CI->getContext()).createBranchWeights(Weights)); + SI.setCondition(ArgValue); return true; } @@ -286,28 +280,19 @@ template <class BrSelInst> static bool handleBrSelExpect(BrSelInst &BSI) { MDBuilder MDB(CI->getContext()); MDNode *Node; - MDNode *ExpNode; if ((ExpectedValue->getZExtValue() == ValueComparedTo) == - (Predicate == CmpInst::ICMP_EQ)) { + (Predicate == CmpInst::ICMP_EQ)) Node = MDB.createBranchWeights(LikelyBranchWeight, UnlikelyBranchWeight); - ExpNode = MDB.createMisExpect(0, LikelyBranchWeight, UnlikelyBranchWeight); - } else { + else Node = MDB.createBranchWeights(UnlikelyBranchWeight, LikelyBranchWeight); - ExpNode = MDB.createMisExpect(1, LikelyBranchWeight, UnlikelyBranchWeight); - } - BSI.setMetadata(LLVMContext::MD_misexpect, ExpNode); + BSI.setMetadata(LLVMContext::MD_prof, Node); if (CmpI) CmpI->setOperand(0, ArgValue); else BSI.setCondition(ArgValue); - - misexpect::checkFrontendInstrumentation(BSI); - - BSI.setMetadata(LLVMContext::MD_prof, Node); - return true; } diff --git a/llvm/lib/Transforms/Utils/CMakeLists.txt b/llvm/lib/Transforms/Utils/CMakeLists.txt index 115f543a8ec..c232aa6223c 100644 --- a/llvm/lib/Transforms/Utils/CMakeLists.txt +++ b/llvm/lib/Transforms/Utils/CMakeLists.txt @@ -40,7 +40,6 @@ add_llvm_library(LLVMTransformUtils LowerSwitch.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 26d3402bd27..00000000000 --- a/llvm/lib/Transforms/Utils/MisExpect.cpp +++ /dev/null @@ -1,177 +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 metadata is generated when llvm.expect intrinsics are lowered see -// LowerExpectIntrinsic.cpp -// -//===----------------------------------------------------------------------===// - -#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/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.")); - -} // namespace llvm - -namespace { - -Instruction *getOprndOrInst(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 switches 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 = I; - //} - 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 = getOprndOrInst(I); - if (PGOWarnMisExpect) - Ctx.diagnose(DiagnosticInfoMisExpect(Cond, Msg)); - OptimizationRemarkEmitter ORE(I->getParent()->getParent()); - ORE.emit(OptimizationRemark(DEBUG_TYPE, "misexpect", Cond) << RemStr.str()); -} - -} // namespace - -namespace llvm { -namespace misexpect { - -void verifyMisExpect(Instruction *I, const SmallVector<uint32_t, 4> &Weights, - LLVMContext &Ctx) { - if (auto *MisExpectData = I->getMetadata(LLVMContext::MD_misexpect)) { - auto *MisExpectDataName = dyn_cast<MDString>(MisExpectData->getOperand(0)); - if (MisExpectDataName && - MisExpectDataName->getString().equals("misexpect")) { - LLVM_DEBUG(llvm::dbgs() << "------------------\n"); - LLVM_DEBUG(llvm::dbgs() - << "Function: " << I->getFunction()->getName() << "\n"); - LLVM_DEBUG(llvm::dbgs() << "Instruction: " << *I << ":\n"); - LLVM_DEBUG(for (int Idx = 0, Size = Weights.size(); Idx < Size; ++Idx) { - llvm::dbgs() << "Weights[" << Idx << "] = " << Weights[Idx] << "\n"; - }); - - // extract values from misexpect metadata - const auto *IndexCint = - mdconst::dyn_extract<ConstantInt>(MisExpectData->getOperand(1)); - const auto *LikelyCInt = - mdconst::dyn_extract<ConstantInt>(MisExpectData->getOperand(2)); - const auto *UnlikelyCInt = - mdconst::dyn_extract<ConstantInt>(MisExpectData->getOperand(3)); - - if (!IndexCint || !LikelyCInt || !UnlikelyCInt) - return; - - const uint64_t Index = IndexCint->getZExtValue(); - const uint64_t LikelyBranchWeight = LikelyCInt->getZExtValue(); - const uint64_t UnlikelyBranchWeight = UnlikelyCInt->getZExtValue(); - const uint64_t ProfileCount = Weights[Index]; - const uint64_t CaseTotal = std::accumulate( - Weights.begin(), Weights.end(), (uint64_t)0, std::plus<uint64_t>()); - const uint64_t NumUnlikelyTargets = Weights.size() - 1; - - const uint64_t TotalBranchWeight = - LikelyBranchWeight + (UnlikelyBranchWeight * NumUnlikelyTargets); - - const llvm::BranchProbability LikelyThreshold(LikelyBranchWeight, - TotalBranchWeight); - uint64_t ScaledThreshold = LikelyThreshold.scale(CaseTotal); - - LLVM_DEBUG(llvm::dbgs() - << "Unlikely Targets: " << NumUnlikelyTargets << ":\n"); - LLVM_DEBUG(llvm::dbgs() << "Profile Count: " << ProfileCount << ":\n"); - LLVM_DEBUG(llvm::dbgs() - << "Scaled Threshold: " << ScaledThreshold << ":\n"); - LLVM_DEBUG(llvm::dbgs() << "------------------\n"); - if (ProfileCount < ScaledThreshold) - emitMisexpectDiagnostic(I, Ctx, ProfileCount, CaseTotal); - } - } -} - -void checkFrontendInstrumentation(Instruction &I) { - if (auto *MD = I.getMetadata(LLVMContext::MD_prof)) { - unsigned NOps = MD->getNumOperands(); - - // Only emit misexpect diagnostics if at least 2 branch weights are present. - // Less than 2 branch weights means that the profiling metadata is: - // 1) incorrect/corrupted - // 2) not branch weight metadata - // 3) completely deterministic - // In these cases we should not emit any diagnostic related to misexpect. - if (NOps < 3) - return; - - // Operand 0 is a string tag "branch_weights" - if (MDString *Tag = cast<MDString>(MD->getOperand(0))) { - if (Tag->getString().equals("branch_weights")) { - SmallVector<uint32_t, 4> RealWeights(NOps - 1); - for (unsigned i = 1; i < NOps; i++) { - ConstantInt *Value = - mdconst::dyn_extract<ConstantInt>(MD->getOperand(i)); - RealWeights[i - 1] = Value->getZExtValue(); - } - verifyMisExpect(&I, RealWeights, I.getContext()); - } - } - } -} - -} // namespace misexpect -} // namespace llvm -#undef DEBUG_TYPE |

