Skip to content

Commit

Permalink
[AsmPrinter] Remove timers (#97046)
Browse files Browse the repository at this point in the history
Timers are an out-of-line function call and a global variable access,
here twice per emitted instruction. At this granularity, not only the
time results become skewed, but the timers also add a performance
overhead when profiling is disabled. Also outside of the innermost loop,
timers add a measurable overhead. As this is quite expensive for a
mostly unused profiling facility, remove the timers.

Fixes #39650.
  • Loading branch information
aengelke authored Jul 1, 2024
1 parent f209469 commit 80ffec7
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 156 deletions.
35 changes: 6 additions & 29 deletions llvm/include/llvm/CodeGen/AsmPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/CodeGen/AsmPrinterHandler.h"
#include "llvm/CodeGen/DebugHandlerBase.h"
#include "llvm/CodeGen/DwarfStringPoolEntry.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/StackMaps.h"
Expand All @@ -35,12 +33,14 @@
namespace llvm {

class AddrLabelMap;
class AsmPrinterHandler;
class BasicBlock;
class BlockAddress;
class Constant;
class ConstantArray;
class ConstantPtrAuth;
class DataLayout;
class DebugHandlerBase;
class DIE;
class DIEAbbrev;
class DwarfDebug;
Expand Down Expand Up @@ -144,23 +144,6 @@ class AsmPrinter : public MachineFunctionPass {
using GOTEquivUsePair = std::pair<const GlobalVariable *, unsigned>;
MapVector<const MCSymbol *, GOTEquivUsePair> GlobalGOTEquivs;

/// struct HandlerInfo and Handlers permit users or target extended
/// AsmPrinter to add their own handlers.
template <class H> struct HandlerInfo {
std::unique_ptr<H> Handler;
StringRef TimerName;
StringRef TimerDescription;
StringRef TimerGroupName;
StringRef TimerGroupDescription;

HandlerInfo(std::unique_ptr<H> Handler, StringRef TimerName,
StringRef TimerDescription, StringRef TimerGroupName,
StringRef TimerGroupDescription)
: Handler(std::move(Handler)), TimerName(TimerName),
TimerDescription(TimerDescription), TimerGroupName(TimerGroupName),
TimerGroupDescription(TimerGroupDescription) {}
};

// Flags representing which CFI section is required for a function/module.
enum class CFISection : unsigned {
None = 0, ///< Do not emit either .eh_frame or .debug_frame
Expand Down Expand Up @@ -206,11 +189,11 @@ class AsmPrinter : public MachineFunctionPass {

/// A vector of all debug/EH info emitters we should use. This vector
/// maintains ownership of the emitters.
SmallVector<HandlerInfo<AsmPrinterHandler>, 2> Handlers;
SmallVector<std::unique_ptr<AsmPrinterHandler>, 2> Handlers;
size_t NumUserHandlers = 0;

/// Debuginfo handler. Protected so that targets can add their own.
SmallVector<HandlerInfo<DebugHandlerBase>, 1> DebugHandlers;
SmallVector<std::unique_ptr<DebugHandlerBase>, 1> DebugHandlers;
size_t NumUserDebugHandlers = 0;

StackMaps SM;
Expand Down Expand Up @@ -536,15 +519,9 @@ class AsmPrinter : public MachineFunctionPass {
// Overridable Hooks
//===------------------------------------------------------------------===//

void addAsmPrinterHandler(HandlerInfo<AsmPrinterHandler> Handler) {
Handlers.insert(Handlers.begin(), std::move(Handler));
NumUserHandlers++;
}
void addAsmPrinterHandler(std::unique_ptr<AsmPrinterHandler> Handler);

void addDebugHandler(HandlerInfo<DebugHandlerBase> Handler) {
DebugHandlers.insert(DebugHandlers.begin(), std::move(Handler));
NumUserDebugHandlers++;
}
void addDebugHandler(std::unique_ptr<DebugHandlerBase> Handler);

// Targets can, or in the case of EmitInstruction, must implement these to
// customize output.
Expand Down
171 changes: 58 additions & 113 deletions llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@
#include "llvm/Support/Format.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Timer.h"
#include "llvm/Support/VCSRevision.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
Expand Down Expand Up @@ -156,17 +155,6 @@ static cl::bits<PGOMapFeaturesEnum> PgoAnalysisMapFeatures(
"Enable extended information within the SHT_LLVM_BB_ADDR_MAP that is "
"extracted from PGO related analysis."));

const char DWARFGroupName[] = "dwarf";
const char DWARFGroupDescription[] = "DWARF Emission";
const char DbgTimerName[] = "emit";
const char DbgTimerDescription[] = "Debug Info Emission";
const char EHTimerName[] = "write_exception";
const char EHTimerDescription[] = "DWARF Exception Writer";
const char CFGuardName[] = "Control Flow Guard";
const char CFGuardDescription[] = "Control Flow Guard";
const char CodeViewLineTablesGroupName[] = "linetables";
const char CodeViewLineTablesGroupDescription[] = "CodeView Line Tables";

STATISTIC(EmittedInsts, "Number of machine instrs printed");

char AsmPrinter::ID = 0;
Expand Down Expand Up @@ -550,19 +538,13 @@ bool AsmPrinter::doInitialization(Module &M) {

if (MAI->doesSupportDebugInformation()) {
bool EmitCodeView = M.getCodeViewFlag();
if (EmitCodeView && TM.getTargetTriple().isOSWindows()) {
DebugHandlers.emplace_back(std::make_unique<CodeViewDebug>(this),
DbgTimerName, DbgTimerDescription,
CodeViewLineTablesGroupName,
CodeViewLineTablesGroupDescription);
}
if (EmitCodeView && TM.getTargetTriple().isOSWindows())
DebugHandlers.push_back(std::make_unique<CodeViewDebug>(this));
if (!EmitCodeView || M.getDwarfVersion()) {
assert(MMI && "MMI could not be nullptr here!");
if (MMI->hasDebugInfo()) {
DD = new DwarfDebug(this);
DebugHandlers.emplace_back(std::unique_ptr<DwarfDebug>(DD),
DbgTimerName, DbgTimerDescription,
DWARFGroupName, DWARFGroupDescription);
DebugHandlers.push_back(std::unique_ptr<DwarfDebug>(DD));
}
}
}
Expand Down Expand Up @@ -625,26 +607,16 @@ bool AsmPrinter::doInitialization(Module &M) {
break;
}
if (ES)
Handlers.emplace_back(std::unique_ptr<EHStreamer>(ES), EHTimerName,
EHTimerDescription, DWARFGroupName,
DWARFGroupDescription);
Handlers.push_back(std::unique_ptr<EHStreamer>(ES));

// Emit tables for any value of cfguard flag (i.e. cfguard=1 or cfguard=2).
if (mdconst::extract_or_null<ConstantInt>(M.getModuleFlag("cfguard")))
Handlers.emplace_back(std::make_unique<WinCFGuard>(this), CFGuardName,
CFGuardDescription, DWARFGroupName,
DWARFGroupDescription);
Handlers.push_back(std::make_unique<WinCFGuard>(this));

for (const auto &HI : DebugHandlers) {
NamedRegionTimer T(HI.TimerName, HI.TimerDescription, HI.TimerGroupName,
HI.TimerGroupDescription, TimePassesIsEnabled);
HI.Handler->beginModule(&M);
}
for (const auto &HI : Handlers) {
NamedRegionTimer T(HI.TimerName, HI.TimerDescription, HI.TimerGroupName,
HI.TimerGroupDescription, TimePassesIsEnabled);
HI.Handler->beginModule(&M);
}
for (auto &Handler : DebugHandlers)
Handler->beginModule(&M);
for (auto &Handler : Handlers)
Handler->beginModule(&M);

return false;
}
Expand Down Expand Up @@ -791,11 +763,8 @@ void AsmPrinter::emitGlobalVariable(const GlobalVariable *GV) {
// sections and expected to be contiguous (e.g. ObjC metadata).
const Align Alignment = getGVAlignment(GV, DL);

for (auto &HI : DebugHandlers) {
NamedRegionTimer T(HI.TimerName, HI.TimerDescription, HI.TimerGroupName,
HI.TimerGroupDescription, TimePassesIsEnabled);
HI.Handler->setSymbolSize(GVSym, Size);
}
for (auto &Handler : DebugHandlers)
Handler->setSymbolSize(GVSym, Size);

// Handle common symbols
if (GVKind.isCommon()) {
Expand Down Expand Up @@ -1066,22 +1035,14 @@ void AsmPrinter::emitFunctionHeader() {
}

// Emit pre-function debug and/or EH information.
for (const auto &HI : DebugHandlers) {
NamedRegionTimer T(HI.TimerName, HI.TimerDescription, HI.TimerGroupName,
HI.TimerGroupDescription, TimePassesIsEnabled);
HI.Handler->beginFunction(MF);
HI.Handler->beginBasicBlockSection(MF->front());
}
for (const auto &HI : Handlers) {
NamedRegionTimer T(HI.TimerName, HI.TimerDescription, HI.TimerGroupName,
HI.TimerGroupDescription, TimePassesIsEnabled);
HI.Handler->beginFunction(MF);
}
for (const auto &HI : Handlers) {
NamedRegionTimer T(HI.TimerName, HI.TimerDescription, HI.TimerGroupName,
HI.TimerGroupDescription, TimePassesIsEnabled);
HI.Handler->beginBasicBlockSection(MF->front());
for (auto &Handler : DebugHandlers) {
Handler->beginFunction(MF);
Handler->beginBasicBlockSection(MF->front());
}
for (auto &Handler : Handlers)
Handler->beginFunction(MF);
for (auto &Handler : Handlers)
Handler->beginBasicBlockSection(MF->front());

// Emit the prologue data.
if (F.hasPrologueData())
Expand Down Expand Up @@ -1776,11 +1737,8 @@ void AsmPrinter::emitFunctionBody() {
if (MDNode *MD = MI.getPCSections())
emitPCSectionsLabel(*MF, *MD);

for (const auto &HI : DebugHandlers) {
NamedRegionTimer T(HI.TimerName, HI.TimerDescription, HI.TimerGroupName,
HI.TimerGroupDescription, TimePassesIsEnabled);
HI.Handler->beginInstruction(&MI);
}
for (auto &Handler : DebugHandlers)
Handler->beginInstruction(&MI);

if (isVerbose())
emitComments(MI, OutStreamer->getCommentOS());
Expand Down Expand Up @@ -1874,11 +1832,8 @@ void AsmPrinter::emitFunctionBody() {
if (MCSymbol *S = MI.getPostInstrSymbol())
OutStreamer->emitLabel(S);

for (const auto &HI : DebugHandlers) {
NamedRegionTimer T(HI.TimerName, HI.TimerDescription, HI.TimerGroupName,
HI.TimerGroupDescription, TimePassesIsEnabled);
HI.Handler->endInstruction();
}
for (auto &Handler : DebugHandlers)
Handler->endInstruction();
}

// We must emit temporary symbol for the end of this basic block, if either
Expand Down Expand Up @@ -2009,22 +1964,13 @@ void AsmPrinter::emitFunctionBody() {
// Call endBasicBlockSection on the last block now, if it wasn't already
// called.
if (!MF->back().isEndSection()) {
for (const auto &HI : DebugHandlers) {
NamedRegionTimer T(HI.TimerName, HI.TimerDescription, HI.TimerGroupName,
HI.TimerGroupDescription, TimePassesIsEnabled);
HI.Handler->endBasicBlockSection(MF->back());
}
for (const auto &HI : Handlers) {
NamedRegionTimer T(HI.TimerName, HI.TimerDescription, HI.TimerGroupName,
HI.TimerGroupDescription, TimePassesIsEnabled);
HI.Handler->endBasicBlockSection(MF->back());
}
}
for (const auto &HI : Handlers) {
NamedRegionTimer T(HI.TimerName, HI.TimerDescription, HI.TimerGroupName,
HI.TimerGroupDescription, TimePassesIsEnabled);
HI.Handler->markFunctionEnd();
for (auto &Handler : DebugHandlers)
Handler->endBasicBlockSection(MF->back());
for (auto &Handler : Handlers)
Handler->endBasicBlockSection(MF->back());
}
for (auto &Handler : Handlers)
Handler->markFunctionEnd();

MBBSectionRanges[MF->front().getSectionIDNum()] =
MBBSectionRange{CurrentFnBegin, CurrentFnEnd};
Expand All @@ -2033,16 +1979,10 @@ void AsmPrinter::emitFunctionBody() {
emitJumpTableInfo();

// Emit post-function debug and/or EH information.
for (const auto &HI : DebugHandlers) {
NamedRegionTimer T(HI.TimerName, HI.TimerDescription, HI.TimerGroupName,
HI.TimerGroupDescription, TimePassesIsEnabled);
HI.Handler->endFunction(MF);
}
for (const auto &HI : Handlers) {
NamedRegionTimer T(HI.TimerName, HI.TimerDescription, HI.TimerGroupName,
HI.TimerGroupDescription, TimePassesIsEnabled);
HI.Handler->endFunction(MF);
}
for (auto &Handler : DebugHandlers)
Handler->endFunction(MF);
for (auto &Handler : Handlers)
Handler->endFunction(MF);

// Emit section containing BB address offsets and their metadata, when
// BB labels are requested for this function. Skip empty functions.
Expand Down Expand Up @@ -2479,16 +2419,10 @@ bool AsmPrinter::doFinalization(Module &M) {
emitGlobalIFunc(M, IFunc);

// Finalize debug and EH information.
for (const auto &HI : DebugHandlers) {
NamedRegionTimer T(HI.TimerName, HI.TimerDescription, HI.TimerGroupName,
HI.TimerGroupDescription, TimePassesIsEnabled);
HI.Handler->endModule();
}
for (const auto &HI : Handlers) {
NamedRegionTimer T(HI.TimerName, HI.TimerDescription, HI.TimerGroupName,
HI.TimerGroupDescription, TimePassesIsEnabled);
HI.Handler->endModule();
}
for (auto &Handler : DebugHandlers)
Handler->endModule();
for (auto &Handler : Handlers)
Handler->endModule();

// This deletes all the ephemeral handlers that AsmPrinter added, while
// keeping all the user-added handlers alive until the AsmPrinter is
Expand Down Expand Up @@ -4010,9 +3944,9 @@ static void emitBasicBlockLoopComments(const MachineBasicBlock &MBB,
void AsmPrinter::emitBasicBlockStart(const MachineBasicBlock &MBB) {
// End the previous funclet and start a new one.
if (MBB.isEHFuncletEntry()) {
for (const auto &HI : Handlers) {
HI.Handler->endFunclet();
HI.Handler->beginFunclet(MBB);
for (auto &Handler : Handlers) {
Handler->endFunclet();
Handler->beginFunclet(MBB);
}
}

Expand Down Expand Up @@ -4083,21 +4017,21 @@ void AsmPrinter::emitBasicBlockStart(const MachineBasicBlock &MBB) {
// if it begins a section (Entry block call is handled separately, next to
// beginFunction).
if (MBB.isBeginSection() && !MBB.isEntryBlock()) {
for (const auto &HI : DebugHandlers)
HI.Handler->beginBasicBlockSection(MBB);
for (const auto &HI : Handlers)
HI.Handler->beginBasicBlockSection(MBB);
for (auto &Handler : DebugHandlers)
Handler->beginBasicBlockSection(MBB);
for (auto &Handler : Handlers)
Handler->beginBasicBlockSection(MBB);
}
}

void AsmPrinter::emitBasicBlockEnd(const MachineBasicBlock &MBB) {
// Check if CFI information needs to be updated for this MBB with basic block
// sections.
if (MBB.isEndSection()) {
for (const auto &HI : DebugHandlers)
HI.Handler->endBasicBlockSection(MBB);
for (const auto &HI : Handlers)
HI.Handler->endBasicBlockSection(MBB);
for (auto &Handler : DebugHandlers)
Handler->endBasicBlockSection(MBB);
for (auto &Handler : Handlers)
Handler->endBasicBlockSection(MBB);
}
}

Expand Down Expand Up @@ -4225,6 +4159,17 @@ void AsmPrinter::emitStackMaps() {
SM.serializeToStackMapSection();
}

void AsmPrinter::addAsmPrinterHandler(
std::unique_ptr<AsmPrinterHandler> Handler) {
Handlers.insert(Handlers.begin(), std::move(Handler));
NumUserHandlers++;
}

void AsmPrinter::addDebugHandler(std::unique_ptr<DebugHandlerBase> Handler) {
DebugHandlers.insert(DebugHandlers.begin(), std::move(Handler));
NumUserDebugHandlers++;
}

/// Pin vtable to this file.
AsmPrinterHandler::~AsmPrinterHandler() = default;

Expand Down
3 changes: 1 addition & 2 deletions llvm/lib/Target/BPF/BPFAsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,7 @@ bool BPFAsmPrinter::doInitialization(Module &M) {
// Only emit BTF when debuginfo available.
if (MAI->doesSupportDebugInformation() && !M.debug_compile_units().empty()) {
BTF = new BTFDebug(this);
DebugHandlers.emplace_back(std::unique_ptr<BTFDebug>(BTF), "emit",
"Debug Info Emission", "BTF", "BTF Emission");
DebugHandlers.push_back(std::unique_ptr<BTFDebug>(BTF));
}

return false;
Expand Down
Loading

0 comments on commit 80ffec7

Please sign in to comment.