xref: /llvm-project/llvm/include/llvm/Transforms/IPO/SampleProfileProbe.h (revision 36c6632eb43bf67e19c8a6a21981cf66e06389b4)
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