123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- #ifndef LLVM_MC_MCPSEUDOPROBE_H
- #define LLVM_MC_MCPSEUDOPROBE_H
- #include "llvm/ADT/DenseSet.h"
- #include "llvm/ADT/SmallVector.h"
- #include "llvm/ADT/StringRef.h"
- #include "llvm/IR/PseudoProbe.h"
- #include "llvm/Support/ErrorOr.h"
- #include <list>
- #include <map>
- #include <memory>
- #include <string>
- #include <tuple>
- #include <type_traits>
- #include <unordered_map>
- #include <unordered_set>
- #include <vector>
- namespace llvm {
- class MCSymbol;
- class MCObjectStreamer;
- class raw_ostream;
- enum class MCPseudoProbeFlag {
-
-
- AddressDelta = 0x1,
- };
- struct MCPseudoProbeFuncDesc {
- uint64_t FuncGUID = 0;
- uint64_t FuncHash = 0;
- std::string FuncName;
- MCPseudoProbeFuncDesc(uint64_t GUID, uint64_t Hash, StringRef Name)
- : FuncGUID(GUID), FuncHash(Hash), FuncName(Name){};
- void print(raw_ostream &OS);
- };
- class MCDecodedPseudoProbe;
- using InlineSite = std::tuple<uint64_t, uint32_t>;
- using MCPseudoProbeInlineStack = SmallVector<InlineSite, 8>;
- using GUIDProbeFunctionMap =
- std::unordered_map<uint64_t, MCPseudoProbeFuncDesc>;
- using AddressProbesMap =
- std::unordered_map<uint64_t, std::list<MCDecodedPseudoProbe>>;
- class MCDecodedPseudoProbeInlineTree;
- class MCPseudoProbeBase {
- protected:
- uint64_t Guid;
- uint64_t Index;
- uint8_t Attributes;
- uint8_t Type;
-
-
-
- const static uint32_t PseudoProbeFirstId = 1;
- public:
- MCPseudoProbeBase(uint64_t G, uint64_t I, uint64_t At, uint8_t T)
- : Guid(G), Index(I), Attributes(At), Type(T) {}
- bool isEntry() const { return Index == PseudoProbeFirstId; }
- uint64_t getGuid() const { return Guid; }
- uint64_t getIndex() const { return Index; }
- uint8_t getAttributes() const { return Attributes; }
- uint8_t getType() const { return Type; }
- bool isBlock() const {
- return Type == static_cast<uint8_t>(PseudoProbeType::Block);
- }
- bool isIndirectCall() const {
- return Type == static_cast<uint8_t>(PseudoProbeType::IndirectCall);
- }
- bool isDirectCall() const {
- return Type == static_cast<uint8_t>(PseudoProbeType::DirectCall);
- }
- bool isCall() const { return isIndirectCall() || isDirectCall(); }
- void setAttributes(uint8_t Attr) { Attributes = Attr; }
- };
- class MCPseudoProbe : public MCPseudoProbeBase {
- MCSymbol *Label;
- public:
- MCPseudoProbe(MCSymbol *Label, uint64_t Guid, uint64_t Index, uint64_t Type,
- uint64_t Attributes)
- : MCPseudoProbeBase(Guid, Index, Attributes, Type), Label(Label) {
- 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; }
- void emit(MCObjectStreamer *MCOS, const MCPseudoProbe *LastProbe) const;
- };
- using MCPseduoProbeFrameLocation = std::pair<StringRef, uint32_t>;
- class MCDecodedPseudoProbe : public MCPseudoProbeBase {
- uint64_t Address;
- MCDecodedPseudoProbeInlineTree *InlineTree;
- public:
- MCDecodedPseudoProbe(uint64_t Ad, uint64_t G, uint32_t I, PseudoProbeType K,
- uint8_t At, MCDecodedPseudoProbeInlineTree *Tree)
- : MCPseudoProbeBase(G, I, At, static_cast<uint8_t>(K)), Address(Ad),
- InlineTree(Tree){};
- uint64_t getAddress() const { return Address; }
- void setAddress(uint64_t Addr) { Address = Addr; }
- MCDecodedPseudoProbeInlineTree *getInlineTreeNode() const {
- return InlineTree;
- }
-
-
-
- void
- getInlineContext(SmallVectorImpl<MCPseduoProbeFrameLocation> &ContextStack,
- const GUIDProbeFunctionMap &GUID2FuncMAP) const;
-
- std::string
- getInlineContextStr(const GUIDProbeFunctionMap &GUID2FuncMAP) const;
-
- void print(raw_ostream &OS, const GUIDProbeFunctionMap &GUID2FuncMAP,
- bool ShowName) const;
- };
- template <typename ProbeType, typename DerivedProbeInlineTreeType>
- class MCPseudoProbeInlineTreeBase {
- struct InlineSiteHash {
- uint64_t operator()(const InlineSite &Site) const {
- return std::get<0>(Site) ^ std::get<1>(Site);
- }
- };
- protected:
-
- using InlinedProbeTreeMap = std::unordered_map<
- InlineSite, std::unique_ptr<DerivedProbeInlineTreeType>, InlineSiteHash>;
- InlinedProbeTreeMap Children;
-
- std::vector<ProbeType> Probes;
- MCPseudoProbeInlineTreeBase() {
- static_assert(std::is_base_of<MCPseudoProbeInlineTreeBase,
- DerivedProbeInlineTreeType>::value,
- "DerivedProbeInlineTreeType must be subclass of "
- "MCPseudoProbeInlineTreeBase");
- }
- public:
- uint64_t Guid = 0;
-
- bool isRoot() const { return Guid == 0; }
- InlinedProbeTreeMap &getChildren() { return Children; }
- const InlinedProbeTreeMap &getChildren() const { return Children; }
- std::vector<ProbeType> &getProbes() { return Probes; }
- void addProbes(ProbeType Probe) { Probes.push_back(Probe); }
-
- MCPseudoProbeInlineTreeBase<ProbeType, DerivedProbeInlineTreeType> *Parent;
- DerivedProbeInlineTreeType *getOrAddNode(const InlineSite &Site) {
- auto Ret = Children.emplace(
- Site, std::make_unique<DerivedProbeInlineTreeType>(Site));
- Ret.first->second->Parent = this;
- return Ret.first->second.get();
- };
- };
- class MCPseudoProbeInlineTree
- : public MCPseudoProbeInlineTreeBase<MCPseudoProbe,
- MCPseudoProbeInlineTree> {
- public:
- MCPseudoProbeInlineTree() = default;
- MCPseudoProbeInlineTree(uint64_t Guid) { this->Guid = Guid; }
- MCPseudoProbeInlineTree(const InlineSite &Site) {
- this->Guid = std::get<0>(Site);
- }
-
- void addPseudoProbe(const MCPseudoProbe &Probe,
- const MCPseudoProbeInlineStack &InlineStack);
- void emit(MCObjectStreamer *MCOS, const MCPseudoProbe *&LastProbe);
- };
- class MCDecodedPseudoProbeInlineTree
- : public MCPseudoProbeInlineTreeBase<MCDecodedPseudoProbe *,
- MCDecodedPseudoProbeInlineTree> {
- public:
- InlineSite ISite;
-
- uint32_t ChildrenToProcess = 0;
- MCDecodedPseudoProbeInlineTree() = default;
- MCDecodedPseudoProbeInlineTree(const InlineSite &Site) : ISite(Site){};
-
- bool hasInlineSite() const { return !isRoot() && !Parent->isRoot(); }
- };
- class MCPseudoProbeSections {
- public:
- void addPseudoProbe(MCSymbol *FuncSym, const MCPseudoProbe &Probe,
- const MCPseudoProbeInlineStack &InlineStack) {
- MCProbeDivisions[FuncSym].addPseudoProbe(Probe, InlineStack);
- }
-
- using MCProbeDivisionMap = std::map<MCSymbol *, MCPseudoProbeInlineTree>;
- private:
-
-
-
- MCProbeDivisionMap MCProbeDivisions;
- public:
- const MCProbeDivisionMap &getMCProbes() const { return MCProbeDivisions; }
- bool empty() const { return MCProbeDivisions.empty(); }
- void emit(MCObjectStreamer *MCOS);
- };
- class MCPseudoProbeTable {
-
-
-
-
-
-
- MCPseudoProbeSections MCProbeSections;
- public:
- static void emit(MCObjectStreamer *MCOS);
- MCPseudoProbeSections &getProbeSections() { return MCProbeSections; }
- #ifndef NDEBUG
- static int DdgPrintIndent;
- #endif
- };
- class MCPseudoProbeDecoder {
-
- GUIDProbeFunctionMap GUID2FuncDescMap;
-
- AddressProbesMap Address2ProbesMap;
-
-
-
-
- MCDecodedPseudoProbeInlineTree DummyInlineRoot;
-
- const uint8_t *Data = nullptr;
-
- const uint8_t *End = nullptr;
-
- bool EncodingIsAddrBased = false;
-
- template <typename T> ErrorOr<T> readUnencodedNumber();
- template <typename T> ErrorOr<T> readUnsignedNumber();
- template <typename T> ErrorOr<T> readSignedNumber();
- ErrorOr<StringRef> readString(uint32_t Size);
- public:
- using Uint64Set = DenseSet<uint64_t>;
- using Uint64Map = DenseMap<uint64_t, uint64_t>;
-
- bool buildGUID2FuncDescMap(const uint8_t *Start, std::size_t Size);
-
-
- bool buildAddress2ProbeMap(const uint8_t *Start, std::size_t Size,
- const Uint64Set &GuildFilter,
- const Uint64Map &FuncStartAddrs);
- bool buildAddress2ProbeMap(MCDecodedPseudoProbeInlineTree *Cur,
- uint64_t &LastAddr, const Uint64Set &GuildFilter,
- const Uint64Map &FuncStartAddrs);
-
- void printGUID2FuncDescMap(raw_ostream &OS);
-
- void printProbeForAddress(raw_ostream &OS, uint64_t Address);
-
- void printProbesForAllAddresses(raw_ostream &OS);
-
- const MCDecodedPseudoProbe *getCallProbeForAddr(uint64_t Address) const;
- const MCPseudoProbeFuncDesc *getFuncDescForGUID(uint64_t GUID) const;
-
-
-
-
-
-
-
- void getInlineContextForProbe(
- const MCDecodedPseudoProbe *Probe,
- SmallVectorImpl<MCPseduoProbeFrameLocation> &InlineContextStack,
- bool IncludeLeaf) const;
- const AddressProbesMap &getAddress2ProbesMap() const {
- return Address2ProbesMap;
- }
- AddressProbesMap &getAddress2ProbesMap() { return Address2ProbesMap; }
- const GUIDProbeFunctionMap &getGUID2FuncDescMap() const {
- return GUID2FuncDescMap;
- }
- const MCPseudoProbeFuncDesc *
- getInlinerDescForProbe(const MCDecodedPseudoProbe *Probe) const;
- const MCDecodedPseudoProbeInlineTree &getDummyInlineRoot() const {
- return DummyInlineRoot;
- }
- };
- }
- #endif
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|