164fa8cceSHongtao Yu //===- Transforms/IPO/SampleProfileProbe.h ----------*- C++ -*-===// 264fa8cceSHongtao Yu // 364fa8cceSHongtao Yu // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 464fa8cceSHongtao Yu // See https://llvm.org/LICENSE.txt for license information. 564fa8cceSHongtao Yu // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 664fa8cceSHongtao Yu // 764fa8cceSHongtao Yu //===----------------------------------------------------------------------===// 864fa8cceSHongtao Yu // 964fa8cceSHongtao Yu /// \file 1064fa8cceSHongtao Yu /// This file provides the interface for the pseudo probe implementation for 1164fa8cceSHongtao Yu /// AutoFDO. 1264fa8cceSHongtao Yu // 1364fa8cceSHongtao Yu //===----------------------------------------------------------------------===// 1464fa8cceSHongtao Yu 1564fa8cceSHongtao Yu #ifndef LLVM_TRANSFORMS_IPO_SAMPLEPROFILEPROBE_H 1664fa8cceSHongtao Yu #define LLVM_TRANSFORMS_IPO_SAMPLEPROFILEPROBE_H 1764fa8cceSHongtao Yu 183d89b3cbSHongtao Yu #include "llvm/Analysis/LazyCallGraph.h" 1964fa8cceSHongtao Yu #include "llvm/IR/PassManager.h" 20*36c6632eSNikita Popov #include "llvm/IR/PassInstrumentation.h" 21ac068e01SHongtao Yu #include "llvm/ProfileData/SampleProf.h" 2264fa8cceSHongtao Yu #include <unordered_map> 2364fa8cceSHongtao Yu 2464fa8cceSHongtao Yu namespace llvm { 25f1985a3fSserge-sans-paille class BasicBlock; 26f1985a3fSserge-sans-paille class Function; 27f1985a3fSserge-sans-paille class Instruction; 28f1985a3fSserge-sans-paille class Loop; 29f1985a3fSserge-sans-paille class PassInstrumentationCallbacks; 30f1985a3fSserge-sans-paille class TargetMachine; 3164fa8cceSHongtao Yu 3264fa8cceSHongtao Yu class Module; 3364fa8cceSHongtao Yu 34ac068e01SHongtao Yu using namespace sampleprof; 3564fa8cceSHongtao Yu using BlockIdMap = std::unordered_map<BasicBlock *, uint32_t>; 3624d4291cSHongtao Yu using InstructionIdMap = std::unordered_map<Instruction *, uint32_t>; 37f28ee1a2SHongtao Yu // Map from tuples of Probe id and inline stack hash code to distribution 38f28ee1a2SHongtao Yu // factors. 39f28ee1a2SHongtao Yu using ProbeFactorMap = std::unordered_map<std::pair<uint64_t, uint64_t>, float, 40f28ee1a2SHongtao Yu pair_hash<uint64_t, uint64_t>>; 413d89b3cbSHongtao Yu using FuncProbeFactorMap = StringMap<ProbeFactorMap>; 4264fa8cceSHongtao Yu 43ac068e01SHongtao Yu 443d89b3cbSHongtao Yu // A pseudo probe verifier that can be run after each IR passes to detect the 453d89b3cbSHongtao Yu // violation of updating probe factors. In principle, the sum of distribution 463d89b3cbSHongtao Yu // factor for a probe should be identical before and after a pass. For a 473d89b3cbSHongtao Yu // function pass, the factor sum for a probe would be typically 100%. 483d89b3cbSHongtao Yu class PseudoProbeVerifier { 493d89b3cbSHongtao Yu public: 503d89b3cbSHongtao Yu void registerCallbacks(PassInstrumentationCallbacks &PIC); 513d89b3cbSHongtao Yu 523d89b3cbSHongtao Yu // Implementation of pass instrumentation callbacks for new pass manager. 5319158eb7SSebastian Neubauer void runAfterPass(StringRef PassID, Any IR); 543d89b3cbSHongtao Yu 553d89b3cbSHongtao Yu private: 563d89b3cbSHongtao Yu // Allow a little bias due the rounding to integral factors. 57c90c261eSYang Fan constexpr static float DistributionFactorVariance = 0.02f; 583d89b3cbSHongtao Yu // Distribution factors from last pass. 593d89b3cbSHongtao Yu FuncProbeFactorMap FunctionProbeFactors; 603d89b3cbSHongtao Yu 613d89b3cbSHongtao Yu void collectProbeFactors(const BasicBlock *BB, ProbeFactorMap &ProbeFactors); 623d89b3cbSHongtao Yu void runAfterPass(const Module *M); 633d89b3cbSHongtao Yu void runAfterPass(const LazyCallGraph::SCC *C); 643d89b3cbSHongtao Yu void runAfterPass(const Function *F); 653d89b3cbSHongtao Yu void runAfterPass(const Loop *L); 663d89b3cbSHongtao Yu bool shouldVerifyFunction(const Function *F); 673d89b3cbSHongtao Yu void verifyProbeFactors(const Function *F, 683d89b3cbSHongtao Yu const ProbeFactorMap &ProbeFactors); 693d89b3cbSHongtao Yu }; 703d89b3cbSHongtao Yu 7164fa8cceSHongtao Yu /// Sample profile pseudo prober. 7264fa8cceSHongtao Yu /// 7364fa8cceSHongtao Yu /// Insert pseudo probes for block sampling and value sampling. 7464fa8cceSHongtao Yu class SampleProfileProber { 7564fa8cceSHongtao Yu public: 7664fa8cceSHongtao Yu // Give an empty module id when the prober is not used for instrumentation. 77705a4c14SHongtao Yu SampleProfileProber(Function &F, const std::string &CurModuleUniqueId); 7864fa8cceSHongtao Yu void instrumentOneFunc(Function &F, TargetMachine *TM); 7964fa8cceSHongtao Yu 8064fa8cceSHongtao Yu private: getFunction()8164fa8cceSHongtao Yu Function *getFunction() const { return F; } getFunctionHash()82705a4c14SHongtao Yu uint64_t getFunctionHash() const { return FunctionHash; } 8364fa8cceSHongtao Yu uint32_t getBlockId(const BasicBlock *BB) const; 8424d4291cSHongtao Yu uint32_t getCallsiteId(const Instruction *Call) const; 85b8cc3ba4SLei Wang void findUnreachableBlocks(DenseSet<BasicBlock *> &BlocksToIgnore); 86b8cc3ba4SLei Wang void findInvokeNormalDests(DenseSet<BasicBlock *> &InvokeNormalDests); 87b8cc3ba4SLei Wang void computeBlocksToIgnore(DenseSet<BasicBlock *> &BlocksToIgnore, 88b8cc3ba4SLei Wang DenseSet<BasicBlock *> &BlocksAndCallsToIgnore); 89b8cc3ba4SLei Wang const Instruction * 90b8cc3ba4SLei Wang getOriginalTerminator(const BasicBlock *Head, 91b8cc3ba4SLei Wang const DenseSet<BasicBlock *> &BlocksToIgnore); 92b8cc3ba4SLei Wang void computeCFGHash(const DenseSet<BasicBlock *> &BlocksToIgnore); 935bbce06aSLei Wang void computeProbeId(const DenseSet<BasicBlock *> &BlocksToIgnore, 945bbce06aSLei Wang const DenseSet<BasicBlock *> &BlocksAndCallsToIgnore); 9564fa8cceSHongtao Yu 9664fa8cceSHongtao Yu Function *F; 9764fa8cceSHongtao Yu 98705a4c14SHongtao Yu /// The current module ID that is used to name a static object as a comdat 99705a4c14SHongtao Yu /// group. 100705a4c14SHongtao Yu std::string CurModuleUniqueId; 101705a4c14SHongtao Yu 102705a4c14SHongtao Yu /// A CFG hash code used to identify a function code changes. 103705a4c14SHongtao Yu uint64_t FunctionHash; 104705a4c14SHongtao Yu 10564fa8cceSHongtao Yu /// Map basic blocks to the their pseudo probe ids. 10664fa8cceSHongtao Yu BlockIdMap BlockProbeIds; 10764fa8cceSHongtao Yu 10824d4291cSHongtao Yu /// Map indirect calls to the their pseudo probe ids. 10924d4291cSHongtao Yu InstructionIdMap CallProbeIds; 11024d4291cSHongtao Yu 11164fa8cceSHongtao Yu /// The ID of the last probe, Can be used to number a new probe. 11264fa8cceSHongtao Yu uint32_t LastProbeId; 11364fa8cceSHongtao Yu }; 11464fa8cceSHongtao Yu 11564fa8cceSHongtao Yu class SampleProfileProbePass : public PassInfoMixin<SampleProfileProbePass> { 11664fa8cceSHongtao Yu TargetMachine *TM; 11764fa8cceSHongtao Yu 11864fa8cceSHongtao Yu public: SampleProfileProbePass(TargetMachine * TM)11964fa8cceSHongtao Yu SampleProfileProbePass(TargetMachine *TM) : TM(TM) {} 12064fa8cceSHongtao Yu PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM); 12164fa8cceSHongtao Yu }; 12264fa8cceSHongtao Yu 123f28ee1a2SHongtao Yu // Pseudo probe distribution factor updater. 124f28ee1a2SHongtao Yu // Sample profile annotation can happen in both LTO prelink and postlink. The 125f28ee1a2SHongtao Yu // postlink-time re-annotation can degrade profile quality because of prelink 126f28ee1a2SHongtao Yu // code duplication transformation, such as loop unrolling, jump threading, 127f28ee1a2SHongtao Yu // indirect call promotion etc. As such, samples corresponding to a source 128f28ee1a2SHongtao Yu // location may be aggregated multiple times in postlink. With a concept of 129f28ee1a2SHongtao Yu // distribution factor for pseudo probes, samples can be distributed among 130f28ee1a2SHongtao Yu // duplicated probes reasonable based on the assumption that optimizations 131f28ee1a2SHongtao Yu // duplicating code well-maintain the branch frequency information (BFI). This 132f28ee1a2SHongtao Yu // pass updates distribution factors for each pseudo probe at the end of the 133f28ee1a2SHongtao Yu // prelink pipeline, to reflect an estimated portion of the real execution 134f28ee1a2SHongtao Yu // count. 1353d89b3cbSHongtao Yu class PseudoProbeUpdatePass : public PassInfoMixin<PseudoProbeUpdatePass> { 1363d89b3cbSHongtao Yu void runOnFunction(Function &F, FunctionAnalysisManager &FAM); 1373d89b3cbSHongtao Yu 1383d89b3cbSHongtao Yu public: 139152d61a8SKazu Hirata PseudoProbeUpdatePass() = default; 1403d89b3cbSHongtao Yu PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM); 1413d89b3cbSHongtao Yu }; 1423d89b3cbSHongtao Yu 14364fa8cceSHongtao Yu } // end namespace llvm 14464fa8cceSHongtao Yu #endif // LLVM_TRANSFORMS_IPO_SAMPLEPROFILEPROBE_H 145