| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- //===- MCPseudoProbe.h - Pseudo probe encoding support ---------*- C++ -*-===//
- //
- // 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 contains the declaration of the MCPseudoProbe to support the pseudo
- // probe encoding for AutoFDO. Pseudo probes together with their inline context
- // are encoded in a DFS recursive way in the .pseudoprobe sections. For each
- // .pseudoprobe section, the encoded binary data consist of a single or mutiple
- // function records each for one outlined function. A function record has the
- // following format :
- //
- // FUNCTION BODY (one for each outlined function present in the text section)
- // GUID (uint64)
- // GUID of the function
- // NPROBES (ULEB128)
- // Number of probes originating from this function.
- // NUM_INLINED_FUNCTIONS (ULEB128)
- // Number of callees inlined into this function, aka number of
- // first-level inlinees
- // PROBE RECORDS
- // A list of NPROBES entries. Each entry contains:
- // INDEX (ULEB128)
- // TYPE (uint4)
- // 0 - block probe, 1 - indirect call, 2 - direct call
- // ATTRIBUTE (uint3)
- // 1 - reserved, 2 - dangling
- // ADDRESS_TYPE (uint1)
- // 0 - code address, 1 - address delta
- // CODE_ADDRESS (uint64 or ULEB128)
- // code address or address delta, depending on ADDRESS_TYPE
- // INLINED FUNCTION RECORDS
- // A list of NUM_INLINED_FUNCTIONS entries describing each of the inlined
- // callees. Each record contains:
- // INLINE SITE
- // ID of the callsite probe (ULEB128)
- // FUNCTION BODY
- // A FUNCTION BODY entry describing the inlined function.
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_MC_MCPSEUDOPROBE_H
- #define LLVM_MC_MCPSEUDOPROBE_H
- #include "llvm/ADT/MapVector.h"
- #include "llvm/MC/MCSection.h"
- #include <functional>
- #include <map>
- #include <vector>
- namespace llvm {
- class MCStreamer;
- class MCSymbol;
- class MCObjectStreamer;
- enum class MCPseudoProbeFlag {
- // If set, indicates that the probe is encoded as an address delta
- // instead of a real code address.
- AddressDelta = 0x1,
- };
- /// Instances of this class represent a pseudo probe instance for a pseudo probe
- /// table entry, which is created during a machine instruction is assembled and
- /// uses an address from a temporary label created at the current address in the
- /// current section.
- class MCPseudoProbe {
- MCSymbol *Label;
- uint64_t Guid;
- uint64_t Index;
- uint8_t Type;
- uint8_t Attributes;
- public:
- MCPseudoProbe(MCSymbol *Label, uint64_t Guid, uint64_t Index, uint64_t Type,
- uint64_t Attributes)
- : Label(Label), Guid(Guid), Index(Index), Type(Type),
- Attributes(Attributes) {
- assert(Type <= 0xFF && "Probe type too big to encode, exceeding 2^8");
- assert(Attributes <= 0xFF &&
- "Probe attributes too big to encode, exceeding 2^16");
- }
- MCSymbol *getLabel() const { return Label; }
- uint64_t getGuid() const { return Guid; }
- uint64_t getIndex() const { return Index; }
- uint8_t getType() const { return Type; }
- uint8_t getAttributes() const { return Attributes; }
- void emit(MCObjectStreamer *MCOS, const MCPseudoProbe *LastProbe) const;
- };
- // An inline frame has the form <Guid, ProbeID>
- using InlineSite = std::tuple<uint64_t, uint32_t>;
- using MCPseudoProbeInlineStack = SmallVector<InlineSite, 8>;
- // A Tri-tree based data structure to group probes by inline stack.
- // A tree is allocated for a standalone .text section. A fake
- // instance is created as the root of a tree.
- // A real instance of this class is created for each function, either an
- // unlined function that has code in .text section or an inlined function.
- class MCPseudoProbeInlineTree {
- uint64_t Guid;
- // Set of probes that come with the function.
- std::vector<MCPseudoProbe> Probes;
- // Use std::map for a deterministic output.
- std::map<InlineSite, MCPseudoProbeInlineTree *> Inlinees;
- // Root node has a GUID 0.
- bool isRoot() { return Guid == 0; }
- MCPseudoProbeInlineTree *getOrAddNode(InlineSite Site);
- public:
- MCPseudoProbeInlineTree() = default;
- MCPseudoProbeInlineTree(uint64_t Guid) : Guid(Guid) {}
- ~MCPseudoProbeInlineTree();
- void addPseudoProbe(const MCPseudoProbe &Probe,
- const MCPseudoProbeInlineStack &InlineStack);
- void emit(MCObjectStreamer *MCOS, const MCPseudoProbe *&LastProbe);
- };
- /// Instances of this class represent the pseudo probes inserted into a compile
- /// unit.
- class MCPseudoProbeSection {
- public:
- void addPseudoProbe(MCSection *Sec, const MCPseudoProbe &Probe,
- const MCPseudoProbeInlineStack &InlineStack) {
- MCProbeDivisions[Sec].addPseudoProbe(Probe, InlineStack);
- }
- // TODO: Sort by getOrdinal to ensure a determinstic section order
- using MCProbeDivisionMap = std::map<MCSection *, MCPseudoProbeInlineTree>;
- private:
- // A collection of MCPseudoProbe for each text section. The MCPseudoProbes
- // are grouped by GUID of the functions where they are from and will be
- // encoded by groups. In the comdat scenario where a text section really only
- // contains the code of a function solely, the probes associated with a comdat
- // function are still grouped by GUIDs due to inlining that can bring probes
- // from different functions into one function.
- MCProbeDivisionMap MCProbeDivisions;
- public:
- const MCProbeDivisionMap &getMCProbes() const { return MCProbeDivisions; }
- bool empty() const { return MCProbeDivisions.empty(); }
- void emit(MCObjectStreamer *MCOS);
- };
- class MCPseudoProbeTable {
- // A collection of MCPseudoProbe in the current module grouped by text
- // sections. MCPseudoProbes will be encoded into a corresponding
- // .pseudoprobe section. With functions emitted as separate comdats,
- // a text section really only contains the code of a function solely, and the
- // probes associated with the text section will be emitted into a standalone
- // .pseudoprobe section that shares the same comdat group with the function.
- MCPseudoProbeSection MCProbeSections;
- public:
- static void emit(MCObjectStreamer *MCOS);
- MCPseudoProbeSection &getProbeSections() { return MCProbeSections; }
- #ifndef NDEBUG
- static int DdgPrintIndent;
- #endif
- };
- } // end namespace llvm
- #endif // LLVM_MC_MCPSEUDOPROBE_H
|