Go to the documentation of this file.
23 #define DEBUG_TYPE "mcpseudoprobe"
51 assert(
Type <= 0xF &&
"Probe type too big to encode, exceeding 15");
53 "Probe attributes too big to encode, exceeding 7");
83 assert(isRoot() &&
"Should not be called on root");
98 if (InlineStack.empty()) {
101 Top =
InlineSite(std::get<0>(InlineStack.front()), 0);
104 auto *Cur = getOrAddNode(Top);
108 if (!InlineStack.empty()) {
109 auto Iter = InlineStack.begin();
110 auto Index = std::get<1>(*Iter);
112 for (; Iter != InlineStack.end(); Iter++) {
115 Index = std::get<1>(*Iter);
120 Cur->Probes.push_back(Probe);
127 dbgs() <<
"Group [\n";
134 dbgs() <<
"GUID: " << Guid <<
"\n";
143 for (
const auto &Probe : Probes) {
144 Probe.emit(MCOS, LastProbe);
148 assert(Probes.empty() &&
"Root should not have probes");
154 std::map<InlineSite, MCPseudoProbeInlineTree *> Inlinees;
155 for (
auto &Child : Children)
156 Inlinees[Child.first] = Child.second.get();
158 for (
const auto &Inlinee : Inlinees) {
164 dbgs() <<
"InlineSite: " << std::get<1>(Inlinee.first) <<
"\n";
168 Inlinee.second->emit(MCOS, LastProbe);
181 for (
auto &ProbeSec : MCProbeDivisions) {
188 ProbeSec.second.emit(MCOS, LastProbe);
203 if (ProbeSections.empty())
209 ProbeSections.emit(MCOS);
214 auto It = GUID2FuncMAP.
find(GUID);
215 assert(It != GUID2FuncMAP.end() &&
216 "Probe function must exist for a valid GUID");
217 return It->second.FuncName;
221 OS <<
"GUID: " << FuncGUID <<
" Name: " << FuncName <<
"\n";
222 OS <<
"Hash: " << FuncHash <<
"\n";
228 uint32_t Begin = ContextStack.size();
239 std::reverse(ContextStack.begin() + Begin, ContextStack.end());
244 std::ostringstream OContextStr;
246 getInlineContext(ContextStack, GUID2FuncMAP);
247 for (
auto &Cxt : ContextStack) {
248 if (OContextStr.str().size())
249 OContextStr <<
" @ ";
250 OContextStr << Cxt.first.str() <<
":" << Cxt.second;
252 return OContextStr.str();
260 bool ShowName)
const {
264 OS << FuncName.
str() <<
" ";
268 OS <<
"Index: " <<
Index <<
" ";
270 std::string InlineContextStr = getInlineContextStr(GUID2FuncMAP);
271 if (InlineContextStr.size()) {
273 OS << InlineContextStr;
278 template <
typename T>
ErrorOr<T> MCPseudoProbeDecoder::readUnencodedNumber() {
279 if (Data +
sizeof(T) > End) {
280 return std::error_code();
282 T Val = endian::readNext<T, little, unaligned>(Data);
286 template <
typename T>
ErrorOr<T> MCPseudoProbeDecoder::readUnsignedNumber() {
287 unsigned NumBytesRead = 0;
290 return std::error_code();
292 Data += NumBytesRead;
296 template <
typename T>
ErrorOr<T> MCPseudoProbeDecoder::readSignedNumber() {
297 unsigned NumBytesRead = 0;
300 return std::error_code();
302 Data += NumBytesRead;
307 StringRef Str(
reinterpret_cast<const char *
>(Data), Size);
308 if (Data + Size > End) {
309 return std::error_code();
332 auto ErrorOrGUID = readUnencodedNumber<uint64_t>();
336 auto ErrorOrHash = readUnencodedNumber<uint64_t>();
340 auto ErrorOrNameSize = readUnsignedNumber<uint32_t>();
341 if (!ErrorOrNameSize)
356 assert(
Data == End &&
"Have unprocessed data in pseudo_probe_desc section");
362 std::unordered_set<uint64_t> &GuildFilter) {
394 if (Cur == &DummyInlineRoot) {
399 auto ErrorOrIndex = readUnsignedNumber<uint32_t>();
406 auto ErrorOrCurGuid = readUnencodedNumber<uint64_t>();
412 if (Cur == &DummyInlineRoot && !GuildFilter.empty() &&
413 !GuildFilter.count(Guid))
424 auto ErrorOrNodeCount = readUnsignedNumber<uint32_t>();
425 if (!ErrorOrNodeCount)
429 auto ErrorOrCurChildrenToProcess = readUnsignedNumber<uint32_t>();
430 if (!ErrorOrCurChildrenToProcess)
433 for (std::size_t
I = 0;
I < NodeCount;
I++) {
435 auto ErrorOrIndex = readUnsignedNumber<uint32_t>();
440 auto ErrorOrValue = readUnencodedNumber<uint8_t>();
445 uint8_t Attr = (
Value & 0x70) >> 4;
449 auto ErrorOrOffset = readSignedNumber<int64_t>();
452 int64_t Offset =
std::move(*ErrorOrOffset);
453 Addr = LastAddr + Offset;
455 auto ErrorOrAddr = readUnencodedNumber<int64_t>();
463 auto &Probes = Address2ProbesMap[
Addr];
473 buildAddress2ProbeMap(Cur, LastAddr, GuildFilter);
480 const uint8_t *Start, std::size_t Size,
481 std::unordered_set<uint64_t> &GuildFilter) {
486 buildAddress2ProbeMap(&DummyInlineRoot, LastAddr, GuildFilter);
487 assert(
Data == End &&
"Have unprocessed data in pseudo_probe section");
493 std::unordered_set<uint64_t> GuildFilter;
494 return buildAddress2ProbeMap(Start, Size, GuildFilter);
498 OS <<
"Pseudo Probe Desc:\n";
500 std::map<uint64_t, MCPseudoProbeFuncDesc> OrderedMap(GUID2FuncDescMap.begin(),
501 GUID2FuncDescMap.end());
502 for (
auto &
I : OrderedMap) {
509 auto It = Address2ProbesMap.find(Address);
510 if (It != Address2ProbesMap.end()) {
511 for (
auto &Probe : It->second) {
513 Probe.print(OS, GUID2FuncDescMap,
true);
519 std::vector<uint64_t> Addresses;
520 for (
auto Entry : Address2ProbesMap)
521 Addresses.push_back(Entry.first);
522 std::sort(Addresses.begin(), Addresses.end());
523 for (
auto K : Addresses) {
527 printProbeForAddress(OS, K);
533 auto It = Address2ProbesMap.find(Address);
534 if (It == Address2ProbesMap.end())
536 const auto &Probes = It->second;
539 for (
const auto &Probe : Probes) {
540 if (Probe.isCall()) {
542 "There should be only one call probe corresponding to address "
543 "which is a callsite.");
552 auto It = GUID2FuncDescMap.find(GUID);
553 assert(It != GUID2FuncDescMap.end() &&
"Function descriptor doesn't exist");
560 bool IncludeLeaf)
const {
566 const auto *FuncDesc = getFuncDescForGUID(Probe->
getGuid());
576 return getFuncDescForGUID(InlinerNode->
Parent->
Guid);
std::unordered_map< uint64_t, MCPseudoProbeFuncDesc > GUIDProbeFunctionMap
const MCObjectFileInfo * getObjectFileInfo() const
void printProbeForAddress(raw_ostream &OS, uint64_t Address)
This is an optimization pass for GlobalISel generic memory operations.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
std::tuple< uint64_t, uint32_t > InlineSite
void print(raw_ostream &OS, const GUIDProbeFunctionMap &GUID2FuncMAP, bool ShowName) const
Context object for machine code objects.
void emitInt64(uint64_t Value)
LLVM_NODISCARD size_t find(char C, size_t From=0) const
Search for the first character C in the string.
void emitInt8(uint64_t Value)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
void emit(MCObjectStreamer *MCOS)
Instances of this class represent a pseudo probe instance for a pseudo probe table entry,...
void addPseudoProbe(const MCPseudoProbe &Probe, const MCPseudoProbeInlineStack &InlineStack)
The instances of the Type class are immutable: once they are created, they are never changed.
auto reverse(ContainerTy &&C, std::enable_if_t< has_rbegin< ContainerTy >::value > *=nullptr)
unsigned getCodePointerSize() const
Get the code pointer size in bytes.
MCSection * getPseudoProbeSection(const MCSection *TextSec) const
Expected< ExpressionValue > max(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
MCPseudoProbeSection & getProbeSections()
uint64_t decodeULEB128(const uint8_t *p, unsigned *n=nullptr, const uint8_t *end=nullptr, const char **error=nullptr)
Utility function to decode a ULEB128 value.
void print(raw_ostream &OS)
MCDecodedPseudoProbeInlineTree * getInlineTreeNode() const
MCPseudoProbeTable & getMCPseudoProbeTable()
virtual void switchSection(MCSection *Section, const MCExpr *Subsection=nullptr)
Set the current section where code is being emitted to Section.
void emitSymbolValue(const MCSymbol *Sym, unsigned Size, bool IsSectionRelative=false)
Special case of EmitValue that avoids the client having to pass in a MCExpr for MCSymbols.
Streaming object file generation interface.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Flag
These should be considered private to the implementation of the MCInstrDesc class.
void emit(MCObjectStreamer *MCOS, const MCPseudoProbe *&LastProbe)
void getInlineContextForProbe(const MCDecodedPseudoProbe *Probe, SmallVectorImpl< MCPseduoProbeFrameLocation > &InlineContextStack, bool IncludeLeaf) const
This class implements an extremely fast bulk output stream that can only output to a stream.
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
bool buildGUID2FuncDescMap(const uint8_t *Start, std::size_t Size)
DerivedProbeInlineTreeType * getOrAddNode(const InlineSite &Site)
static StringRef getProbeFNameForGUID(const GUIDProbeFunctionMap &GUID2FuncMAP, uint64_t GUID)
static const MCExpr * buildSymbolDiff(MCObjectStreamer *MCOS, const MCSymbol *A, const MCSymbol *B)
InlinedProbeTreeMap & getChildren()
void emit(MCObjectStreamer *MCOS, const MCPseudoProbe *LastProbe) const
bool buildAddress2ProbeMap(const uint8_t *Start, std::size_t Size)
const MCAsmInfo * getAsmInfo() const
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
static const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
void insert(MCFragment *F)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
MCSymbol * getLabel() const
MCPseudoProbeInlineTreeBase< ProbeType, DerivedProbeInlineTreeType > * Parent
std::string getInlineContextStr(const GUIDProbeFunctionMap &GUID2FuncMAP) const
StringRef - Represent a constant reference to a string, i.e.
void printGUID2FuncDescMap(raw_ostream &OS)
static const char * PseudoProbeTypeStr[3]
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
void addProbes(ProbeType Probe)
static int DdgPrintIndent
void emitSLEB128IntValue(int64_t Value)
Special case of EmitSLEB128Value that avoids the client having to pass in a MCExpr for constant integ...
uint64_t getIndex() const
void sort(IteratorTy Start, IteratorTy End)
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
bool hasInlineSite() const
const MCDecodedPseudoProbe * getCallProbeForAddr(uint64_t Address) const
void printProbesForAllAddresses(raw_ostream &OS)
int64_t decodeSLEB128(const uint8_t *p, unsigned *n=nullptr, const uint8_t *end=nullptr, const char **error=nullptr)
Utility function to decode a SLEB128 value.
const MCPseudoProbeFuncDesc * getFuncDescForGUID(uint64_t GUID) const
void emitULEB128IntValue(uint64_t Value, unsigned PadTo=0)
Special case of EmitULEB128Value that avoids the client having to pass in a MCExpr for constant integ...
MCContext & getContext() const
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
Represents either an error or a value T.
Reimplement select in terms of SEL *We would really like to support but we need to prove that the add doesn t need to overflow between the two bit chunks *Implement pre post increment support(e.g. PR935) *Implement smarter const ant generation for binops with large immediates. A few ARMv6T2 ops should be pattern matched
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void getInlineContext(SmallVectorImpl< MCPseduoProbeFrameLocation > &ContextStack, const GUIDProbeFunctionMap &GUID2FuncMAP) const
std::pair< StringRef, uint32_t > MCPseduoProbeFrameLocation
const MCPseudoProbeFuncDesc * getInlinerDescForProbe(const MCDecodedPseudoProbe *Probe) const
static StringRef readString(WasmObjectFile::ReadContext &Ctx)
LLVM Value Representation.
Base class for the full range of assembler expressions which are needed for parsing.
reference emplace_back(ArgTypes &&... Args)
MCAssembler * getAssemblerPtr() override
static void emit(MCObjectStreamer *MCOS)