54
54
#ifndef LLVM_MC_MCPSEUDOPROBE_H
55
55
#define LLVM_MC_MCPSEUDOPROBE_H
56
56
57
+ #include " llvm/ADT/ArrayRef.h"
57
58
#include " llvm/ADT/DenseMap.h"
58
59
#include " llvm/ADT/DenseSet.h"
59
60
#include " llvm/ADT/SmallVector.h"
60
61
#include " llvm/ADT/StringRef.h"
62
+ #include " llvm/ADT/iterator.h"
61
63
#include " llvm/IR/PseudoProbe.h"
62
64
#include " llvm/Support/ErrorOr.h"
63
- #include < list >
65
+ #include < functional >
64
66
#include < map>
65
67
#include < memory>
66
68
#include < string>
67
69
#include < tuple>
68
70
#include < type_traits>
69
71
#include < unordered_map>
70
- #include < unordered_set>
71
72
#include < vector>
72
73
73
74
namespace llvm {
@@ -103,14 +104,15 @@ using MCPseudoProbeInlineStack = SmallVector<InlineSite, 8>;
103
104
using GUIDProbeFunctionMap =
104
105
std::unordered_map<uint64_t , MCPseudoProbeFuncDesc>;
105
106
// Address to pseudo probes map.
106
- using AddressProbesMap = std::map<uint64_t , std::list<MCDecodedPseudoProbe>>;
107
+ using AddressProbesMap =
108
+ std::map<uint64_t ,
109
+ std::vector<std::reference_wrapper<MCDecodedPseudoProbe>>>;
107
110
108
111
class MCDecodedPseudoProbeInlineTree ;
109
112
110
113
class MCPseudoProbeBase {
111
114
protected:
112
- uint64_t Guid;
113
- uint64_t Index;
115
+ uint32_t Index;
114
116
uint32_t Discriminator;
115
117
uint8_t Attributes;
116
118
uint8_t Type;
@@ -120,14 +122,12 @@ class MCPseudoProbeBase {
120
122
const static uint32_t PseudoProbeFirstId = 1 ;
121
123
122
124
public:
123
- MCPseudoProbeBase (uint64_t G, uint64_t I, uint64_t At, uint8_t T, uint32_t D)
124
- : Guid(G), Index(I), Discriminator(D), Attributes(At), Type(T) {}
125
+ MCPseudoProbeBase (uint64_t I, uint64_t At, uint8_t T, uint32_t D)
126
+ : Index(I), Discriminator(D), Attributes(At), Type(T) {}
125
127
126
128
bool isEntry () const { return Index == PseudoProbeFirstId; }
127
129
128
- uint64_t getGuid () const { return Guid; }
129
-
130
- uint64_t getIndex () const { return Index; }
130
+ uint32_t getIndex () const { return Index; }
131
131
132
132
uint32_t getDiscriminator () const { return Discriminator; }
133
133
@@ -157,18 +157,20 @@ class MCPseudoProbeBase {
157
157
// / uses an address from a temporary label created at the current address in the
158
158
// / current section.
159
159
class MCPseudoProbe : public MCPseudoProbeBase {
160
+ uint64_t Guid;
160
161
MCSymbol *Label;
161
162
162
163
public:
163
164
MCPseudoProbe (MCSymbol *Label, uint64_t Guid, uint64_t Index, uint64_t Type,
164
165
uint64_t Attributes, uint32_t Discriminator)
165
- : MCPseudoProbeBase(Guid, Index, Attributes, Type, Discriminator),
166
+ : MCPseudoProbeBase(Index, Attributes, Type, Discriminator), Guid(Guid ),
166
167
Label (Label) {
167
168
assert (Type <= 0xFF && " Probe type too big to encode, exceeding 2^8" );
168
169
assert (Attributes <= 0xFF &&
169
170
" Probe attributes too big to encode, exceeding 2^16" );
170
171
}
171
172
173
+ uint64_t getGuid () const { return Guid; };
172
174
MCSymbol *getLabel () const { return Label; }
173
175
void emit (MCObjectStreamer *MCOS, const MCPseudoProbe *LastProbe) const ;
174
176
};
@@ -181,11 +183,11 @@ class MCDecodedPseudoProbe : public MCPseudoProbeBase {
181
183
MCDecodedPseudoProbeInlineTree *InlineTree;
182
184
183
185
public:
184
- MCDecodedPseudoProbe (uint64_t Ad, uint64_t G, uint32_t I, PseudoProbeType K,
185
- uint8_t At, uint32_t D,
186
- MCDecodedPseudoProbeInlineTree *Tree)
187
- : MCPseudoProbeBase(G, I, At, static_cast <uint8_t >(K), D), Address(Ad),
186
+ MCDecodedPseudoProbe (uint64_t Ad, uint32_t I, PseudoProbeType K, uint8_t At,
187
+ uint32_t D, MCDecodedPseudoProbeInlineTree *Tree)
188
+ : MCPseudoProbeBase(I, At, static_cast <uint8_t >(K), D), Address(Ad),
188
189
InlineTree (Tree){};
190
+ uint64_t getGuid () const ;
189
191
190
192
uint64_t getAddress () const { return Address; }
191
193
@@ -211,21 +213,14 @@ class MCDecodedPseudoProbe : public MCPseudoProbeBase {
211
213
bool ShowName) const ;
212
214
};
213
215
214
- template <typename ProbeType, typename DerivedProbeInlineTreeType>
216
+ template <typename ProbesType, typename DerivedProbeInlineTreeType,
217
+ typename InlinedProbeTreeMap>
215
218
class MCPseudoProbeInlineTreeBase {
216
- struct InlineSiteHash {
217
- uint64_t operator ()(const InlineSite &Site) const {
218
- return std::get<0 >(Site) ^ std::get<1 >(Site);
219
- }
220
- };
221
-
222
219
protected:
223
220
// Track children (e.g. inlinees) of current context
224
- using InlinedProbeTreeMap = std::unordered_map<
225
- InlineSite, std::unique_ptr<DerivedProbeInlineTreeType>, InlineSiteHash>;
226
221
InlinedProbeTreeMap Children;
227
222
// Set of probes that come with the function.
228
- std::vector<ProbeType> Probes;
223
+ ProbesType Probes;
229
224
MCPseudoProbeInlineTreeBase () {
230
225
static_assert (std::is_base_of<MCPseudoProbeInlineTreeBase,
231
226
DerivedProbeInlineTreeType>::value,
@@ -240,12 +235,10 @@ class MCPseudoProbeInlineTreeBase {
240
235
bool isRoot () const { return Guid == 0 ; }
241
236
InlinedProbeTreeMap &getChildren () { return Children; }
242
237
const InlinedProbeTreeMap &getChildren () const { return Children; }
243
- std::vector<ProbeType> &getProbes () { return Probes; }
244
- const std::vector<ProbeType> &getProbes () const { return Probes; }
245
- void addProbes (ProbeType Probe) { Probes.push_back (Probe); }
238
+ const ProbesType &getProbes () const { return Probes; }
246
239
// Caller node of the inline site
247
- MCPseudoProbeInlineTreeBase<ProbeType , DerivedProbeInlineTreeType> *Parent =
248
- nullptr ;
240
+ MCPseudoProbeInlineTreeBase<ProbesType , DerivedProbeInlineTreeType,
241
+ InlinedProbeTreeMap> *Parent = nullptr ;
249
242
DerivedProbeInlineTreeType *getOrAddNode (const InlineSite &Site) {
250
243
auto Ret = Children.emplace (
251
244
Site, std::make_unique<DerivedProbeInlineTreeType>(Site));
@@ -259,9 +252,17 @@ class MCPseudoProbeInlineTreeBase {
259
252
// instance is created as the root of a tree.
260
253
// A real instance of this class is created for each function, either a
261
254
// not inlined function that has code in .text section or an inlined function.
255
+ struct InlineSiteHash {
256
+ uint64_t operator ()(const InlineSite &Site) const {
257
+ return std::get<0 >(Site) ^ std::get<1 >(Site);
258
+ }
259
+ };
262
260
class MCPseudoProbeInlineTree
263
- : public MCPseudoProbeInlineTreeBase<MCPseudoProbe,
264
- MCPseudoProbeInlineTree> {
261
+ : public MCPseudoProbeInlineTreeBase<
262
+ std::vector<MCPseudoProbe>, MCPseudoProbeInlineTree,
263
+ std::unordered_map<InlineSite,
264
+ std::unique_ptr<MCPseudoProbeInlineTree>,
265
+ InlineSiteHash>> {
265
266
public:
266
267
MCPseudoProbeInlineTree () = default ;
267
268
MCPseudoProbeInlineTree (uint64_t Guid) { this ->Guid = Guid; }
@@ -277,16 +278,31 @@ class MCPseudoProbeInlineTree
277
278
278
279
// inline tree node for the decoded pseudo probe
279
280
class MCDecodedPseudoProbeInlineTree
280
- : public MCPseudoProbeInlineTreeBase<MCDecodedPseudoProbe *,
281
- MCDecodedPseudoProbeInlineTree> {
282
- public:
283
- InlineSite ISite;
281
+ : public MCPseudoProbeInlineTreeBase<
282
+ MCDecodedPseudoProbe *, MCDecodedPseudoProbeInlineTree,
283
+ MutableArrayRef<MCDecodedPseudoProbeInlineTree>> {
284
+ uint32_t NumProbes = 0 ;
285
+ uint32_t ProbeId = 0 ;
284
286
287
+ public:
285
288
MCDecodedPseudoProbeInlineTree () = default ;
286
- MCDecodedPseudoProbeInlineTree (const InlineSite &Site) : ISite(Site){};
289
+ MCDecodedPseudoProbeInlineTree (const InlineSite &Site,
290
+ MCDecodedPseudoProbeInlineTree *Parent)
291
+ : ProbeId(std::get<1 >(Site)) {
292
+ this ->Guid = std::get<0 >(Site);
293
+ this ->Parent = Parent;
294
+ }
287
295
288
296
// Return false if it's a dummy inline site
289
297
bool hasInlineSite () const { return !isRoot () && !Parent->isRoot (); }
298
+ InlineSite getInlineSite () const { return InlineSite (Guid, ProbeId); }
299
+ void setProbes (MutableArrayRef<MCDecodedPseudoProbe> ProbesRef) {
300
+ Probes = ProbesRef.data ();
301
+ NumProbes = ProbesRef.size ();
302
+ }
303
+ auto getProbes () const {
304
+ return MutableArrayRef<MCDecodedPseudoProbe>(Probes, NumProbes);
305
+ }
290
306
};
291
307
292
308
// / Instances of this class represent the pseudo probes inserted into a compile
@@ -336,6 +352,20 @@ class MCPseudoProbeTable {
336
352
};
337
353
338
354
class MCPseudoProbeDecoder {
355
+ // Decoded pseudo probes vector.
356
+ std::vector<MCDecodedPseudoProbe> PseudoProbeVec;
357
+ // Injected pseudo probes, identified by the containing inline tree node.
358
+ // Need to keep injected probes separately for two reasons:
359
+ // 1) Probes cannot be added to the PseudoProbeVec: appending may cause
360
+ // reallocation so that pointers to its elements will become invalid.
361
+ // 2) Probes belonging to function record must be contiguous in PseudoProbeVec
362
+ // as owning InlineTree references them with an ArrayRef to save space.
363
+ std::unordered_map<const MCDecodedPseudoProbeInlineTree *,
364
+ std::vector<MCDecodedPseudoProbe>>
365
+ InjectedProbeMap;
366
+ // Decoded inline records vector.
367
+ std::vector<MCDecodedPseudoProbeInlineTree> InlineTreeVec;
368
+
339
369
// GUID to PseudoProbeFuncDesc map.
340
370
GUIDProbeFunctionMap GUID2FuncDescMap;
341
371
@@ -382,10 +412,6 @@ class MCPseudoProbeDecoder {
382
412
const Uint64Set &GuildFilter,
383
413
const Uint64Map &FuncStartAddrs);
384
414
385
- bool buildAddress2ProbeMap (MCDecodedPseudoProbeInlineTree *Cur,
386
- uint64_t &LastAddr, const Uint64Set &GuildFilter,
387
- const Uint64Map &FuncStartAddrs);
388
-
389
415
// Print pseudo_probe_desc section info
390
416
void printGUID2FuncDescMap (raw_ostream &OS);
391
417
@@ -428,6 +454,34 @@ class MCPseudoProbeDecoder {
428
454
const MCDecodedPseudoProbeInlineTree &getDummyInlineRoot () const {
429
455
return DummyInlineRoot;
430
456
}
457
+
458
+ void addInjectedProbe (const MCDecodedPseudoProbe &Probe, uint64_t Address) {
459
+ const MCDecodedPseudoProbeInlineTree *Parent = Probe.getInlineTreeNode ();
460
+ InjectedProbeMap[Parent].emplace_back (Probe).setAddress (Address);
461
+ }
462
+
463
+ size_t
464
+ getNumInjectedProbes (const MCDecodedPseudoProbeInlineTree *Parent) const {
465
+ auto It = InjectedProbeMap.find (Parent);
466
+ if (It == InjectedProbeMap.end ())
467
+ return 0 ;
468
+ return It->second .size ();
469
+ }
470
+
471
+ auto getInjectedProbes (MCDecodedPseudoProbeInlineTree *Parent) {
472
+ auto It = InjectedProbeMap.find (Parent);
473
+ assert (It != InjectedProbeMap.end ());
474
+ return iterator_range (It->second );
475
+ }
476
+
477
+ private:
478
+ // Recursively parse an inlining tree encoded in pseudo_probe section. Returns
479
+ // whether the the top-level node should be skipped.
480
+ template <bool IsTopLevelFunc>
481
+ bool buildAddress2ProbeMap (MCDecodedPseudoProbeInlineTree *Cur,
482
+ uint64_t &LastAddr, const Uint64Set &GuildFilter,
483
+ const Uint64Map &FuncStartAddrs,
484
+ const uint32_t CurChildIndex);
431
485
};
432
486
433
487
} // end namespace llvm
0 commit comments