PseudoProbe.cpp 3.7 KB

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