Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
32 changes: 32 additions & 0 deletions llvm/lib/CodeGen/AsmPrinter/PseudoProbePrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@
#include "llvm/MC/MCPseudoProbe.h"
#include "llvm/MC/MCStreamer.h"

#ifndef NDEBUG
#include "llvm/IR/Module.h"
#include "llvm/Support/WithColor.h"
#endif

using namespace llvm;

void PseudoProbeHandler::emitPseudoProbe(uint64_t Guid, uint64_t Index,
Expand All @@ -35,6 +40,9 @@ void PseudoProbeHandler::emitPseudoProbe(uint64_t Guid, uint64_t Index,
uint64_t &CallerGuid = NameGuidMap[Name];
if (!CallerGuid)
CallerGuid = Function::getGUIDAssumingExternalLinkage(Name);
#ifndef NDEBUG
verifyGuidExistenceInDesc(CallerGuid, Name);
#endif
uint64_t CallerProbeId = PseudoProbeDwarfDiscriminator::extractProbeIndex(
InlinedAt->getDiscriminator());
ReversedInlineStack.emplace_back(CallerGuid, CallerProbeId);
Expand All @@ -51,4 +59,28 @@ void PseudoProbeHandler::emitPseudoProbe(uint64_t Guid, uint64_t Index,
SmallVector<InlineSite, 8> InlineStack(llvm::reverse(ReversedInlineStack));
Asm->OutStreamer->emitPseudoProbe(Guid, Index, Type, Attr, Discriminator,
InlineStack, Asm->CurrentFnSym);
#ifndef NDEBUG
verifyGuidExistenceInDesc(
Guid, DebugLoc ? DebugLoc->getSubprogramLinkageName() : "");
#endif
}

#ifndef NDEBUG
void PseudoProbeHandler::verifyGuidExistenceInDesc(uint64_t Guid,
StringRef FuncName) {
NamedMDNode *Desc = Asm->MF->getFunction().getParent()->getNamedMetadata(
PseudoProbeDescMetadataName);
assert(Desc && "pseudo probe does not exist");

// Keep DescGuidSet up to date.
for (size_t I = DescGuidSet.size(), E = Desc->getNumOperands(); I != E; ++I) {
const auto *MD = cast<MDNode>(Desc->getOperand(I));
auto *ID = mdconst::extract<ConstantInt>(MD->getOperand(0));
DescGuidSet.insert(ID->getZExtValue());
}

if (!DescGuidSet.contains(Guid))
WithColor::warning() << "Guid:" << Guid << " Name:" << FuncName
<< " does not exist in pseudo probe desc\n";
}
#endif
11 changes: 11 additions & 0 deletions llvm/lib/CodeGen/AsmPrinter/PseudoProbePrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@

#include "llvm/ADT/DenseMap.h"

#ifndef NDEBUG
#include "llvm/ADT/DenseSet.h"
#endif

namespace llvm {

class AsmPrinter;
Expand All @@ -26,6 +30,13 @@ class PseudoProbeHandler {
// Name to GUID map, used as caching/memoization for speed.
DenseMap<StringRef, uint64_t> NameGuidMap;

#ifndef NDEBUG
// All GUID in llvm.pseudo_probe_desc.
DenseSet<uint64_t> DescGuidSet;
Copy link
Contributor

Choose a reason for hiding this comment

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

why don't prefer "SparseSet" here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

SparseSet is more suitable for small key universe. It would be very big for GUID.
I think DenseSet is a greater candidate here.


void verifyGuidExistenceInDesc(uint64_t Guid, StringRef FuncName);
#endif

public:
PseudoProbeHandler(AsmPrinter *A) : Asm(A) {};

Expand Down
46 changes: 46 additions & 0 deletions llvm/test/CodeGen/X86/pseudo-probe-desc-check.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
; RUN: llc -mtriple=x86_64-unknown-linux-gnu < %s 2>&1 | FileCheck %s
; RUN: llc -mtriple=x86_64-unknown-windows-msvc < %s 2>&1 | FileCheck %s

; CHECK: warning: Guid:8314849053352128226 Name:inlinee does not exist in pseudo probe desc
; CHECK: warning: Guid:6492337042787843907 Name:extract2 does not exist in pseudo probe desc

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"

define void @extract1() !dbg !8 {
entry:
call void @llvm.pseudoprobe(i64 6028998432455395745, i64 1, i32 0, i64 -1), !dbg !11
call void @llvm.pseudoprobe(i64 8314849053352128226, i64 1, i32 0, i64 -1), !dbg !12
ret void, !dbg !16
}

define void @extract2() !dbg !17 {
entry:
call void @llvm.pseudoprobe(i64 6492337042787843907, i64 1, i32 0, i64 -1), !dbg !18
ret void, !dbg !18
}

declare void @llvm.pseudoprobe(i64, i64, i32, i64)

!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!2, !3, !4, !5, !6}
!llvm.pseudo_probe_desc = !{!7}

!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang", isOptimized: false, emissionKind: LineTablesOnly, splitDebugInlining: false, nameTableKind: None)
!1 = !DIFile(filename: "test.c", directory: "/home/foo")
!2 = !{i32 7, !"Dwarf Version", i32 4}
!3 = !{i32 2, !"Debug Info Version", i32 3}
!4 = !{i32 1, !"wchar_size", i32 4}
!5 = !{i32 7, !"uwtable", i32 2}
!6 = !{i32 7, !"frame-pointer", i32 2}
!7 = !{i64 6028998432455395745, i64 281479271677951, !"extract1"}
!8 = distinct !DISubprogram(name: "extract1", scope: !1, file: !1, line: 4, type: !9, scopeLine: 4, spFlags: DISPFlagDefinition, unit: !0)
!9 = !DISubroutineType(types: !10)
!10 = !{}
!11 = !DILocation(line: 5, column: 3, scope: !8)
!12 = !DILocation(line: 2, column: 1, scope: !13, inlinedAt: !14)
!13 = distinct !DISubprogram(name: "inlinee", scope: !1, file: !1, line: 1, type: !9, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0)
!14 = distinct !DILocation(line: 5, column: 3, scope: !15)
!15 = !DILexicalBlockFile(scope: !8, file: !1, discriminator: 455082007)
!16 = !DILocation(line: 6, column: 1, scope: !8)
!17 = distinct !DISubprogram(name: "extract2", scope: !1, file: !1, line: 8, type: !9, scopeLine: 8, spFlags: DISPFlagDefinition, unit: !0)
!18 = !DILocation(line: 9, column: 1, scope: !17)
Loading