PseudoProbe.cpp 3.7 KB

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