From: Markus Böck Date: Tue, 6 Sep 2022 18:20:40 +0000 (+0200) Subject: [MC] Emit Stackmaps before debug info X-Git-Tag: upstream/17.0.6~34275 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f049b2c3fcbae739ac965f97fd6855ca1aab77b8;p=platform%2Fupstream%2Fllvm.git [MC] Emit Stackmaps before debug info This patch is essentially an alternative to https://reviews.llvm.org/D75836 and was mentioned by @lhames in a comment. The gist of the issue is that Mach-O has restrictions on which kind of sections are allowed after debug info has been emitted, which is also properly asserted within LLVM. Problem is that stack maps are currently emitted as one of the last sections in each target-specific AsmPrinter so far, which would cause the assertion to trigger. The current approach of special casing for the `__LLVM_STACKMAPS` section is not viable either, as downstream users can overwrite the stackmap format using plugins, which may want to use different sections. This patch fixes the issue by emitting the stack map earlier, right before debug info is emitted. The way this is implemented is by taking the choice when to emit the StackMap away from the target AsmPrinter and doing so in the base class. The only disadvantage of this approach is that the `StackMaps` member is now part of the base class, even for targets that do not support them. This is functionaly not a problem however, as emitting an empty `StackMaps` is a no-op. Differential Revision: https://reviews.llvm.org/D132708 --- diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h index 989cb71..f19f526 100644 --- a/llvm/include/llvm/CodeGen/AsmPrinter.h +++ b/llvm/include/llvm/CodeGen/AsmPrinter.h @@ -21,6 +21,7 @@ #include "llvm/CodeGen/AsmPrinterHandler.h" #include "llvm/CodeGen/DwarfStringPoolEntry.h" #include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/StackMaps.h" #include "llvm/IR/InlineAsm.h" #include "llvm/Support/ErrorHandling.h" #include @@ -68,7 +69,6 @@ class MDNode; class Module; class PseudoProbeHandler; class raw_ostream; -class StackMaps; class StringRef; class TargetLoweringObjectFile; class TargetMachine; @@ -202,6 +202,8 @@ protected: std::vector Handlers; size_t NumUserHandlers = 0; + StackMaps SM; + private: /// If generated on the fly this own the instance. std::unique_ptr OwnedMDT; @@ -503,7 +505,7 @@ public: void emitGlobalGOTEquivs(); /// Emit the stack maps. - void emitStackMaps(StackMaps &SM); + void emitStackMaps(); //===------------------------------------------------------------------===// // Overridable Hooks diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index c77c4eb..48c9667 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -354,7 +354,8 @@ Align AsmPrinter::getGVAlignment(const GlobalObject *GV, const DataLayout &DL, AsmPrinter::AsmPrinter(TargetMachine &tm, std::unique_ptr Streamer) : MachineFunctionPass(ID), TM(tm), MAI(tm.getMCAsmInfo()), - OutContext(Streamer->getContext()), OutStreamer(std::move(Streamer)) { + OutContext(Streamer->getContext()), OutStreamer(std::move(Streamer)), + SM(*this) { VerboseAsm = OutStreamer->isVerboseAsm(); } @@ -2078,6 +2079,12 @@ bool AsmPrinter::doFinalization(Module &M) { if (auto *TS = OutStreamer->getTargetStreamer()) TS->emitConstantPools(); + // Emit Stack maps before any debug info. Mach-O requires that no data or + // text sections come after debug info has been emitted. This matters for + // stack maps as they are arbitrary data, and may even have a custom format + // through user plugins. + emitStackMaps(); + // Finalize debug and EH information. for (const HandlerInfo &HI : Handlers) { NamedRegionTimer T(HI.TimerName, HI.TimerDescription, HI.TimerGroupName, @@ -3745,7 +3752,7 @@ GCMetadataPrinter *AsmPrinter::GetOrCreateGCPrinter(GCStrategy &S) { report_fatal_error("no GCMetadataPrinter registered for GC: " + Twine(Name)); } -void AsmPrinter::emitStackMaps(StackMaps &SM) { +void AsmPrinter::emitStackMaps() { GCModuleInfo *MI = getAnalysisIfAvailable(); assert(MI && "AsmPrinter didn't require GCModuleInfo?"); bool NeedsDefault = false; diff --git a/llvm/lib/MC/MCMachOStreamer.cpp b/llvm/lib/MC/MCMachOStreamer.cpp index f358f59..fcbe2e1 100644 --- a/llvm/lib/MC/MCMachOStreamer.cpp +++ b/llvm/lib/MC/MCMachOStreamer.cpp @@ -173,9 +173,7 @@ void MCMachOStreamer::changeSection(MCSection *Section, if (SegName == "__DWARF") CreatedADWARFSection = true; else if (Created && DWARFMustBeAtTheEnd && !canGoAfterDWARF(MSec)) - assert((!CreatedADWARFSection || - Section == getContext().getObjectFileInfo()->getStackMapSection()) - && "Creating regular section after DWARF"); + assert(!CreatedADWARFSection && "Creating regular section after DWARF"); // Output a linker-local symbol so we don't need section-relative local // relocations. The linker hates us when we do that. diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp index df2fce5..9d0b4e2 100644 --- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp +++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp @@ -70,7 +70,6 @@ namespace { class AArch64AsmPrinter : public AsmPrinter { AArch64MCInstLower MCInstLowering; - StackMaps SM; FaultMaps FM; const AArch64Subtarget *STI; bool ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags = false; @@ -78,7 +77,7 @@ class AArch64AsmPrinter : public AsmPrinter { public: AArch64AsmPrinter(TargetMachine &TM, std::unique_ptr Streamer) : AsmPrinter(TM, std::move(Streamer)), MCInstLowering(OutContext, *this), - SM(*this), FM(*this) {} + FM(*this) {} StringRef getPassName() const override { return "AArch64 Assembly Printer"; } @@ -685,9 +684,8 @@ void AArch64AsmPrinter::emitEndOfAsmFile(Module &M) { // generates code that does this, it is always safe to set. OutStreamer->emitAssemblerFlag(MCAF_SubsectionsViaSymbols); } - + // Emit stack and fault map information. - emitStackMaps(SM); FM.serializeToFaultMapSection(); } diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp index 2f30e52..17a829b 100644 --- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -140,12 +140,11 @@ protected: MCSymbol *> TOC; const PPCSubtarget *Subtarget = nullptr; - StackMaps SM; public: explicit PPCAsmPrinter(TargetMachine &TM, std::unique_ptr Streamer) - : AsmPrinter(TM, std::move(Streamer)), SM(*this) {} + : AsmPrinter(TM, std::move(Streamer)) {} StringRef getPassName() const override { return "PowerPC Assembly Printer"; } @@ -172,8 +171,6 @@ public: bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &O) override; - void emitEndOfAsmFile(Module &M) override; - void LowerSTACKMAP(StackMaps &SM, const MachineInstr &MI); void LowerPATCHPOINT(StackMaps &SM, const MachineInstr &MI); void EmitTlsCall(const MachineInstr *MI, MCSymbolRefExpr::VariantKind VK); @@ -427,10 +424,6 @@ PPCAsmPrinter::lookUpOrCreateTOCEntry(const MCSymbol *Sym, return TOCEntry; } -void PPCAsmPrinter::emitEndOfAsmFile(Module &M) { - emitStackMaps(SM); -} - void PPCAsmPrinter::LowerSTACKMAP(StackMaps &SM, const MachineInstr &MI) { unsigned NumNOPBytes = MI.getOperand(1).getImm(); diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp index 1d55bf9..aff9e2f 100644 --- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp +++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp @@ -817,10 +817,6 @@ bool SystemZAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, return false; } -void SystemZAsmPrinter::emitEndOfAsmFile(Module &M) { - emitStackMaps(SM); -} - void SystemZAsmPrinter::emitFunctionBodyEnd() { if (TM.getTargetTriple().isOSzOS()) { // Emit symbol for the end of function if the z/OS target streamer diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h index f14b4a1..044dfbc 100644 --- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h +++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h @@ -25,7 +25,6 @@ class raw_ostream; class LLVM_LIBRARY_VISIBILITY SystemZAsmPrinter : public AsmPrinter { private: - StackMaps SM; MCSymbol *CurrentFnPPA1Sym; // PPA1 Symbol. MCSymbol *CurrentFnEPMarkerSym; // Entry Point Marker. @@ -51,14 +50,13 @@ private: public: SystemZAsmPrinter(TargetMachine &TM, std::unique_ptr Streamer) - : AsmPrinter(TM, std::move(Streamer)), SM(*this), - CurrentFnPPA1Sym(nullptr), CurrentFnEPMarkerSym(nullptr) {} + : AsmPrinter(TM, std::move(Streamer)), CurrentFnPPA1Sym(nullptr), + CurrentFnEPMarkerSym(nullptr) {} // Override AsmPrinter. StringRef getPassName() const override { return "SystemZ Assembly Printer"; } void emitInstruction(const MachineInstr *MI) override; void emitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) override; - void emitEndOfAsmFile(Module &M) override; bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS) override; bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, diff --git a/llvm/lib/Target/X86/X86AsmPrinter.cpp b/llvm/lib/Target/X86/X86AsmPrinter.cpp index 3e0f2a4..968e680 100644 --- a/llvm/lib/Target/X86/X86AsmPrinter.cpp +++ b/llvm/lib/Target/X86/X86AsmPrinter.cpp @@ -49,7 +49,7 @@ using namespace llvm; X86AsmPrinter::X86AsmPrinter(TargetMachine &TM, std::unique_ptr Streamer) - : AsmPrinter(TM, std::move(Streamer)), SM(*this), FM(*this) {} + : AsmPrinter(TM, std::move(Streamer)), FM(*this) {} //===----------------------------------------------------------------------===// // Primitive Helper Functions. @@ -889,8 +889,7 @@ void X86AsmPrinter::emitEndOfAsmFile(Module &M) { // global table for symbol lookup. emitNonLazyStubs(MMI, *OutStreamer); - // Emit stack and fault map information. - emitStackMaps(SM); + // Emit fault map information. FM.serializeToFaultMapSection(); // This flag tells the linker that no global symbols contain code that fall @@ -920,9 +919,7 @@ void X86AsmPrinter::emitEndOfAsmFile(Module &M) { OutStreamer->emitSymbolAttribute(S, MCSA_Global); return; } - emitStackMaps(SM); } else if (TT.isOSBinFormatELF()) { - emitStackMaps(SM); FM.serializeToFaultMapSection(); } diff --git a/llvm/lib/Target/X86/X86AsmPrinter.h b/llvm/lib/Target/X86/X86AsmPrinter.h index b9aefe4..c81651c 100644 --- a/llvm/lib/Target/X86/X86AsmPrinter.h +++ b/llvm/lib/Target/X86/X86AsmPrinter.h @@ -26,7 +26,6 @@ class TargetMachine; class LLVM_LIBRARY_VISIBILITY X86AsmPrinter : public AsmPrinter { const X86Subtarget *Subtarget = nullptr; - StackMaps SM; FaultMaps FM; std::unique_ptr CodeEmitter; bool EmitFPOData = false; diff --git a/llvm/test/CodeGen/X86/stackmap-macho.ll b/llvm/test/CodeGen/X86/stackmap-macho.ll new file mode 100644 index 0000000..a664674 --- /dev/null +++ b/llvm/test/CodeGen/X86/stackmap-macho.ll @@ -0,0 +1,28 @@ +; RUN: llc -verify-machineinstrs < %s | FileCheck %s + +; Used to crash with assertions when emitting object files. +; RUN: llc -filetype=obj %s -o /dev/null + +; Check stack map section is emitted before debug info. +; CHECK: .section __LLVM_STACKMAPS +; CHECK: .section __DWARF + +target triple = "x86_64-apple-macosx12.0" + +declare void @func() + +define ptr addrspace(1) @test1(ptr addrspace(1) %arg) gc "statepoint-example" { +entry: + %safepoint_token = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) @func, i32 0, i32 0, i32 0, i32 0) ["gc-live"(ptr addrspace(1) %arg)] + %reloc1 = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 0, i32 0) + ret ptr addrspace(1) %reloc1 +} + +declare token @llvm.experimental.gc.statepoint.p0(i64, i32, ptr, i32, i32, ...) +declare ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token, i32, i32) + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!2} +!0 = distinct !DICompileUnit(language: DW_LANG_C89, producer: "clang", isOptimized: true, emissionKind: FullDebug, file: !1, enums: !{}, retainedTypes: !{}) +!1 = !DIFile(filename: "t.c", directory: "") +!2 = !{i32 2, !"Debug Info Version", i32 3} diff --git a/llvm/test/CodeGen/X86/statepoint-stackmap-size.ll b/llvm/test/CodeGen/X86/statepoint-stackmap-size.ll index 7fb7516..38e74e0 100644 --- a/llvm/test/CodeGen/X86/statepoint-stackmap-size.ll +++ b/llvm/test/CodeGen/X86/statepoint-stackmap-size.ll @@ -3,7 +3,7 @@ ; Without removal of duplicate entries, the size is 62 lines ; CHECK: .section .llvm_stackmaps,{{.*$}} ; CHECK-NEXT:{{(.+$[[:space:]]){48}[[:space:]]}} -; CHECK-NOT:{{.|[[:space:]]}} +; CHECK-SAME: .section target triple = "x86_64-pc-linux-gnu"