mirror of
https://github.com/llvm/llvm-project.git
synced 2025-05-10 05:16:08 +00:00

Currently, an AsmPrinterHandler has several methods that allow to dynamically hook in unwind or debug info emission, e.g. at begin/end of every function or instruction. The class hierarchy and the actually overridden functions are as follows: (SymSz=setSymbolSize, mFE=markFunctionEnd, BBS=BasicBlockSection, FL=Funclet; b=beginX, e=endX) SymSz Mod Fn mFE BBS FL Inst AsmPrinterHandler - - - - - - - ` PseudoProbeHandler - - - - - - - ` WinCFGuard - e e - - - - ` EHStreamer - - - - - - - ` DwarfCFIException - e be - be - - ` ARMException - - be e - - - ` AIXException - - e - - - - ` WinException - e be e - be - ` WasmException - e be - - - - ` DebugHandlerBase - b be - be - be ` BTFDebug - e - - - - b ` CodeViewDebug - be - - - - b ` DWARFDebug yes be - - - - b Doing virtual function calls per instruction is costly and useless when the called function does nothing. This commit performs the following clean-up/improvements: - PseudoProbeHandler is no longer an AsmPrinterHandler -- it used nothing of its functionality to hook in at the possible points. This avoids virtual function calls when a pseudo probe printer is present. - DebugHandlerBase is no longer an AsmPrinterHandler, but a separate base class. DebugHandlerBase is the only remaining "hook" for begin/end instruction and setSymbolSize (only used by DWARFDebug). begin/end for function and basic block sections are never overriden and therefore are no longer virtual. (Originally I intended there to be only one debug handler, but BPF as the only target supports two at the same time: DWARF and BTF.) - AsmPrinterHandler no longer has begin/end instruction and setSymbolSize hooks -- these were only used by DebugHandlerBase. This avoid iterating over handlers in every instruction. AsmPrinterHandler Mod Fn mFE BBS FL ` WinCFGuard e e - - - ` EHStreamer - - - - - ` DwarfCFIException e be - be - ` ARMException - be e - - ` AIXException - e - - - ` WinException e be e - be ` WasmException e be - - - SymSz Mod Fn BBS Inst DebugHandlerBase - b be be be ` BTFDebug - e b ` CodeViewDebug - be b ` DWARFDebug yes be b PseudoProbeHandler (no shared methods) To continue allowing external users (e.g., Julia) to hook in at every instruction, a new method addDebugHandler is exposed. This results in a performance improvement, especially in the -O0 -g0 case with unwind information (e.g., JIT baseline).
55 lines
2.4 KiB
C++
55 lines
2.4 KiB
C++
//===- llvm/CodeGen/PseudoProbePrinter.cpp - Pseudo Probe Emission -------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file contains support for writing pseudo probe info into asm files.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "PseudoProbePrinter.h"
|
|
#include "llvm/CodeGen/AsmPrinter.h"
|
|
#include "llvm/IR/DebugInfoMetadata.h"
|
|
#include "llvm/IR/Function.h"
|
|
#include "llvm/IR/PseudoProbe.h"
|
|
#include "llvm/MC/MCPseudoProbe.h"
|
|
#include "llvm/MC/MCStreamer.h"
|
|
|
|
using namespace llvm;
|
|
|
|
void PseudoProbeHandler::emitPseudoProbe(uint64_t Guid, uint64_t Index,
|
|
uint64_t Type, uint64_t Attr,
|
|
const DILocation *DebugLoc) {
|
|
// Gather all the inlined-at nodes.
|
|
// When it's done ReversedInlineStack looks like ([66, B], [88, A])
|
|
// which means, Function A inlines function B at calliste with a probe id 88,
|
|
// and B inlines C at probe 66 where C is represented by Guid.
|
|
SmallVector<InlineSite, 8> ReversedInlineStack;
|
|
auto *InlinedAt = DebugLoc ? DebugLoc->getInlinedAt() : nullptr;
|
|
while (InlinedAt) {
|
|
auto Name = InlinedAt->getSubprogramLinkageName();
|
|
// Use caching to avoid redundant md5 computation for build speed.
|
|
uint64_t &CallerGuid = NameGuidMap[Name];
|
|
if (!CallerGuid)
|
|
CallerGuid = Function::getGUID(Name);
|
|
uint64_t CallerProbeId = PseudoProbeDwarfDiscriminator::extractProbeIndex(
|
|
InlinedAt->getDiscriminator());
|
|
ReversedInlineStack.emplace_back(CallerGuid, CallerProbeId);
|
|
InlinedAt = InlinedAt->getInlinedAt();
|
|
}
|
|
uint64_t Discriminator = 0;
|
|
// For now only block probes have FS discriminators. See
|
|
// MIRFSDiscriminator.cpp for more details.
|
|
if (EnableFSDiscriminator && DebugLoc &&
|
|
(Type == (uint64_t)PseudoProbeType::Block))
|
|
Discriminator = DebugLoc->getDiscriminator();
|
|
assert((EnableFSDiscriminator || Discriminator == 0) &&
|
|
"Discriminator should not be set in non-FSAFDO mode");
|
|
SmallVector<InlineSite, 8> InlineStack(llvm::reverse(ReversedInlineStack));
|
|
Asm->OutStreamer->emitPseudoProbe(Guid, Index, Type, Attr, Discriminator,
|
|
InlineStack, Asm->CurrentFnSym);
|
|
}
|