003 File Manager
Current Path:
/usr/src/contrib/llvm-project/llvm/lib/Transforms/Utils
usr
/
src
/
contrib
/
llvm-project
/
llvm
/
lib
/
Transforms
/
Utils
/
📁
..
📄
AMDGPUEmitPrintf.cpp
(8.57 KB)
📄
ASanStackFrameLayout.cpp
(5.75 KB)
📄
AddDiscriminators.cpp
(10.78 KB)
📄
AssumeBundleBuilder.cpp
(21.46 KB)
📄
BasicBlockUtils.cpp
(51.81 KB)
📄
BreakCriticalEdges.cpp
(19.03 KB)
📄
BuildLibCalls.cpp
(43.9 KB)
📄
BypassSlowDivision.cpp
(17.95 KB)
📄
CallGraphUpdater.cpp
(5.76 KB)
📄
CallPromotionUtils.cpp
(22.18 KB)
📄
CanonicalizeAliases.cpp
(3.18 KB)
📄
CanonicalizeFreezeInLoops.cpp
(7.93 KB)
📄
CloneFunction.cpp
(34.49 KB)
📄
CloneModule.cpp
(7.93 KB)
📄
CodeExtractor.cpp
(65.69 KB)
📄
CodeMoverUtils.cpp
(15.82 KB)
📄
CtorUtils.cpp
(5.1 KB)
📄
Debugify.cpp
(17.78 KB)
📄
DemoteRegToStack.cpp
(6.1 KB)
📄
EntryExitInstrumenter.cpp
(5.83 KB)
📄
EscapeEnumerator.cpp
(2.96 KB)
📄
Evaluator.cpp
(27.98 KB)
📄
FixIrreducible.cpp
(12.68 KB)
📄
FlattenCFG.cpp
(16.99 KB)
📄
FunctionComparator.cpp
(34.36 KB)
📄
FunctionImportUtils.cpp
(13.8 KB)
📄
GlobalStatus.cpp
(7.23 KB)
📄
GuardUtils.cpp
(4.76 KB)
📄
ImportedFunctionsInliningStatistics.cpp
(7.67 KB)
📄
InjectTLIMappings.cpp
(6.62 KB)
📄
InlineFunction.cpp
(103.28 KB)
📄
InstructionNamer.cpp
(1.98 KB)
📄
IntegerDivision.cpp
(26.17 KB)
📄
LCSSA.cpp
(18.72 KB)
📄
LibCallsShrinkWrap.cpp
(18.68 KB)
📄
Local.cpp
(114.96 KB)
📄
LoopRotationUtils.cpp
(29.47 KB)
📄
LoopSimplify.cpp
(36.13 KB)
📄
LoopUnroll.cpp
(38.07 KB)
📄
LoopUnrollAndJam.cpp
(37.71 KB)
📄
LoopUnrollPeel.cpp
(31.88 KB)
📄
LoopUnrollRuntime.cpp
(40.17 KB)
📄
LoopUtils.cpp
(65.03 KB)
📄
LoopVersioning.cpp
(12.42 KB)
📄
LowerInvoke.cpp
(3.3 KB)
📄
LowerMemIntrinsics.cpp
(20.41 KB)
📄
LowerSwitch.cpp
(23.46 KB)
📄
Mem2Reg.cpp
(3.71 KB)
📄
MetaRenamer.cpp
(5.29 KB)
📄
MisExpect.cpp
(6.97 KB)
📄
ModuleUtils.cpp
(10.99 KB)
📄
NameAnonGlobals.cpp
(3.33 KB)
📄
PredicateInfo.cpp
(36.79 KB)
📄
PromoteMemoryToRegister.cpp
(37.26 KB)
📄
SSAUpdater.cpp
(16.72 KB)
📄
SSAUpdaterBulk.cpp
(7.46 KB)
📄
SanitizerStats.cpp
(4.08 KB)
📄
ScalarEvolutionExpander.cpp
(101.25 KB)
📄
SimplifyCFG.cpp
(238.13 KB)
📄
SimplifyIndVar.cpp
(34.53 KB)
📄
SimplifyLibCalls.cpp
(122.25 KB)
📄
SizeOpts.cpp
(5.08 KB)
📄
SplitModule.cpp
(9.67 KB)
📄
StripGCRelocates.cpp
(2.86 KB)
📄
StripNonLineTableDebugInfo.cpp
(1.4 KB)
📄
SymbolRewriter.cpp
(18.82 KB)
📄
UnifyFunctionExitNodes.cpp
(4.42 KB)
📄
UnifyLoopExits.cpp
(8.16 KB)
📄
UniqueInternalLinkageNames.cpp
(2.91 KB)
📄
Utils.cpp
(2.53 KB)
📄
VNCoercion.cpp
(25.89 KB)
📄
ValueMapper.cpp
(38.06 KB)
Editing: MisExpect.cpp
//===--- 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/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.")); } // 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
Upload File
Create Folder