diff --git a/llvm/include/llvm/IR/PseudoProbe.h b/llvm/include/llvm/IR/PseudoProbe.h --- a/llvm/include/llvm/IR/PseudoProbe.h +++ b/llvm/include/llvm/IR/PseudoProbe.h @@ -24,8 +24,15 @@ constexpr const char *PseudoProbeDescMetadataName = "llvm.pseudo_probe_desc"; +enum class PseudoProbeReservedId { Invalid = 0, Last = Invalid }; + enum class PseudoProbeType { Block = 0, IndirectCall, DirectCall }; +enum class PseudoProbeAttributes { + Reserved = 0x1, + Sentinel = 0x2, // A place holder for function entry address. +}; + // The saturated distrution factor representing 100% for block probes. constexpr static uint64_t PseudoProbeFullDistributionFactor = std::numeric_limits::max(); @@ -80,6 +87,10 @@ float Factor; }; +static inline bool isSentinelProbe(uint32_t Flags) { + return Flags & (uint32_t)PseudoProbeAttributes::Sentinel; +} + Optional extractProbe(const Instruction &Inst); void setProbeDistributionFactor(Instruction &Inst, float Factor); diff --git a/llvm/include/llvm/MC/MCObjectFileInfo.h b/llvm/include/llvm/MC/MCObjectFileInfo.h --- a/llvm/include/llvm/MC/MCObjectFileInfo.h +++ b/llvm/include/llvm/MC/MCObjectFileInfo.h @@ -362,7 +362,7 @@ MCSection *getKCFITrapSection(const MCSection &TextSec) const; - MCSection *getPseudoProbeSection(const MCSection *TextSec) const; + MCSection *getPseudoProbeSection(const MCSection &TextSec) const; MCSection *getPseudoProbeDescSection(StringRef FuncName) const; diff --git a/llvm/include/llvm/MC/MCPseudoProbe.h b/llvm/include/llvm/MC/MCPseudoProbe.h --- a/llvm/include/llvm/MC/MCPseudoProbe.h +++ b/llvm/include/llvm/MC/MCPseudoProbe.h @@ -29,7 +29,9 @@ // ATTRIBUTE (uint3) // 1 - reserved // ADDRESS_TYPE (uint1) -// 0 - code address, 1 - address delta +// 0 - code address for regular probes +// - GUID of linkage name for sentinel probes +// 1 - address delta // CODE_ADDRESS (uint64 or ULEB128) // code address or address delta, depending on ADDRESS_TYPE // INLINED FUNCTION RECORDS @@ -276,23 +278,19 @@ /// Instances of this class represent the pseudo probes inserted into a compile /// unit. -class MCPseudoProbeSection { +class MCPseudoProbeSections { public: - void addPseudoProbe(MCSection *Sec, const MCPseudoProbe &Probe, + void addPseudoProbe(MCSymbol *FuncSym, const MCPseudoProbe &Probe, const MCPseudoProbeInlineStack &InlineStack) { - MCProbeDivisions[Sec].addPseudoProbe(Probe, InlineStack); + MCProbeDivisions[FuncSym].addPseudoProbe(Probe, InlineStack); } // TODO: Sort by getOrdinal to ensure a determinstic section order - using MCProbeDivisionMap = std::map; + using MCProbeDivisionMap = std::map; 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. + // A collection of MCPseudoProbe for each binary function. The MCPseudoProbes + // are grouped by GUIDs due to inlining that can bring probes from different functions into one function. MCProbeDivisionMap MCProbeDivisions; public: @@ -304,18 +302,18 @@ }; class MCPseudoProbeTable { - // A collection of MCPseudoProbe in the current module grouped by text - // sections. MCPseudoProbes will be encoded into a corresponding + // A collection of MCPseudoProbe in the current module grouped by binary + // functions. 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; + MCPseudoProbeSections MCProbeSections; public: static void emit(MCObjectStreamer *MCOS); - MCPseudoProbeSection &getProbeSections() { return MCProbeSections; } + MCPseudoProbeSections &getProbeSections() { return MCProbeSections; } #ifndef NDEBUG static int DdgPrintIndent; diff --git a/llvm/include/llvm/MC/MCStreamer.h b/llvm/include/llvm/MC/MCStreamer.h --- a/llvm/include/llvm/MC/MCStreamer.h +++ b/llvm/include/llvm/MC/MCStreamer.h @@ -1105,7 +1105,8 @@ /// Emit the a pseudo probe into the current section. virtual void emitPseudoProbe(uint64_t Guid, uint64_t Index, uint64_t Type, uint64_t Attr, - const MCPseudoProbeInlineStack &InlineStack); + const MCPseudoProbeInlineStack &InlineStack, + MCSymbol *FnSym); /// Set the bundle alignment mode from now on in the section. /// The argument is the power of 2 to which the alignment is set. The diff --git a/llvm/include/llvm/Transforms/IPO/SampleProfileProbe.h b/llvm/include/llvm/Transforms/IPO/SampleProfileProbe.h --- a/llvm/include/llvm/Transforms/IPO/SampleProfileProbe.h +++ b/llvm/include/llvm/Transforms/IPO/SampleProfileProbe.h @@ -41,8 +41,6 @@ pair_hash>; using FuncProbeFactorMap = StringMap; -enum class PseudoProbeReservedId { Invalid = 0, Last = Invalid }; - class PseudoProbeDescriptor { uint64_t FunctionGUID; uint64_t FunctionHash; diff --git a/llvm/lib/CodeGen/AsmPrinter/PseudoProbePrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/PseudoProbePrinter.cpp --- a/llvm/lib/CodeGen/AsmPrinter/PseudoProbePrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/PseudoProbePrinter.cpp @@ -48,5 +48,6 @@ } SmallVector InlineStack(llvm::reverse(ReversedInlineStack)); - Asm->OutStreamer->emitPseudoProbe(Guid, Index, Type, Attr, InlineStack); + Asm->OutStreamer->emitPseudoProbe(Guid, Index, Type, Attr, InlineStack, + Asm->CurrentFnSym); } diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp --- a/llvm/lib/MC/MCAsmStreamer.cpp +++ b/llvm/lib/MC/MCAsmStreamer.cpp @@ -378,7 +378,7 @@ void emitPseudoProbe(uint64_t Guid, uint64_t Index, uint64_t Type, uint64_t Attr, - const MCPseudoProbeInlineStack &InlineStack) override; + const MCPseudoProbeInlineStack &InlineStack, MCSymbol *FnSym) override; void emitBundleAlignMode(unsigned AlignPow2) override; void emitBundleLock(bool AlignToEnd) override; @@ -2338,13 +2338,16 @@ void MCAsmStreamer::emitPseudoProbe( uint64_t Guid, uint64_t Index, uint64_t Type, uint64_t Attr, - const MCPseudoProbeInlineStack &InlineStack) { + const MCPseudoProbeInlineStack &InlineStack, MCSymbol *FnSym) { OS << "\t.pseudoprobe\t" << Guid << " " << Index << " " << Type << " " << Attr; // Emit inline stack like // @ GUIDmain:3 @ GUIDCaller:1 @ GUIDDirectCaller:11 for (const auto &Site : InlineStack) OS << " @ " << std::get<0>(Site) << ":" << std::get<1>(Site); + + OS << " " << FnSym->getName(); + EmitEOL(); } diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp --- a/llvm/lib/MC/MCObjectFileInfo.cpp +++ b/llvm/lib/MC/MCObjectFileInfo.cpp @@ -1160,11 +1160,11 @@ } MCSection * -MCObjectFileInfo::getPseudoProbeSection(const MCSection *TextSec) const { +MCObjectFileInfo::getPseudoProbeSection(const MCSection &TextSec) const { if (Ctx->getObjectFileType() == MCContext::IsELF) { - const auto *ElfSec = static_cast(TextSec); + const auto &ElfSec = static_cast(TextSec); // Create a separate section for probes that comes with a comdat function. - if (const MCSymbol *Group = ElfSec->getGroup()) { + if (const MCSymbol *Group = ElfSec.getGroup()) { auto *S = static_cast(PseudoProbeSection); auto Flags = S->getFlags() | ELF::SHF_GROUP; return Ctx->getELFSection(S->getName(), S->getType(), Flags, diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp --- a/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/llvm/lib/MC/MCParser/AsmParser.cpp @@ -5904,10 +5904,16 @@ InlineStack.push_back(Site); } + // Parse function entry name + StringRef FnName; + if (parseIdentifier(FnName)) + return Error(getLexer().getLoc(), "unexpected token in '.pseudoprobe' directive"); + MCSymbol *FnSym = getContext().lookupSymbol(FnName); + if (parseEOL()) return true; - getStreamer().emitPseudoProbe(Guid, Index, Type, Attr, InlineStack); + getStreamer().emitPseudoProbe(Guid, Index, Type, Attr, InlineStack, FnSym); return false; } diff --git a/llvm/lib/MC/MCPseudoProbe.cpp b/llvm/lib/MC/MCPseudoProbe.cpp --- a/llvm/lib/MC/MCPseudoProbe.cpp +++ b/llvm/lib/MC/MCPseudoProbe.cpp @@ -14,9 +14,12 @@ #include "llvm/MC/MCFragment.h" #include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/MCObjectStreamer.h" +#include "llvm/MC/MCSymbol.h" #include "llvm/Support/Endian.h" #include "llvm/Support/LEB128.h" +#include "llvm/Support/MD5.h" #include "llvm/Support/raw_ostream.h" +#include #include #include #include @@ -43,6 +46,10 @@ void MCPseudoProbe::emit(MCObjectStreamer *MCOS, const MCPseudoProbe *LastProbe) const { + bool IsSentinel = isSentinelProbe(getAttributes()); + assert(LastProbe || + IsSentinel && "Last probe should not be null for non-sentinel probes"); + // Emit Index MCOS->emitULEB128IntValue(Index); // Emit Type and the flag: @@ -53,10 +60,11 @@ assert(Attributes <= 0x7 && "Probe attributes too big to encode, exceeding 7"); uint8_t PackedType = Type | (Attributes << 4); - uint8_t Flag = LastProbe ? ((int8_t)MCPseudoProbeFlag::AddressDelta << 7) : 0; + uint8_t Flag = + IsSentinel ? ((int8_t)MCPseudoProbeFlag::AddressDelta << 7) : 0; MCOS->emitInt8(Flag | PackedType); - if (LastProbe) { + if (!IsSentinel) { // Emit the delta between the address label and LastProbe. const MCExpr *AddrDelta = buildSymbolDiff(MCOS, Label, LastProbe->getLabel()); @@ -67,9 +75,8 @@ MCOS->insert(new MCPseudoProbeAddrFragment(AddrDelta)); } } else { - // Emit label as a symbolic code address. - MCOS->emitSymbolValue( - Label, MCOS->getContext().getAsmInfo()->getCodePointerSize()); + // Emit the GUID of the code range that the sentinel probe represents. + MCOS->emitInt64(Guid); } LLVM_DEBUG({ @@ -81,7 +88,7 @@ void MCPseudoProbeInlineTree::addPseudoProbe( const MCPseudoProbe &Probe, const MCPseudoProbeInlineStack &InlineStack) { // The function should not be called on the root. - assert(isRoot() && "Should not be called on root"); + assert(isRoot() && "Should only be called on root"); // When it comes here, the input look like: // Probe: GUID of C, ... @@ -128,43 +135,51 @@ dbgs() << "Group [\n"; MCPseudoProbeTable::DdgPrintIndent += 2; }); + assert(!isRoot() && "Root should not come here"); + // Emit probes grouped by GUID. - if (Guid != 0) { - LLVM_DEBUG({ - dbgs().indent(MCPseudoProbeTable::DdgPrintIndent); - dbgs() << "GUID: " << Guid << "\n"; - }); - // Emit Guid - MCOS->emitInt64(Guid); - // Emit number of probes in this node - MCOS->emitULEB128IntValue(Probes.size()); - // Emit number of direct inlinees - MCOS->emitULEB128IntValue(Children.size()); - // Emit probes in this group - for (const auto &Probe : Probes) { - Probe.emit(MCOS, LastProbe); - LastProbe = &Probe; - } - } else { - assert(Probes.empty() && "Root should not have probes"); + LLVM_DEBUG({ + dbgs().indent(MCPseudoProbeTable::DdgPrintIndent); + dbgs() << "GUID: " << Guid << "\n"; + }); + // Emit Guid + MCOS->emitInt64(Guid); + // Emit number of probes in this node, including a sentinel probe for + // top-level functions if needed. + bool NeedSantinel = false; + if (Parent->isRoot()) { + assert(isSentinelProbe(LastProbe->getAttributes()) && + "Starting probe of a top-level function should be a sentinel probe"); + if (LastProbe->getGuid() != Guid) + NeedSantinel = true; + } + + MCOS->emitULEB128IntValue(Probes.size() + NeedSantinel); + // Emit number of direct inlinees + MCOS->emitULEB128IntValue(Children.size()); + // Emit sentinel probe for top-level functions + if (NeedSantinel) + LastProbe->emit(MCOS, nullptr); + + // Emit probes in this group + for (const auto &Probe : Probes) { + Probe.emit(MCOS, LastProbe); + LastProbe = &Probe; } - // Emit sorted descendant - // InlineSite is unique for each pair, - // so there will be no ordering of Inlinee based on MCPseudoProbeInlineTree* + // Emit sorted descendant. InlineSite is unique for each pair, so there will + // be no ordering of Inlinee based on MCPseudoProbeInlineTree* std::map Inlinees; for (auto &Child : Children) Inlinees[Child.first] = Child.second.get(); for (const auto &Inlinee : Inlinees) { - if (Guid) { - // Emit probe index - MCOS->emitULEB128IntValue(std::get<1>(Inlinee.first)); - LLVM_DEBUG({ - dbgs().indent(MCPseudoProbeTable::DdgPrintIndent); - dbgs() << "InlineSite: " << std::get<1>(Inlinee.first) << "\n"; - }); - } + // Emit probe index + MCOS->emitULEB128IntValue(std::get<1>(Inlinee.first)); + LLVM_DEBUG({ + dbgs().indent(MCPseudoProbeTable::DdgPrintIndent); + dbgs() << "InlineSite: " << std::get<1>(Inlinee.first) << "\n"; + }); // Emit the group Inlinee.second->emit(MCOS, LastProbe); } @@ -176,17 +191,33 @@ }); } -void MCPseudoProbeSection::emit(MCObjectStreamer *MCOS) { +void MCPseudoProbeSections::emit(MCObjectStreamer *MCOS) { MCContext &Ctx = MCOS->getContext(); - for (auto &ProbeSec : MCProbeDivisions) { - const MCPseudoProbe *LastProbe = nullptr; - if (auto *S = - Ctx.getObjectFileInfo()->getPseudoProbeSection(ProbeSec.first)) { + const auto *FuncSym = ProbeSec.first; + const auto &Root = ProbeSec.second; + if (auto *S = Ctx.getObjectFileInfo()->getPseudoProbeSection( + FuncSym->getSection())) { // Switch to the .pseudoprobe section or a comdat group. MCOS->switchSection(S); // Emit probes grouped by GUID. - ProbeSec.second.emit(MCOS, LastProbe); + // Emit sorted descendant. InlineSite is unique for each pair, so there + // will be no ordering of Inlinee based on MCPseudoProbeInlineTree* + std::map Inlinees; + for (auto Child = Root.getChildren().begin(); + Child != Root.getChildren().end(); ++Child) + Inlinees[Child->first] = Child->second.get(); + + for (const auto &Inlinee : Inlinees) { + // Emit the group guarded by a sentinel probe. + MCPseudoProbe SentinelProbe(const_cast(FuncSym), + MD5Hash(FuncSym->getName()), + (uint32_t)PseudoProbeReservedId::Invalid, + (uint32_t)PseudoProbeType::Block, + (uint32_t)PseudoProbeAttributes::Sentinel); + const MCPseudoProbe *Probe = &SentinelProbe; + Inlinee.second->emit(MCOS, Probe); + } } } } diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp --- a/llvm/lib/MC/MCStreamer.cpp +++ b/llvm/lib/MC/MCStreamer.cpp @@ -1102,7 +1102,8 @@ void MCStreamer::emitPseudoProbe(uint64_t Guid, uint64_t Index, uint64_t Type, uint64_t Attr, - const MCPseudoProbeInlineStack &InlineStack) { + const MCPseudoProbeInlineStack &InlineStack, + MCSymbol *FnSym) { auto &Context = getContext(); // Create a symbol at in the current section for use in the probe. @@ -1116,7 +1117,7 @@ // Add the probe entry to this section's entries. Context.getMCPseudoProbeTable().getProbeSections().addPseudoProbe( - getCurrentSectionOnly(), Probe, InlineStack); + FnSym, Probe, InlineStack); } void MCStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo, diff --git a/llvm/test/Transforms/SampleProfile/pseudo-probe-emit-inline.ll b/llvm/test/Transforms/SampleProfile/pseudo-probe-emit-inline.ll --- a/llvm/test/Transforms/SampleProfile/pseudo-probe-emit-inline.ll +++ b/llvm/test/Transforms/SampleProfile/pseudo-probe-emit-inline.ll @@ -10,17 +10,18 @@ ; RUN: llvm-mc -filetype=obj <%t1 -o %t4 ; RUN: llvm-objdump --section-headers %t4 | FileCheck %s --check-prefix=CHECK-OBJ + define dso_local void @foo2() !dbg !7 { ; CHECK-IL: call void @llvm.pseudoprobe(i64 [[#GUID1:]], i64 1, i32 0, i64 -1), !dbg ![[#]] -; CHECK-ASM: .pseudoprobe [[#GUID1:]] 1 0 0 +; CHECK-ASM: .pseudoprobe [[#GUID1:]] 1 0 0 foo2 ret void, !dbg !10 } define dso_local void @foo() #0 !dbg !11 { ; CHECK-IL: call void @llvm.pseudoprobe(i64 [[#GUID2:]], i64 1, i32 0, i64 -1), !dbg ![[#]] ; CHECK-IL: call void @llvm.pseudoprobe(i64 [[#GUID1]], i64 1, i32 0, i64 -1), !dbg ![[#DL1:]] -; CHECK-ASM: .pseudoprobe [[#GUID2:]] 1 0 0 -; CHECK-ASM: .pseudoprobe [[#GUID1]] 1 0 0 @ [[#GUID2]]:2 +; CHECK-ASM: .pseudoprobe [[#GUID2:]] 1 0 0 foo +; CHECK-ASM: .pseudoprobe [[#GUID1]] 1 0 0 @ [[#GUID2]]:2 foo call void @foo2(), !dbg !12 ret void, !dbg !13 } @@ -29,9 +30,9 @@ ; CHECK-IL: call void @llvm.pseudoprobe(i64 [[#GUID3:]], i64 1, i32 0, i64 -1), !dbg ![[#]] ; CHECK-IL: call void @llvm.pseudoprobe(i64 [[#GUID2]], i64 1, i32 0, i64 -1), !dbg ![[#DL2:]] ; CHECK-IL: call void @llvm.pseudoprobe(i64 [[#GUID1]], i64 1, i32 0, i64 -1), !dbg ![[#DL3:]] -; CHECK-ASM: .pseudoprobe [[#GUID3:]] 1 0 0 -; CHECK-ASM: .pseudoprobe [[#GUID2]] 1 0 0 @ [[#GUID3]]:2 -; CHECK-ASM: .pseudoprobe [[#GUID1]] 1 0 0 @ [[#GUID3]]:2 @ [[#GUID2]]:2 +; CHECK-ASM: .pseudoprobe [[#GUID3:]] 1 0 0 entry +; CHECK-ASM: .pseudoprobe [[#GUID2]] 1 0 0 @ [[#GUID3]]:2 entry +; CHECK-ASM: .pseudoprobe [[#GUID1]] 1 0 0 @ [[#GUID3]]:2 @ [[#GUID2]]:2 entry call void @foo(), !dbg !18 ret i32 0, !dbg !19 } @@ -71,6 +72,7 @@ ; CHECK-OBJ: .pseudo_probe_desc ; CHECK-OBJ: .pseudo_probe +; CHECK-OBJ-NOT: .rela.pseudo_probe !llvm.dbg.cu = !{!0} !llvm.module.flags = !{!3, !4} diff --git a/llvm/test/Transforms/SampleProfile/pseudo-probe-emit.ll b/llvm/test/Transforms/SampleProfile/pseudo-probe-emit.ll --- a/llvm/test/Transforms/SampleProfile/pseudo-probe-emit.ll +++ b/llvm/test/Transforms/SampleProfile/pseudo-probe-emit.ll @@ -18,15 +18,15 @@ %cmp = icmp eq i32 %x, 0 ; CHECK-IL: call void @llvm.pseudoprobe(i64 [[#GUID:]], i64 1, i32 0, i64 -1), !dbg ![[#FAKELINE:]] ; CHECK-MIR: PSEUDO_PROBE [[#GUID:]], 1, 0, 0 -; CHECK-ASM: .pseudoprobe [[#GUID:]] 1 0 0 +; CHECK-ASM: .pseudoprobe [[#GUID:]] 1 0 0 foo br i1 %cmp, label %bb1, label %bb2 bb1: ; CHECK-IL: call void @llvm.pseudoprobe(i64 [[#GUID:]], i64 2, i32 0, i64 -1), !dbg ![[#FAKELINE]] ; CHECK-MIR: PSEUDO_PROBE [[#GUID]], 3, 0, 0 ; CHECK-MIR: PSEUDO_PROBE [[#GUID]], 4, 0, 0 -; CHECK-ASM: .pseudoprobe [[#GUID]] 3 0 0 -; CHECK-ASM: .pseudoprobe [[#GUID]] 4 0 0 +; CHECK-ASM: .pseudoprobe [[#GUID]] 3 0 0 foo +; CHECK-ASM: .pseudoprobe [[#GUID]] 4 0 0 foo store i32 6, ptr @a, align 4 br label %bb3 @@ -34,8 +34,8 @@ ; CHECK-IL: call void @llvm.pseudoprobe(i64 [[#GUID:]], i64 3, i32 0, i64 -1), !dbg ![[#FAKELINE]] ; CHECK-MIR: PSEUDO_PROBE [[#GUID]], 2, 0, 0 ; CHECK-MIR: PSEUDO_PROBE [[#GUID]], 4, 0, 0 -; CHECK-ASM: .pseudoprobe [[#GUID]] 2 0 0 -; CHECK-ASM: .pseudoprobe [[#GUID]] 4 0 0 +; CHECK-ASM: .pseudoprobe [[#GUID]] 2 0 0 foo +; CHECK-ASM: .pseudoprobe [[#GUID]] 4 0 0 foo store i32 8, ptr @a, align 4 br label %bb3 @@ -44,22 +44,22 @@ ret void, !dbg !12 } -declare void @bar(i32 %x) +declare void @bar(i32 %x) define internal void @foo2(ptr %f) !dbg !4 { entry: ; CHECK-IL: call void @llvm.pseudoprobe(i64 [[#GUID2:]], i64 1, i32 0, i64 -1) ; CHECK-MIR: PSEUDO_PROBE [[#GUID2:]], 1, 0, 0 -; CHECK-ASM: .pseudoprobe [[#GUID2:]] 1 0 0 +; CHECK-ASM: .pseudoprobe [[#GUID2:]] 1 0 0 foo2 ; Check pseudo_probe metadata attached to the indirect call instruction. ; CHECK-IL: call void %f(i32 1), !dbg ![[#PROBE0:]] ; CHECK-MIR: PSEUDO_PROBE [[#GUID2]], 2, 1, 0 -; CHECK-ASM: .pseudoprobe [[#GUID2]] 2 1 0 +; CHECK-ASM: .pseudoprobe [[#GUID2]] 2 1 0 foo2 call void %f(i32 1), !dbg !13 ; Check pseudo_probe metadata attached to the direct call instruction. ; CHECK-IL: call void @bar(i32 1), !dbg ![[#PROBE1:]] ; CHECK-MIR: PSEUDO_PROBE [[#GUID2]], 3, 2, 0 -; CHECK-ASM: .pseudoprobe [[#GUID2]] 3 2 0 +; CHECK-ASM: .pseudoprobe [[#GUID2]] 3 2 0 foo2 call void @bar(i32 1) ret void } @@ -92,7 +92,8 @@ ; CHECK-ASM-NEXT: .ascii "foo2" ; CHECK-OBJ-COUNT-2: .pseudo_probe_desc -; CHECK-OBJ-COUNT-2: .pseudo_probe +; CHECK-OBJ: .pseudo_probe +; CHECK-OBJ-NOT: .rela.pseudo_probe !llvm.dbg.cu = !{!0} !llvm.module.flags = !{!9, !10}