Skip to content

Reintroduce full AsmPrinterHandler API (#122297) #39

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 21, 2025
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
17 changes: 9 additions & 8 deletions llvm/include/llvm/CodeGen/AsmPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class DebugHandlerBase;
class DIE;
class DIEAbbrev;
class DwarfDebug;
class EHStreamer;
class GCMetadataPrinter;
class GCStrategy;
class GlobalAlias;
Expand Down Expand Up @@ -187,15 +188,17 @@ class AsmPrinter : public MachineFunctionPass {
/// For dso_local functions, the current $local alias for the function.
MCSymbol *CurrentFnBeginLocal = nullptr;

/// A vector of all debug/EH info emitters we should use. This vector
/// maintains ownership of the emitters.
/// A handle to the EH info emitter (if present).
// Only for EHStreamer subtypes, but some C++ compilers will incorrectly warn
// us if we declare that directly.
SmallVector<std::unique_ptr<AsmPrinterHandler>, 1> EHHandlers;

// A vector of all Debuginfo emitters we should use. Protected so that
// targets can add their own. This vector maintains ownership of the
// emitters.
SmallVector<std::unique_ptr<AsmPrinterHandler>, 2> Handlers;
size_t NumUserHandlers = 0;

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

StackMaps SM;

private:
Expand Down Expand Up @@ -521,8 +524,6 @@ class AsmPrinter : public MachineFunctionPass {

void addAsmPrinterHandler(std::unique_ptr<AsmPrinterHandler> Handler);

void addDebugHandler(std::unique_ptr<DebugHandlerBase> Handler);

// Targets can, or in the case of EmitInstruction, must implement these to
// customize output.

Expand Down
12 changes: 12 additions & 0 deletions llvm/include/llvm/CodeGen/AsmPrinterHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,18 @@ class AsmPrinterHandler {
/// immediately prior to markFunctionEnd.
virtual void endBasicBlockSection(const MachineBasicBlock &MBB) {}

/// For symbols that have a size designated (e.g. common symbols),
/// this tracks that size.
virtual void setSymbolSize(const MCSymbol *Sym, uint64_t Size) {}

/// Process beginning of an instruction.
virtual void beginInstruction(const MachineInstr *MI) {}

/// Process end of an instruction.
virtual void endInstruction() {}

virtual void beginCodeAlignment(const MachineBasicBlock &MBB) {}

/// Emit target-specific EH funclet machinery.
virtual void beginFunclet(const MachineBasicBlock &MBB,
MCSymbol *Sym = nullptr) {}
Expand Down
26 changes: 10 additions & 16 deletions llvm/include/llvm/CodeGen/DebugHandlerBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,10 @@ struct DbgVariableLocation {

/// Base class for debug information backends. Common functionality related to
/// tracking which variables and scopes are alive at a given PC live here.
class DebugHandlerBase {
class DebugHandlerBase : public AsmPrinterHandler {
protected:
DebugHandlerBase(AsmPrinter *A);

public:
virtual ~DebugHandlerBase();

protected:
/// Target of debug info emission.
AsmPrinter *Asm = nullptr;

Expand Down Expand Up @@ -120,22 +116,20 @@ class DebugHandlerBase {
private:
InstructionOrdering InstOrdering;

// AsmPrinterHandler overrides.
public:
/// For symbols that have a size designated (e.g. common symbols),
/// this tracks that size. Only used by DWARF.
virtual void setSymbolSize(const MCSymbol *Sym, uint64_t Size) {}
virtual ~DebugHandlerBase() override;

virtual void beginModule(Module *M);
virtual void endModule() = 0;
void beginModule(Module *M) override;

virtual void beginInstruction(const MachineInstr *MI);
virtual void endInstruction();
void beginInstruction(const MachineInstr *MI) override;
void endInstruction() override;

void beginFunction(const MachineFunction *MF);
void endFunction(const MachineFunction *MF);
void beginFunction(const MachineFunction *MF) override;
void endFunction(const MachineFunction *MF) override;

void beginBasicBlockSection(const MachineBasicBlock &MBB);
void endBasicBlockSection(const MachineBasicBlock &MBB);
void beginBasicBlockSection(const MachineBasicBlock &MBB) override;
void endBasicBlockSection(const MachineBasicBlock &MBB) override;

/// Return Label preceding the instruction.
MCSymbol *getLabelBeforeInsn(const MachineInstr *MI);
Expand Down
68 changes: 34 additions & 34 deletions llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -539,12 +539,12 @@ bool AsmPrinter::doInitialization(Module &M) {
if (MAI->doesSupportDebugInformation()) {
bool EmitCodeView = M.getCodeViewFlag();
if (EmitCodeView && TM.getTargetTriple().isOSWindows())
DebugHandlers.push_back(std::make_unique<CodeViewDebug>(this));
Handlers.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.push_back(std::unique_ptr<DwarfDebug>(DD));
Handlers.push_back(std::unique_ptr<DwarfDebug>(DD));
}
}
}
Expand Down Expand Up @@ -611,12 +611,12 @@ bool AsmPrinter::doInitialization(Module &M) {

// 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.push_back(std::make_unique<WinCFGuard>(this));
EHHandlers.push_back(std::make_unique<WinCFGuard>(this));

for (auto &Handler : DebugHandlers)
Handler->beginModule(&M);
for (auto &Handler : Handlers)
Handler->beginModule(&M);
for (auto &Handler : EHHandlers)
Handler->beginModule(&M);

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

for (auto &Handler : DebugHandlers)
for (auto &Handler : Handlers)
Handler->setSymbolSize(GVSym, Size);

// Handle common symbols
Expand Down Expand Up @@ -1035,14 +1035,14 @@ void AsmPrinter::emitFunctionHeader() {
}

// Emit pre-function debug and/or EH information.
for (auto &Handler : DebugHandlers) {
for (auto &Handler : Handlers) {
Handler->beginFunction(MF);
Handler->beginBasicBlockSection(MF->front());
}
for (auto &Handler : Handlers)
for (auto &Handler : EHHandlers) {
Handler->beginFunction(MF);
for (auto &Handler : Handlers)
Handler->beginBasicBlockSection(MF->front());
}

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

for (auto &Handler : DebugHandlers)
for (auto &Handler : Handlers)
Handler->beginInstruction(&MI);

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

for (auto &Handler : DebugHandlers)
for (auto &Handler : Handlers)
Handler->endInstruction();
}

Expand Down Expand Up @@ -1966,27 +1966,26 @@ void AsmPrinter::emitFunctionBody() {
// Call endBasicBlockSection on the last block now, if it wasn't already
// called.
if (!MF->back().isEndSection()) {
for (auto &Handler : DebugHandlers)
Handler->endBasicBlockSection(MF->back());
for (auto &Handler : Handlers)
Handler->endBasicBlockSection(MF->back());
for (auto &Handler : EHHandlers)
Handler->endBasicBlockSection(MF->back());
}
for (auto &Handler : Handlers)
Handler->markFunctionEnd();

assert(!MBBSectionRanges.contains(MF->front().getSectionID()) &&
"Overwrite section range");
MBBSectionRanges[MF->front().getSectionID()] =
MBBSectionRange{CurrentFnBegin, CurrentFnEnd};
for (auto &Handler : EHHandlers)
Handler->markFunctionEnd();
// Update the end label of the entry block's section.
MBBSectionRanges[MF->front().getSectionID()].EndLabel = CurrentFnEnd;

// Print out jump tables referenced by the function.
emitJumpTableInfo();

// Emit post-function debug and/or EH information.
for (auto &Handler : DebugHandlers)
Handler->endFunction(MF);
for (auto &Handler : Handlers)
Handler->endFunction(MF);
for (auto &Handler : EHHandlers)
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 @@ -2425,17 +2424,16 @@ bool AsmPrinter::doFinalization(Module &M) {
emitGlobalIFunc(M, IFunc);

// Finalize debug and EH information.
for (auto &Handler : DebugHandlers)
Handler->endModule();
for (auto &Handler : Handlers)
Handler->endModule();
for (auto &Handler : EHHandlers)
Handler->endModule();

// This deletes all the ephemeral handlers that AsmPrinter added, while
// keeping all the user-added handlers alive until the AsmPrinter is
// destroyed.
EHHandlers.clear();
Handlers.erase(Handlers.begin() + NumUserHandlers, Handlers.end());
DebugHandlers.erase(DebugHandlers.begin() + NumUserDebugHandlers,
DebugHandlers.end());
DD = nullptr;

// If the target wants to know about weak references, print them all.
Expand Down Expand Up @@ -3957,6 +3955,10 @@ void AsmPrinter::emitBasicBlockStart(const MachineBasicBlock &MBB) {
Handler->endFunclet();
Handler->beginFunclet(MBB);
}
for (auto &Handler : EHHandlers) {
Handler->endFunclet();
Handler->beginFunclet(MBB);
}
}

// Switch to a new section if this basic block must begin a section. The
Expand All @@ -3969,6 +3971,9 @@ void AsmPrinter::emitBasicBlockStart(const MachineBasicBlock &MBB) {
CurrentSectionBeginSym = MBB.getSymbol();
}

for (auto &Handler : Handlers)
Handler->beginCodeAlignment(MBB);

// Emit an alignment directive for this block, if needed.
const Align Alignment = MBB.getAlignment();
if (Alignment != Align(1))
Expand Down Expand Up @@ -4026,21 +4031,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 (auto &Handler : DebugHandlers)
Handler->beginBasicBlockSection(MBB);
for (auto &Handler : Handlers)
Handler->beginBasicBlockSection(MBB);
for (auto &Handler : EHHandlers)
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 (auto &Handler : DebugHandlers)
Handler->endBasicBlockSection(MBB);
for (auto &Handler : Handlers)
Handler->endBasicBlockSection(MBB);
for (auto &Handler : EHHandlers)
Handler->endBasicBlockSection(MBB);
}
}

Expand Down Expand Up @@ -4174,12 +4179,7 @@ void AsmPrinter::addAsmPrinterHandler(
NumUserHandlers++;
}

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

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

void AsmPrinterHandler::markFunctionEnd() {}
Expand Down
1 change: 0 additions & 1 deletion llvm/lib/CodeGen/AsmPrinter/PseudoProbePrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
#define LLVM_LIB_CODEGEN_ASMPRINTER_PSEUDOPROBEPRINTER_H

#include "llvm/ADT/DenseMap.h"
#include "llvm/CodeGen/AsmPrinterHandler.h"

namespace llvm {

Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/BPF/BPFAsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +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.push_back(std::unique_ptr<BTFDebug>(BTF));
Handlers.push_back(std::unique_ptr<BTFDebug>(BTF));
}

return false;
Expand Down
53 changes: 3 additions & 50 deletions llvm/unittests/CodeGen/AsmPrinterDwarfTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -384,10 +384,13 @@ class AsmPrinterHandlerTest : public AsmPrinterFixtureBase {
public:
TestHandler(AsmPrinterHandlerTest &Test) : Test(Test) {}
virtual ~TestHandler() {}
virtual void setSymbolSize(const MCSymbol *Sym, uint64_t Size) override {}
virtual void beginModule(Module *M) override { Test.BeginCount++; }
virtual void endModule() override { Test.EndCount++; }
virtual void beginFunction(const MachineFunction *MF) override {}
virtual void endFunction(const MachineFunction *MF) override {}
virtual void beginInstruction(const MachineInstr *MI) override {}
virtual void endInstruction() override {}
};

protected:
Expand Down Expand Up @@ -424,54 +427,4 @@ TEST_F(AsmPrinterHandlerTest, Basic) {
ASSERT_EQ(EndCount, 3);
}

class AsmPrinterDebugHandlerTest : public AsmPrinterFixtureBase {
class TestDebugHandler : public DebugHandlerBase {
AsmPrinterDebugHandlerTest &Test;

public:
TestDebugHandler(AsmPrinterDebugHandlerTest &Test, AsmPrinter *AP)
: DebugHandlerBase(AP), Test(Test) {}
virtual ~TestDebugHandler() {}
virtual void beginModule(Module *M) override { Test.BeginCount++; }
virtual void endModule() override { Test.EndCount++; }
virtual void beginFunctionImpl(const MachineFunction *MF) override {}
virtual void endFunctionImpl(const MachineFunction *MF) override {}
virtual void beginInstruction(const MachineInstr *MI) override {}
virtual void endInstruction() override {}
};

protected:
bool init(const std::string &TripleStr, unsigned DwarfVersion,
dwarf::DwarfFormat DwarfFormat) {
if (!AsmPrinterFixtureBase::init(TripleStr, DwarfVersion, DwarfFormat))
return false;

auto *AP = TestPrinter->getAP();
AP->addDebugHandler(std::make_unique<TestDebugHandler>(*this, AP));
LLVMTargetMachine *LLVMTM = static_cast<LLVMTargetMachine *>(&AP->TM);
legacy::PassManager PM;
PM.add(new MachineModuleInfoWrapperPass(LLVMTM));
PM.add(TestPrinter->releaseAP()); // Takes ownership of destroying AP
LLVMContext Context;
std::unique_ptr<Module> M(new Module("TestModule", Context));
M->setDataLayout(LLVMTM->createDataLayout());
PM.run(*M);
// Now check that we can run it twice.
AP->addDebugHandler(std::make_unique<TestDebugHandler>(*this, AP));
PM.run(*M);
return true;
}

int BeginCount = 0;
int EndCount = 0;
};

TEST_F(AsmPrinterDebugHandlerTest, Basic) {
if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32))
GTEST_SKIP();

ASSERT_EQ(BeginCount, 3);
ASSERT_EQ(EndCount, 3);
}

} // end namespace