IndirectCallPromotionAnalysis.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. //===-- IndirectCallPromotionAnalysis.cpp - Find promotion candidates ===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // Helper methods for identifying profitable indirect call promotion
  10. // candidates for an instruction when the indirect-call value profile metadata
  11. // is available.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #include "llvm/Analysis/IndirectCallPromotionAnalysis.h"
  15. #include "llvm/ADT/STLExtras.h"
  16. #include "llvm/Analysis/IndirectCallVisitor.h"
  17. #include "llvm/IR/InstIterator.h"
  18. #include "llvm/IR/InstVisitor.h"
  19. #include "llvm/IR/Instructions.h"
  20. #include "llvm/IR/IntrinsicInst.h"
  21. #include "llvm/ProfileData/InstrProf.h"
  22. #include "llvm/Support/CommandLine.h"
  23. #include "llvm/Support/Debug.h"
  24. #include <memory>
  25. using namespace llvm;
  26. #define DEBUG_TYPE "pgo-icall-prom-analysis"
  27. // The percent threshold for the direct-call target (this call site vs the
  28. // remaining call count) for it to be considered as the promotion target.
  29. static cl::opt<unsigned> ICPRemainingPercentThreshold(
  30. "icp-remaining-percent-threshold", cl::init(30), cl::Hidden, cl::ZeroOrMore,
  31. cl::desc("The percentage threshold against remaining unpromoted indirect "
  32. "call count for the promotion"));
  33. // The percent threshold for the direct-call target (this call site vs the
  34. // total call count) for it to be considered as the promotion target.
  35. static cl::opt<unsigned>
  36. ICPTotalPercentThreshold("icp-total-percent-threshold", cl::init(5),
  37. cl::Hidden, cl::ZeroOrMore,
  38. cl::desc("The percentage threshold against total "
  39. "count for the promotion"));
  40. // Set the maximum number of targets to promote for a single indirect-call
  41. // callsite.
  42. static cl::opt<unsigned>
  43. MaxNumPromotions("icp-max-prom", cl::init(3), cl::Hidden, cl::ZeroOrMore,
  44. cl::desc("Max number of promotions for a single indirect "
  45. "call callsite"));
  46. ICallPromotionAnalysis::ICallPromotionAnalysis() {
  47. ValueDataArray = std::make_unique<InstrProfValueData[]>(MaxNumPromotions);
  48. }
  49. bool ICallPromotionAnalysis::isPromotionProfitable(uint64_t Count,
  50. uint64_t TotalCount,
  51. uint64_t RemainingCount) {
  52. return Count * 100 >= ICPRemainingPercentThreshold * RemainingCount &&
  53. Count * 100 >= ICPTotalPercentThreshold * TotalCount;
  54. }
  55. // Indirect-call promotion heuristic. The direct targets are sorted based on
  56. // the count. Stop at the first target that is not promoted. Returns the
  57. // number of candidates deemed profitable.
  58. uint32_t ICallPromotionAnalysis::getProfitablePromotionCandidates(
  59. const Instruction *Inst, uint32_t NumVals, uint64_t TotalCount) {
  60. ArrayRef<InstrProfValueData> ValueDataRef(ValueDataArray.get(), NumVals);
  61. LLVM_DEBUG(dbgs() << " \nWork on callsite " << *Inst
  62. << " Num_targets: " << NumVals << "\n");
  63. uint32_t I = 0;
  64. uint64_t RemainingCount = TotalCount;
  65. for (; I < MaxNumPromotions && I < NumVals; I++) {
  66. uint64_t Count = ValueDataRef[I].Count;
  67. assert(Count <= RemainingCount);
  68. LLVM_DEBUG(dbgs() << " Candidate " << I << " Count=" << Count
  69. << " Target_func: " << ValueDataRef[I].Value << "\n");
  70. if (!isPromotionProfitable(Count, TotalCount, RemainingCount)) {
  71. LLVM_DEBUG(dbgs() << " Not promote: Cold target.\n");
  72. return I;
  73. }
  74. RemainingCount -= Count;
  75. }
  76. return I;
  77. }
  78. ArrayRef<InstrProfValueData>
  79. ICallPromotionAnalysis::getPromotionCandidatesForInstruction(
  80. const Instruction *I, uint32_t &NumVals, uint64_t &TotalCount,
  81. uint32_t &NumCandidates) {
  82. bool Res =
  83. getValueProfDataFromInst(*I, IPVK_IndirectCallTarget, MaxNumPromotions,
  84. ValueDataArray.get(), NumVals, TotalCount);
  85. if (!Res) {
  86. NumCandidates = 0;
  87. return ArrayRef<InstrProfValueData>();
  88. }
  89. NumCandidates = getProfitablePromotionCandidates(I, NumVals, TotalCount);
  90. return ArrayRef<InstrProfValueData>(ValueDataArray.get(), NumVals);
  91. }