SampleProfileProbe.h 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- Transforms/IPO/SampleProfileProbe.h ----------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. /// \file
  15. /// This file provides the interface for the pseudo probe implementation for
  16. /// AutoFDO.
  17. //
  18. //===----------------------------------------------------------------------===//
  19. #ifndef LLVM_TRANSFORMS_IPO_SAMPLEPROFILEPROBE_H
  20. #define LLVM_TRANSFORMS_IPO_SAMPLEPROFILEPROBE_H
  21. #include "llvm/ADT/DenseMap.h"
  22. #include "llvm/Analysis/CallGraphSCCPass.h"
  23. #include "llvm/Analysis/LazyCallGraph.h"
  24. #include "llvm/Analysis/LoopInfo.h"
  25. #include "llvm/IR/PassInstrumentation.h"
  26. #include "llvm/IR/PassManager.h"
  27. #include "llvm/IR/PseudoProbe.h"
  28. #include "llvm/ProfileData/SampleProf.h"
  29. #include "llvm/Target/TargetMachine.h"
  30. #include <unordered_map>
  31. namespace llvm {
  32. class Module;
  33. using namespace sampleprof;
  34. using BlockIdMap = std::unordered_map<BasicBlock *, uint32_t>;
  35. using InstructionIdMap = std::unordered_map<Instruction *, uint32_t>;
  36. // Map from tuples of Probe id and inline stack hash code to distribution
  37. // factors.
  38. using ProbeFactorMap = std::unordered_map<std::pair<uint64_t, uint64_t>, float,
  39. pair_hash<uint64_t, uint64_t>>;
  40. using FuncProbeFactorMap = StringMap<ProbeFactorMap>;
  41. enum class PseudoProbeReservedId { Invalid = 0, Last = Invalid };
  42. class PseudoProbeDescriptor {
  43. uint64_t FunctionGUID;
  44. uint64_t FunctionHash;
  45. public:
  46. PseudoProbeDescriptor(uint64_t GUID, uint64_t Hash)
  47. : FunctionGUID(GUID), FunctionHash(Hash) {}
  48. uint64_t getFunctionGUID() const { return FunctionGUID; }
  49. uint64_t getFunctionHash() const { return FunctionHash; }
  50. };
  51. // A pseudo probe verifier that can be run after each IR passes to detect the
  52. // violation of updating probe factors. In principle, the sum of distribution
  53. // factor for a probe should be identical before and after a pass. For a
  54. // function pass, the factor sum for a probe would be typically 100%.
  55. class PseudoProbeVerifier {
  56. public:
  57. void registerCallbacks(PassInstrumentationCallbacks &PIC);
  58. // Implementation of pass instrumentation callbacks for new pass manager.
  59. void runAfterPass(StringRef PassID, Any IR);
  60. private:
  61. // Allow a little bias due the rounding to integral factors.
  62. constexpr static float DistributionFactorVariance = 0.02f;
  63. // Distribution factors from last pass.
  64. FuncProbeFactorMap FunctionProbeFactors;
  65. void collectProbeFactors(const BasicBlock *BB, ProbeFactorMap &ProbeFactors);
  66. void runAfterPass(const Module *M);
  67. void runAfterPass(const LazyCallGraph::SCC *C);
  68. void runAfterPass(const Function *F);
  69. void runAfterPass(const Loop *L);
  70. bool shouldVerifyFunction(const Function *F);
  71. void verifyProbeFactors(const Function *F,
  72. const ProbeFactorMap &ProbeFactors);
  73. };
  74. // This class serves sample counts correlation for SampleProfileLoader by
  75. // analyzing pseudo probes and their function descriptors injected by
  76. // SampleProfileProber.
  77. class PseudoProbeManager {
  78. DenseMap<uint64_t, PseudoProbeDescriptor> GUIDToProbeDescMap;
  79. const PseudoProbeDescriptor *getDesc(const Function &F) const;
  80. public:
  81. PseudoProbeManager(const Module &M);
  82. bool moduleIsProbed(const Module &M) const;
  83. bool profileIsValid(const Function &F, const FunctionSamples &Samples) const;
  84. };
  85. /// Sample profile pseudo prober.
  86. ///
  87. /// Insert pseudo probes for block sampling and value sampling.
  88. class SampleProfileProber {
  89. public:
  90. // Give an empty module id when the prober is not used for instrumentation.
  91. SampleProfileProber(Function &F, const std::string &CurModuleUniqueId);
  92. void instrumentOneFunc(Function &F, TargetMachine *TM);
  93. private:
  94. Function *getFunction() const { return F; }
  95. uint64_t getFunctionHash() const { return FunctionHash; }
  96. uint32_t getBlockId(const BasicBlock *BB) const;
  97. uint32_t getCallsiteId(const Instruction *Call) const;
  98. void computeCFGHash();
  99. void computeProbeIdForBlocks();
  100. void computeProbeIdForCallsites();
  101. Function *F;
  102. /// The current module ID that is used to name a static object as a comdat
  103. /// group.
  104. std::string CurModuleUniqueId;
  105. /// A CFG hash code used to identify a function code changes.
  106. uint64_t FunctionHash;
  107. /// Map basic blocks to the their pseudo probe ids.
  108. BlockIdMap BlockProbeIds;
  109. /// Map indirect calls to the their pseudo probe ids.
  110. InstructionIdMap CallProbeIds;
  111. /// The ID of the last probe, Can be used to number a new probe.
  112. uint32_t LastProbeId;
  113. };
  114. class SampleProfileProbePass : public PassInfoMixin<SampleProfileProbePass> {
  115. TargetMachine *TM;
  116. public:
  117. SampleProfileProbePass(TargetMachine *TM) : TM(TM) {}
  118. PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
  119. };
  120. // Pseudo probe distribution factor updater.
  121. // Sample profile annotation can happen in both LTO prelink and postlink. The
  122. // postlink-time re-annotation can degrade profile quality because of prelink
  123. // code duplication transformation, such as loop unrolling, jump threading,
  124. // indirect call promotion etc. As such, samples corresponding to a source
  125. // location may be aggregated multiple times in postlink. With a concept of
  126. // distribution factor for pseudo probes, samples can be distributed among
  127. // duplicated probes reasonable based on the assumption that optimizations
  128. // duplicating code well-maintain the branch frequency information (BFI). This
  129. // pass updates distribution factors for each pseudo probe at the end of the
  130. // prelink pipeline, to reflect an estimated portion of the real execution
  131. // count.
  132. class PseudoProbeUpdatePass : public PassInfoMixin<PseudoProbeUpdatePass> {
  133. void runOnFunction(Function &F, FunctionAnalysisManager &FAM);
  134. public:
  135. PseudoProbeUpdatePass() = default;
  136. PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
  137. };
  138. } // end namespace llvm
  139. #endif // LLVM_TRANSFORMS_IPO_SAMPLEPROFILEPROBE_H
  140. #ifdef __GNUC__
  141. #pragma GCC diagnostic pop
  142. #endif