PseudoProbe.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. //===- PseudoProbe.cpp - Pseudo Probe Helpers -----------------------------===//
  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. // This file implements the helpers to manipulate pseudo probe IR intrinsic
  10. // calls.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "llvm/IR/PseudoProbe.h"
  14. #include "llvm/IR/DebugInfoMetadata.h"
  15. #include "llvm/IR/IRBuilder.h"
  16. #include "llvm/IR/Instruction.h"
  17. #include "llvm/IR/IntrinsicInst.h"
  18. using namespace llvm;
  19. namespace llvm {
  20. std::optional<PseudoProbe>
  21. extractProbeFromDiscriminator(const Instruction &Inst) {
  22. assert(isa<CallBase>(&Inst) && !isa<IntrinsicInst>(&Inst) &&
  23. "Only call instructions should have pseudo probe encodes as their "
  24. "Dwarf discriminators");
  25. if (const DebugLoc &DLoc = Inst.getDebugLoc()) {
  26. const DILocation *DIL = DLoc;
  27. auto Discriminator = DIL->getDiscriminator();
  28. if (DILocation::isPseudoProbeDiscriminator(Discriminator)) {
  29. PseudoProbe Probe;
  30. Probe.Id =
  31. PseudoProbeDwarfDiscriminator::extractProbeIndex(Discriminator);
  32. Probe.Type =
  33. PseudoProbeDwarfDiscriminator::extractProbeType(Discriminator);
  34. Probe.Attr =
  35. PseudoProbeDwarfDiscriminator::extractProbeAttributes(Discriminator);
  36. Probe.Factor =
  37. PseudoProbeDwarfDiscriminator::extractProbeFactor(Discriminator) /
  38. (float)PseudoProbeDwarfDiscriminator::FullDistributionFactor;
  39. return Probe;
  40. }
  41. }
  42. return std::nullopt;
  43. }
  44. std::optional<PseudoProbe> extractProbe(const Instruction &Inst) {
  45. if (const auto *II = dyn_cast<PseudoProbeInst>(&Inst)) {
  46. PseudoProbe Probe;
  47. Probe.Id = II->getIndex()->getZExtValue();
  48. Probe.Type = (uint32_t)PseudoProbeType::Block;
  49. Probe.Attr = II->getAttributes()->getZExtValue();
  50. Probe.Factor = II->getFactor()->getZExtValue() /
  51. (float)PseudoProbeFullDistributionFactor;
  52. return Probe;
  53. }
  54. if (isa<CallBase>(&Inst) && !isa<IntrinsicInst>(&Inst))
  55. return extractProbeFromDiscriminator(Inst);
  56. return std::nullopt;
  57. }
  58. void setProbeDistributionFactor(Instruction &Inst, float Factor) {
  59. assert(Factor >= 0 && Factor <= 1 &&
  60. "Distribution factor must be in [0, 1.0]");
  61. if (auto *II = dyn_cast<PseudoProbeInst>(&Inst)) {
  62. IRBuilder<> Builder(&Inst);
  63. uint64_t IntFactor = PseudoProbeFullDistributionFactor;
  64. if (Factor < 1)
  65. IntFactor *= Factor;
  66. auto OrigFactor = II->getFactor()->getZExtValue();
  67. if (IntFactor != OrigFactor)
  68. II->replaceUsesOfWith(II->getFactor(), Builder.getInt64(IntFactor));
  69. } else if (isa<CallBase>(&Inst) && !isa<IntrinsicInst>(&Inst)) {
  70. if (const DebugLoc &DLoc = Inst.getDebugLoc()) {
  71. const DILocation *DIL = DLoc;
  72. auto Discriminator = DIL->getDiscriminator();
  73. if (DILocation::isPseudoProbeDiscriminator(Discriminator)) {
  74. auto Index =
  75. PseudoProbeDwarfDiscriminator::extractProbeIndex(Discriminator);
  76. auto Type =
  77. PseudoProbeDwarfDiscriminator::extractProbeType(Discriminator);
  78. auto Attr = PseudoProbeDwarfDiscriminator::extractProbeAttributes(
  79. Discriminator);
  80. // Round small factors to 0 to avoid over-counting.
  81. uint32_t IntFactor =
  82. PseudoProbeDwarfDiscriminator::FullDistributionFactor;
  83. if (Factor < 1)
  84. IntFactor *= Factor;
  85. uint32_t V = PseudoProbeDwarfDiscriminator::packProbeData(
  86. Index, Type, Attr, IntFactor);
  87. DIL = DIL->cloneWithDiscriminator(V);
  88. Inst.setDebugLoc(DIL);
  89. }
  90. }
  91. }
  92. }
  93. } // namespace llvm