Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -1890,7 +1890,7 @@ defm pseudo_probe_for_profiling : BoolFOption<"pseudo-probe-for-profiling",
CodeGenOpts<"PseudoProbeForProfiling">, DefaultFalse,
PosFlag<SetTrue, [], [ClangOption], "Emit">,
NegFlag<SetFalse, [], [ClangOption], "Do not emit">,
BothFlags<[], [ClangOption, CC1Option],
BothFlags<[], [ClangOption, CC1Option, CLOption],
" pseudo probes for sample profiling">>;
def forder_file_instrumentation : Flag<["-"], "forder-file-instrumentation">,
Group<f_Group>, Visibility<[ClangOption, CC1Option, CLOption]>,
Expand Down
1 change: 1 addition & 0 deletions clang/test/Driver/cl-options.c
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,7 @@
// RUN: -fno-profile-instr-use \
// RUN: -fcs-profile-generate \
// RUN: -fcs-profile-generate=dir \
// RUN: -fpseudo-probe-for-profiling \
// RUN: -ftime-trace \
// RUN: -fmodules \
// RUN: -fno-modules \
Expand Down
9 changes: 7 additions & 2 deletions llvm/include/llvm/MC/MCSectionCOFF.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,19 @@ class MCSectionCOFF final : public MCSection {
/// section (Characteristics & IMAGE_SCN_LNK_COMDAT) != 0
mutable int Selection;

unsigned UniqueID;

private:
friend class MCContext;
// The storage of Name is owned by MCContext's COFFUniquingMap.
MCSectionCOFF(StringRef Name, unsigned Characteristics,
MCSymbol *COMDATSymbol, int Selection, MCSymbol *Begin)
MCSymbol *COMDATSymbol, int Selection, unsigned UniqueID,
MCSymbol *Begin)
: MCSection(SV_COFF, Name, Characteristics & COFF::IMAGE_SCN_CNT_CODE,
Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA,
Begin),
Characteristics(Characteristics), COMDATSymbol(COMDATSymbol),
Selection(Selection) {
Selection(Selection), UniqueID(UniqueID) {
assert((Characteristics & 0x00F00000) == 0 &&
"alignment must not be set upon section creation");
}
Expand All @@ -72,6 +75,8 @@ class MCSectionCOFF final : public MCSection {

void setSelection(int Selection) const;

unsigned getUniqueID() const { return UniqueID; }

void printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
raw_ostream &OS,
uint32_t Subsection) const override;
Expand Down
3 changes: 3 additions & 0 deletions llvm/include/llvm/Target/TargetLoweringObjectFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ class TargetLoweringObjectFile : public MCObjectFileInfo {
/// Emit Call Graph Profile metadata.
void emitCGProfileMetadata(MCStreamer &Streamer, Module &M) const;

/// Emit pseudo_probe_desc metadata.
void emitPseudoProbeDescMetadata(MCStreamer &Streamer, Module &M) const;

/// Get the module-level metadata that the platform cares about.
virtual void getModuleMetadata(Module &M) {}

Expand Down
24 changes: 2 additions & 22 deletions llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -335,28 +335,7 @@ void TargetLoweringObjectFileELF::emitModuleMetadata(MCStreamer &Streamer,
}
}

if (NamedMDNode *FuncInfo = M.getNamedMetadata(PseudoProbeDescMetadataName)) {
// Emit a descriptor for every function including functions that have an
// available external linkage. We may not want this for imported functions
// that has code in another thinLTO module but we don't have a good way to
// tell them apart from inline functions defined in header files. Therefore
// we put each descriptor in a separate comdat section and rely on the
// linker to deduplicate.
for (const auto *Operand : FuncInfo->operands()) {
const auto *MD = cast<MDNode>(Operand);
auto *GUID = mdconst::dyn_extract<ConstantInt>(MD->getOperand(0));
auto *Hash = mdconst::dyn_extract<ConstantInt>(MD->getOperand(1));
auto *Name = cast<MDString>(MD->getOperand(2));
auto *S = C.getObjectFileInfo()->getPseudoProbeDescSection(
TM->getFunctionSections() ? Name->getString() : StringRef());

Streamer.switchSection(S);
Streamer.emitInt64(GUID->getZExtValue());
Streamer.emitInt64(Hash->getZExtValue());
Streamer.emitULEB128IntValue(Name->getString().size());
Streamer.emitBytes(Name->getString());
}
}
emitPseudoProbeDescMetadata(Streamer, M);

if (NamedMDNode *LLVMStats = M.getNamedMetadata("llvm.stats")) {
// Emit the metadata for llvm statistics into .llvm_stats section, which is
Expand Down Expand Up @@ -1864,6 +1843,7 @@ void TargetLoweringObjectFileCOFF::emitModuleMetadata(MCStreamer &Streamer,
}

emitCGProfileMetadata(Streamer, M);
emitPseudoProbeDescMetadata(Streamer, M);
}

void TargetLoweringObjectFileCOFF::emitLinkerDirectives(
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/MC/MCAsmStreamer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2492,7 +2492,8 @@ void MCAsmStreamer::emitPseudoProbe(uint64_t Guid, uint64_t Index,
for (const auto &Site : InlineStack)
OS << " @ " << std::get<0>(Site) << ":" << std::get<1>(Site);

OS << " " << FnSym->getName();
OS << " ";
FnSym->print(OS, MAI);

EmitEOL();
}
Expand Down
10 changes: 9 additions & 1 deletion llvm/lib/MC/MCContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "llvm/MC/MCFragment.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCLabel.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCSectionDXContainer.h"
#include "llvm/MC/MCSectionELF.h"
Expand Down Expand Up @@ -718,10 +719,17 @@ MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
StringRef CachedName = Iter->first.SectionName;
MCSymbol *Begin = getOrCreateSectionSymbol<MCSymbolCOFF>(Section);
MCSectionCOFF *Result = new (COFFAllocator.Allocate()) MCSectionCOFF(
CachedName, Characteristics, COMDATSymbol, Selection, Begin);
CachedName, Characteristics, COMDATSymbol, Selection, UniqueID, Begin);
Iter->second = Result;
auto *F = allocInitialFragment(*Result);
Begin->setFragment(F);
// Normally the comdat symbol is function begin label and will be set a
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks little bit ugly here. Any better solution?
We must support create pseudo_probe_desc section from asm so it can't be simply implemented in getPseudoProbeDescSection

// fragment in emitLabel. It is not hold for a pseudo_probe_desc comdat
// symbol, so we need to set its fragment here.
if (COMDATSymbol && !COMDATSymbol->getFragment() &&
Section == MOFI->getPseudoProbeDescSection("")->getName()) {
COMDATSymbol->setFragment(F);
}
return Result;
}

Expand Down
81 changes: 59 additions & 22 deletions llvm/lib/MC/MCObjectFileInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -792,6 +792,16 @@ void MCObjectFileInfo::initCOFFMCObjectFileInfo(const Triple &T) {
StackMapSection = Ctx->getCOFFSection(".llvm_stackmaps",
COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
COFF::IMAGE_SCN_MEM_READ);

// Set IMAGE_SCN_MEM_DISCARDABLE so that lld will not truncate section name.
PseudoProbeSection = Ctx->getCOFFSection(
".pseudo_probe", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
COFF::IMAGE_SCN_MEM_DISCARDABLE |
COFF::IMAGE_SCN_MEM_READ);
PseudoProbeDescSection = Ctx->getCOFFSection(
".pseudo_probe_desc", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
COFF::IMAGE_SCN_MEM_DISCARDABLE |
COFF::IMAGE_SCN_MEM_READ);
}

void MCObjectFileInfo::initSPIRVMCObjectFileInfo(const Triple &T) {
Expand Down Expand Up @@ -1141,41 +1151,68 @@ MCObjectFileInfo::getKCFITrapSection(const MCSection &TextSec) const {

MCSection *
MCObjectFileInfo::getPseudoProbeSection(const MCSection &TextSec) const {
if (Ctx->getObjectFileType() != MCContext::IsELF)
return PseudoProbeSection;
auto ObjFileType = Ctx->getObjectFileType();
if (ObjFileType == MCContext::IsELF) {
const auto &ElfSec = static_cast<const MCSectionELF &>(TextSec);
unsigned Flags = ELF::SHF_LINK_ORDER;
StringRef GroupName;
if (const MCSymbol *Group = ElfSec.getGroup()) {
GroupName = Group->getName();
Flags |= ELF::SHF_GROUP;
}

const auto &ElfSec = static_cast<const MCSectionELF &>(TextSec);
unsigned Flags = ELF::SHF_LINK_ORDER;
StringRef GroupName;
if (const MCSymbol *Group = ElfSec.getGroup()) {
GroupName = Group->getName();
Flags |= ELF::SHF_GROUP;
return Ctx->getELFSection(PseudoProbeSection->getName(), ELF::SHT_PROGBITS,
Flags, 0, GroupName, true, ElfSec.getUniqueID(),
cast<MCSymbolELF>(TextSec.getBeginSymbol()));
} else if (ObjFileType == MCContext::IsCOFF) {
StringRef COMDATSymName = "";
int Selection = 0;
unsigned Characteristics =
COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_DISCARDABLE |
COFF::IMAGE_SCN_MEM_READ | COFF::IMAGE_SCN_LNK_COMDAT;
auto &COFFSec = cast<MCSectionCOFF>(TextSec);
if (const MCSymbol *COMDATSym = COFFSec.getCOMDATSymbol()) {
// Associate .pseudo_probe to its function section.
COMDATSymName = COMDATSym->getName();
Selection = COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE;
}

return Ctx->getCOFFSection(PseudoProbeSection->getName(), Characteristics,
COMDATSymName, Selection, COFFSec.getUniqueID());
}

return Ctx->getELFSection(PseudoProbeSection->getName(), ELF::SHT_PROGBITS,
Flags, 0, GroupName, true, ElfSec.getUniqueID(),
cast<MCSymbolELF>(TextSec.getBeginSymbol()));
return PseudoProbeSection;
}

MCSection *
MCObjectFileInfo::getPseudoProbeDescSection(StringRef FuncName) const {
if (Ctx->getObjectFileType() == MCContext::IsELF) {
// Create a separate comdat group for each function's descriptor in order
// for the linker to deduplicate. The duplication, must be from different
// tranlation unit, can come from:
// 1. Inline functions defined in header files;
// 2. ThinLTO imported funcions;
// 3. Weak-linkage definitions.
// Use a concatenation of the section name and the function name as the
// group name so that descriptor-only groups won't be folded with groups of
// code.
if (Ctx->getTargetTriple().supportsCOMDAT() && !FuncName.empty()) {
// Create a separate comdat group for each function's descriptor in order
// for the linker to deduplicate. The duplication, must be from different
// tranlation unit, can come from:
// 1. Inline functions defined in header files;
// 2. ThinLTO imported funcions;
// 3. Weak-linkage definitions.
// Use a concatenation of the section name and the function name as the
// group name so that descriptor-only groups won't be folded with groups of
// code.
if (Ctx->getTargetTriple().supportsCOMDAT() && !FuncName.empty()) {
auto ObjFileType = Ctx->getObjectFileType();
if (ObjFileType == MCContext::IsELF) {
auto *S = static_cast<MCSectionELF *>(PseudoProbeDescSection);
auto Flags = S->getFlags() | ELF::SHF_GROUP;
return Ctx->getELFSection(S->getName(), S->getType(), Flags,
S->getEntrySize(),
S->getName() + "_" + FuncName,
/*IsComdat=*/true);
} else if (ObjFileType == MCContext::IsCOFF) {
unsigned Characteristics = COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
COFF::IMAGE_SCN_MEM_DISCARDABLE |
COFF::IMAGE_SCN_MEM_READ |
COFF::IMAGE_SCN_LNK_COMDAT;
auto *S = cast<MCSectionCOFF>(PseudoProbeDescSection);
std::string COMDATSymName = (S->getName() + "_" + FuncName).str();
return Ctx->getCOFFSection(S->getName(), Characteristics, COMDATSymName,
COFF::IMAGE_COMDAT_SELECT_ANY);
}
}
return PseudoProbeDescSection;
Expand Down
27 changes: 27 additions & 0 deletions llvm/lib/Target/TargetLoweringObjectFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,33 @@ void TargetLoweringObjectFile::emitCGProfileMetadata(MCStreamer &Streamer,
}
}

void TargetLoweringObjectFile::emitPseudoProbeDescMetadata(MCStreamer &Streamer,
Module &M) const {
if (NamedMDNode *FuncInfo = M.getNamedMetadata(PseudoProbeDescMetadataName)) {
// Emit a descriptor for every function including functions that have an
// available external linkage. We may not want this for imported functions
// that has code in another thinLTO module but we don't have a good way to
// tell them apart from inline functions defined in header files. Therefore
// we put each descriptor in a separate comdat section and rely on the
// linker to deduplicate.
auto &C = getContext();
for (const auto *Operand : FuncInfo->operands()) {
const auto *MD = cast<MDNode>(Operand);
auto *GUID = mdconst::dyn_extract<ConstantInt>(MD->getOperand(0));
auto *Hash = mdconst::dyn_extract<ConstantInt>(MD->getOperand(1));
auto *Name = cast<MDString>(MD->getOperand(2));
auto *S = C.getObjectFileInfo()->getPseudoProbeDescSection(
TM->getFunctionSections() ? Name->getString() : StringRef());

Streamer.switchSection(S);
Streamer.emitInt64(GUID->getZExtValue());
Streamer.emitInt64(Hash->getZExtValue());
Streamer.emitULEB128IntValue(Name->getString().size());
Streamer.emitBytes(Name->getString());
}
}
}

/// getKindForGlobal - This is a top-level target-independent classifier for
/// a global object. Given a global variable and information from the TM, this
/// function classifies the global in a target independent manner. This function
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; REQUIRES: x86_64-linux
; REQUIRES: target={{x86_64-.*-(linux|windows).*}}
; REQUIRES: asserts
; RUN: opt < %s -passes='thinlto<O2>' -pgo-kind=pgo-sample-use-pipeline -sample-profile-file=%S/Inputs/pseudo-probe-callee-profile-mismatch.prof --salvage-stale-profile -S --debug-only=sample-profile,sample-profile-matcher,sample-profile-impl -pass-remarks=inline 2>&1 | FileCheck %s

Expand All @@ -14,7 +14,7 @@


target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
target triple = "x86_64-unknown--"

define available_externally i32 @main() #0 {
%1 = call i32 @bar(), !dbg !13
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/SampleProfile/pseudo-probe-dangle.ll
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; REQUIRES: x86_64-linux
; REQUIRES: target={{x86_64-.*-(linux|windows).*}}
; RUN: opt < %s -passes='pseudo-probe,jump-threading' -S -o %t
; RUN: FileCheck %s < %t --check-prefix=JT
; RUN: llc -function-sections <%t -filetype=asm | FileCheck %s --check-prefix=ASM
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/SampleProfile/pseudo-probe-dangle2.ll
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; REQUIRES: x86_64-linux
; REQUIRES: target={{x86_64-.*-(linux|windows).*}}
; RUN: opt < %s -passes=simplifycfg -S -o %t
; RUN: FileCheck %s < %t

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; REQUIRES: x86_64-linux
; REQUIRES: target={{x86_64-.*-(linux|windows).*}}
; RUN: opt < %s -passes=pseudo-probe -S -o - | FileCheck %s

; CHECK: ![[#]] = !{i64 -3345296970173352005, i64 [[#]], !"foo.dbg"}
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/SampleProfile/pseudo-probe-eh.ll
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; REQUIRES: x86_64-linux
; REQUIRES: target={{x86_64-.*-(linux|windows).*}}
; RUN: opt < %s -passes=pseudo-probe -function-sections -S -o - | FileCheck %s

;; Check the generation of pseudoprobe intrinsic call for non-EH blocks only.
Expand Down
73 changes: 49 additions & 24 deletions llvm/test/Transforms/SampleProfile/pseudo-probe-emit-inline.ll
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
; REQUIRES: x86_64-linux
; REQUIRES: target={{x86_64-.*-(linux|windows).*}}
; RUN: opt < %s -passes='pseudo-probe,cgscc(inline)' -function-sections -mtriple=x86_64-unknown-linux-gnu -S -o %t
; RUN: FileCheck %s < %t --check-prefix=CHECK-IL
; RUN: llc -function-sections <%t -filetype=asm -o %t1
; RUN: FileCheck %s < %t1 --check-prefix=CHECK-ASM
; RUN: llc -function-sections <%t -filetype=obj -o %t2
; RUN: llvm-objdump --section-headers %t2 | FileCheck %s --check-prefix=CHECK-OBJ
; RUN: llvm-mc -filetype=asm <%t1 -o %t3
; RUN: FileCheck %s < %t3 --check-prefix=CHECK-ASM
; RUN: llvm-mc -filetype=obj <%t1 -o %t4
; RUN: llvm-objdump --section-headers %t4 | FileCheck %s --check-prefix=CHECK-OBJ
; For ELF.
; RUN: llc -function-sections -mtriple=x86_64--linux <%t -filetype=asm -o %t1
; RUN: FileCheck %s < %t1 --check-prefixes=CHECK-ASM,CHECK-ASM-ELF
; RUN: llc -function-sections -mtriple=x86_64--linux <%t -filetype=obj -o %t2
; RUN: llvm-objdump --section-headers %t2 | FileCheck %s --check-prefix=CHECK-OBJ
; RUN: llvm-mc -triple=x86_64--linux -filetype=asm <%t1 -o %t3
; RUN: FileCheck %s < %t3 --check-prefixes=CHECK-ASM,CHECK-ASM-ELF
; RUN: llvm-mc -triple=x86_64--linux -filetype=obj <%t1 -o %t4
; RUN: llvm-objdump --section-headers %t4 | FileCheck %s --check-prefix=CHECK-OBJ
; For COFF.
; RUN: llc -function-sections -mtriple=x86_64--windows <%t -filetype=asm -o %t1
; RUN: FileCheck %s < %t1 --check-prefixes=CHECK-ASM,CHECK-ASM-COFF
; RUN: llc -function-sections -mtriple=x86_64--windows <%t -filetype=obj -o %t2
; RUN: llvm-objdump --section-headers %t2 | FileCheck %s --check-prefixes=CHECK-OBJ
; RUN: llvm-mc -triple=x86_64--windows -filetype=asm <%t1 -o %t3
; RUN: FileCheck %s < %t3 --check-prefixes=CHECK-ASM,CHECK-ASM-COFF
; RUN: llvm-mc -triple=x86_64--windows -filetype=obj <%t1 -o %t4
; RUN: llvm-objdump --section-headers %t4 | FileCheck %s --check-prefixes=CHECK-OBJ


define dso_local void @foo2() !dbg !7 {
Expand Down Expand Up @@ -54,21 +64,36 @@ define dso_local i32 @entry() !dbg !14 {


; Check the generation of .pseudo_probe_desc section
; CHECK-ASM: .section .pseudo_probe_desc,"G",@progbits,.pseudo_probe_desc_foo2,comdat
; CHECK-ASM-NEXT: .quad [[#GUID1]]
; CHECK-ASM-NEXT: .quad [[#HASH1:]]
; CHECK-ASM-NEXT: .byte 4
; CHECK-ASM-NEXT: .ascii "foo2"
; CHECK-ASM-NEXT: .section .pseudo_probe_desc,"G",@progbits,.pseudo_probe_desc_foo,comdat
; CHECK-ASM-NEXT: .quad [[#GUID2]]
; CHECK-ASM-NEXT: .quad [[#HASH2:]]
; CHECK-ASM-NEXT: .byte 3
; CHECK-ASM-NEXT: .ascii "foo"
; CHECK-ASM-NEXT: .section .pseudo_probe_desc,"G",@progbits,.pseudo_probe_desc_entry,comdat
; CHECK-ASM-NEXT: .quad [[#GUID3]]
; CHECK-ASM-NEXT: .quad [[#HASH3:]]
; CHECK-ASM-NEXT: .byte 5
; CHECK-ASM-NEXT: .ascii "entry"
; CHECK-ASM-ELF: .section .pseudo_probe_desc,"G",@progbits,.pseudo_probe_desc_foo2,comdat
; CHECK-ASM-ELF-NEXT: .quad [[#GUID1]]
; CHECK-ASM-ELF-NEXT: .quad [[#HASH1:]]
; CHECK-ASM-ELF-NEXT: .byte 4
; CHECK-ASM-ELF-NEXT: .ascii "foo2"
; CHECK-ASM-ELF-NEXT: .section .pseudo_probe_desc,"G",@progbits,.pseudo_probe_desc_foo,comdat
; CHECK-ASM-ELF-NEXT: .quad [[#GUID2]]
; CHECK-ASM-ELF-NEXT: .quad [[#HASH2:]]
; CHECK-ASM-ELF-NEXT: .byte 3
; CHECK-ASM-ELF-NEXT: .ascii "foo"
; CHECK-ASM-ELF-NEXT: .section .pseudo_probe_desc,"G",@progbits,.pseudo_probe_desc_entry,comdat
; CHECK-ASM-ELF-NEXT: .quad [[#GUID3]]
; CHECK-ASM-ELF-NEXT: .quad [[#HASH3:]]
; CHECK-ASM-ELF-NEXT: .byte 5
; CHECK-ASM-ELF-NEXT: .ascii "entry"
; CHECK-ASM-COFF: .section .pseudo_probe_desc,"drD",discard,.pseudo_probe_desc_foo2
; CHECK-ASM-COFF-NEXT: .quad [[#GUID1]]
; CHECK-ASM-COFF-NEXT: .quad [[#HASH1:]]
; CHECK-ASM-COFF-NEXT: .byte 4
; CHECK-ASM-COFF-NEXT: .ascii "foo2"
; CHECK-ASM-COFF-NEXT: .section .pseudo_probe_desc,"drD",discard,.pseudo_probe_desc_foo
; CHECK-ASM-COFF-NEXT: .quad [[#GUID2]]
; CHECK-ASM-COFF-NEXT: .quad [[#HASH2:]]
; CHECK-ASM-COFF-NEXT: .byte 3
; CHECK-ASM-COFF-NEXT: .ascii "foo"
; CHECK-ASM-COFF-NEXT: .section .pseudo_probe_desc,"drD",discard,.pseudo_probe_desc_entry
; CHECK-ASM-COFF-NEXT: .quad [[#GUID3]]
; CHECK-ASM-COFF-NEXT: .quad [[#HASH3:]]
; CHECK-ASM-COFF-NEXT: .byte 5
; CHECK-ASM-COFF-NEXT: .ascii "entry"

; CHECK-OBJ: .pseudo_probe_desc
; CHECK-OBJ: .pseudo_probe
Expand Down
Loading
Loading