Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 1
//===- InstrProfCorrelator.h ------------------------------------*- C++ -*-===//
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
// This file defines InstrProfCorrelator used to generate PGO profiles from
9
// raw profile data and debug info.
10
//===----------------------------------------------------------------------===//
11
 
12
#ifndef LLVM_PROFILEDATA_INSTRPROFCORRELATOR_H
13
#define LLVM_PROFILEDATA_INSTRPROFCORRELATOR_H
14
 
15
#include "llvm/ADT/DenseSet.h"
16
#include "llvm/ProfileData/InstrProf.h"
17
#include "llvm/Support/Error.h"
18
#include "llvm/Support/MemoryBuffer.h"
19
#include "llvm/Support/YAMLTraits.h"
20
#include <optional>
21
#include <vector>
22
 
23
namespace llvm {
24
class DWARFContext;
25
class DWARFDie;
26
namespace object {
27
class ObjectFile;
28
}
29
 
30
/// InstrProfCorrelator - A base class used to create raw instrumentation data
31
/// to their functions.
32
class InstrProfCorrelator {
33
public:
34
  static llvm::Expected<std::unique_ptr<InstrProfCorrelator>>
35
  get(StringRef DebugInfoFilename);
36
 
37
  /// Construct a ProfileData vector used to correlate raw instrumentation data
38
  /// to their functions.
39
  virtual Error correlateProfileData() = 0;
40
 
41
  /// Process debug info and dump the correlation data.
42
  virtual Error dumpYaml(raw_ostream &OS) = 0;
43
 
44
  /// Return the number of ProfileData elements.
45
  std::optional<size_t> getDataSize() const;
46
 
47
  /// Return a pointer to the names string that this class constructs.
48
  const char *getNamesPointer() const { return Names.c_str(); }
49
 
50
  /// Return the number of bytes in the names string.
51
  size_t getNamesSize() const { return Names.size(); }
52
 
53
  /// Return the size of the counters section in bytes.
54
  uint64_t getCountersSectionSize() const {
55
    return Ctx->CountersSectionEnd - Ctx->CountersSectionStart;
56
  }
57
 
58
  static const char *FunctionNameAttributeName;
59
  static const char *CFGHashAttributeName;
60
  static const char *NumCountersAttributeName;
61
 
62
  enum InstrProfCorrelatorKind { CK_32Bit, CK_64Bit };
63
  InstrProfCorrelatorKind getKind() const { return Kind; }
64
  virtual ~InstrProfCorrelator() = default;
65
 
66
protected:
67
  struct Context {
68
    static llvm::Expected<std::unique_ptr<Context>>
69
    get(std::unique_ptr<MemoryBuffer> Buffer, const object::ObjectFile &Obj);
70
    std::unique_ptr<MemoryBuffer> Buffer;
71
    /// The address range of the __llvm_prf_cnts section.
72
    uint64_t CountersSectionStart;
73
    uint64_t CountersSectionEnd;
74
    /// True if target and host have different endian orders.
75
    bool ShouldSwapBytes;
76
  };
77
  const std::unique_ptr<Context> Ctx;
78
 
79
  InstrProfCorrelator(InstrProfCorrelatorKind K, std::unique_ptr<Context> Ctx)
80
      : Ctx(std::move(Ctx)), Kind(K) {}
81
 
82
  std::string Names;
83
  std::vector<std::string> NamesVec;
84
 
85
  struct Probe {
86
    std::string FunctionName;
87
    std::optional<std::string> LinkageName;
88
    yaml::Hex64 CFGHash;
89
    yaml::Hex64 CounterOffset;
90
    uint32_t NumCounters;
91
    std::optional<std::string> FilePath;
92
    std::optional<int> LineNumber;
93
  };
94
 
95
  struct CorrelationData {
96
    std::vector<Probe> Probes;
97
  };
98
 
99
  friend struct yaml::MappingTraits<Probe>;
100
  friend struct yaml::SequenceElementTraits<Probe>;
101
  friend struct yaml::MappingTraits<CorrelationData>;
102
 
103
private:
104
  static llvm::Expected<std::unique_ptr<InstrProfCorrelator>>
105
  get(std::unique_ptr<MemoryBuffer> Buffer);
106
 
107
  const InstrProfCorrelatorKind Kind;
108
};
109
 
110
/// InstrProfCorrelatorImpl - A child of InstrProfCorrelator with a template
111
/// pointer type so that the ProfileData vector can be materialized.
112
template <class IntPtrT>
113
class InstrProfCorrelatorImpl : public InstrProfCorrelator {
114
public:
115
  InstrProfCorrelatorImpl(std::unique_ptr<InstrProfCorrelator::Context> Ctx);
116
  static bool classof(const InstrProfCorrelator *C);
117
 
118
  /// Return a pointer to the underlying ProfileData vector that this class
119
  /// constructs.
120
  const RawInstrProf::ProfileData<IntPtrT> *getDataPointer() const {
121
    return Data.empty() ? nullptr : Data.data();
122
  }
123
 
124
  /// Return the number of ProfileData elements.
125
  size_t getDataSize() const { return Data.size(); }
126
 
127
  static llvm::Expected<std::unique_ptr<InstrProfCorrelatorImpl<IntPtrT>>>
128
  get(std::unique_ptr<InstrProfCorrelator::Context> Ctx,
129
      const object::ObjectFile &Obj);
130
 
131
protected:
132
  std::vector<RawInstrProf::ProfileData<IntPtrT>> Data;
133
 
134
  Error correlateProfileData() override;
135
  virtual void correlateProfileDataImpl(
136
      InstrProfCorrelator::CorrelationData *Data = nullptr) = 0;
137
 
138
  Error dumpYaml(raw_ostream &OS) override;
139
 
140
  void addProbe(StringRef FunctionName, uint64_t CFGHash, IntPtrT CounterOffset,
141
                IntPtrT FunctionPtr, uint32_t NumCounters);
142
 
143
private:
144
  InstrProfCorrelatorImpl(InstrProfCorrelatorKind Kind,
145
                          std::unique_ptr<InstrProfCorrelator::Context> Ctx)
146
      : InstrProfCorrelator(Kind, std::move(Ctx)){};
147
  llvm::DenseSet<IntPtrT> CounterOffsets;
148
 
149
  // Byte-swap the value if necessary.
150
  template <class T> T maybeSwap(T Value) const {
151
    return Ctx->ShouldSwapBytes ? sys::getSwappedBytes(Value) : Value;
152
  }
153
};
154
 
155
/// DwarfInstrProfCorrelator - A child of InstrProfCorrelatorImpl that takes
156
/// DWARF debug info as input to correlate profiles.
157
template <class IntPtrT>
158
class DwarfInstrProfCorrelator : public InstrProfCorrelatorImpl<IntPtrT> {
159
public:
160
  DwarfInstrProfCorrelator(std::unique_ptr<DWARFContext> DICtx,
161
                           std::unique_ptr<InstrProfCorrelator::Context> Ctx)
162
      : InstrProfCorrelatorImpl<IntPtrT>(std::move(Ctx)),
163
        DICtx(std::move(DICtx)) {}
164
 
165
private:
166
  std::unique_ptr<DWARFContext> DICtx;
167
 
168
  /// Return the address of the object that the provided DIE symbolizes.
169
  std::optional<uint64_t> getLocation(const DWARFDie &Die) const;
170
 
171
  /// Returns true if the provided DIE symbolizes an instrumentation probe
172
  /// symbol.
173
  static bool isDIEOfProbe(const DWARFDie &Die);
174
 
175
  /// Iterate over DWARF DIEs to find those that symbolize instrumentation
176
  /// probes and construct the ProfileData vector and Names string.
177
  ///
178
  /// Here is some example DWARF for an instrumentation probe we are looking
179
  /// for:
180
  /// \code
181
  ///   DW_TAG_subprogram
182
  ///   DW_AT_low_pc    (0x0000000000000000)
183
  ///   DW_AT_high_pc   (0x0000000000000014)
184
  ///   DW_AT_name      ("foo")
185
  ///     DW_TAG_variable
186
  ///       DW_AT_name  ("__profc_foo")
187
  ///       DW_AT_location      (DW_OP_addr 0x0)
188
  ///       DW_TAG_LLVM_annotation
189
  ///         DW_AT_name        ("Function Name")
190
  ///         DW_AT_const_value ("foo")
191
  ///       DW_TAG_LLVM_annotation
192
  ///         DW_AT_name        ("CFG Hash")
193
  ///         DW_AT_const_value (12345678)
194
  ///       DW_TAG_LLVM_annotation
195
  ///         DW_AT_name        ("Num Counters")
196
  ///         DW_AT_const_value (2)
197
  ///       NULL
198
  ///     NULL
199
  /// \endcode
200
  void correlateProfileDataImpl(
201
      InstrProfCorrelator::CorrelationData *Data = nullptr) override;
202
};
203
 
204
} // end namespace llvm
205
 
206
#endif // LLVM_PROFILEDATA_INSTRPROFCORRELATOR_H