aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/llvm12/lib/IR/PseudoProbe.cpp
blob: 24f38b8888b704b895ec2e999ea87042d568fc88 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
//===- PseudoProbe.cpp - Pseudo Probe Helpers -----------------------------===// 
// 
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 
// See https://llvm.org/LICENSE.txt for license information. 
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 
// 
//===----------------------------------------------------------------------===// 
// 
// This file implements the helpers to manipulate pseudo probe IR intrinsic 
// calls. 
// 
//===----------------------------------------------------------------------===// 
 
#include "llvm/IR/PseudoProbe.h" 
#include "llvm/IR/DebugInfoMetadata.h" 
#include "llvm/IR/IRBuilder.h" 
#include "llvm/IR/Instruction.h" 
 
using namespace llvm; 
 
namespace llvm { 
 
Optional<PseudoProbe> extractProbeFromDiscriminator(const Instruction &Inst) { 
  assert(isa<CallBase>(&Inst) && !isa<IntrinsicInst>(&Inst) && 
         "Only call instructions should have pseudo probe encodes as their " 
         "Dwarf discriminators"); 
  if (const DebugLoc &DLoc = Inst.getDebugLoc()) { 
    const DILocation *DIL = DLoc; 
    auto Discriminator = DIL->getDiscriminator(); 
    if (DILocation::isPseudoProbeDiscriminator(Discriminator)) { 
      PseudoProbe Probe; 
      Probe.Id = 
          PseudoProbeDwarfDiscriminator::extractProbeIndex(Discriminator); 
      Probe.Type = 
          PseudoProbeDwarfDiscriminator::extractProbeType(Discriminator); 
      Probe.Attr = 
          PseudoProbeDwarfDiscriminator::extractProbeAttributes(Discriminator); 
      Probe.Factor = 
          PseudoProbeDwarfDiscriminator::extractProbeFactor(Discriminator) / 
          (float)PseudoProbeDwarfDiscriminator::FullDistributionFactor; 
      return Probe; 
    } 
  } 
  return None; 
} 
 
Optional<PseudoProbe> extractProbe(const Instruction &Inst) { 
  if (const auto *II = dyn_cast<PseudoProbeInst>(&Inst)) { 
    PseudoProbe Probe; 
    Probe.Id = II->getIndex()->getZExtValue(); 
    Probe.Type = (uint32_t)PseudoProbeType::Block; 
    Probe.Attr = II->getAttributes()->getZExtValue(); 
    Probe.Factor = II->getFactor()->getZExtValue() / 
                   (float)PseudoProbeFullDistributionFactor; 
    return Probe; 
  } 
 
  if (isa<CallBase>(&Inst) && !isa<IntrinsicInst>(&Inst)) 
    return extractProbeFromDiscriminator(Inst); 
 
  return None; 
} 
 
void setProbeDistributionFactor(Instruction &Inst, float Factor) { 
  assert(Factor >= 0 && Factor <= 1 && 
         "Distribution factor must be in [0, 1.0]"); 
  if (auto *II = dyn_cast<PseudoProbeInst>(&Inst)) { 
    IRBuilder<> Builder(&Inst); 
    uint64_t IntFactor = PseudoProbeFullDistributionFactor; 
    if (Factor < 1) 
      IntFactor *= Factor; 
    auto OrigFactor = II->getFactor()->getZExtValue(); 
    if (IntFactor != OrigFactor) 
      II->replaceUsesOfWith(II->getFactor(), Builder.getInt64(IntFactor)); 
  } else if (isa<CallBase>(&Inst) && !isa<IntrinsicInst>(&Inst)) { 
    if (const DebugLoc &DLoc = Inst.getDebugLoc()) { 
      const DILocation *DIL = DLoc; 
      auto Discriminator = DIL->getDiscriminator(); 
      if (DILocation::isPseudoProbeDiscriminator(Discriminator)) { 
        auto Index = 
            PseudoProbeDwarfDiscriminator::extractProbeIndex(Discriminator); 
        auto Type = 
            PseudoProbeDwarfDiscriminator::extractProbeType(Discriminator); 
        auto Attr = PseudoProbeDwarfDiscriminator::extractProbeAttributes( 
            Discriminator); 
        // Round small factors to 0 to avoid over-counting. 
        uint32_t IntFactor = 
            PseudoProbeDwarfDiscriminator::FullDistributionFactor; 
        if (Factor < 1) 
          IntFactor *= Factor; 
        uint32_t V = PseudoProbeDwarfDiscriminator::packProbeData( 
            Index, Type, Attr, IntFactor); 
        DIL = DIL->cloneWithDiscriminator(V); 
        Inst.setDebugLoc(DIL); 
      } 
    } 
  } 
} 
} // namespace llvm