diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h --- 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 Module; class PseudoProbeHandler; class raw_ostream; -class StackMaps; class StringRef; class TargetLoweringObjectFile; class TargetMachine; @@ -202,6 +202,8 @@ 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 @@ 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 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -354,7 +354,8 @@ 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 @@ 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 @@ 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 --- a/llvm/lib/MC/MCMachOStreamer.cpp +++ b/llvm/lib/MC/MCMachOStreamer.cpp @@ -173,9 +173,7 @@ 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 --- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp +++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp @@ -70,7 +70,6 @@ class AArch64AsmPrinter : public AsmPrinter { AArch64MCInstLower MCInstLowering; - StackMaps SM; FaultMaps FM; const AArch64Subtarget *STI; bool ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags = false; @@ -78,7 +77,7 @@ 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 @@ // 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 --- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -140,12 +140,11 @@ 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 @@ 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 @@ 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.h b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h --- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h +++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h @@ -25,7 +25,6 @@ class LLVM_LIBRARY_VISIBILITY SystemZAsmPrinter : public AsmPrinter { private: - StackMaps SM; MCSymbol *CurrentFnPPA1Sym; // PPA1 Symbol. MCSymbol *CurrentFnEPMarkerSym; // Entry Point Marker. @@ -51,14 +50,13 @@ 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/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp --- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp +++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp @@ -817,10 +817,6 @@ 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/X86/X86AsmPrinter.h b/llvm/lib/Target/X86/X86AsmPrinter.h --- a/llvm/lib/Target/X86/X86AsmPrinter.h +++ b/llvm/lib/Target/X86/X86AsmPrinter.h @@ -26,7 +26,6 @@ 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/lib/Target/X86/X86AsmPrinter.cpp b/llvm/lib/Target/X86/X86AsmPrinter.cpp --- a/llvm/lib/Target/X86/X86AsmPrinter.cpp +++ b/llvm/lib/Target/X86/X86AsmPrinter.cpp @@ -49,7 +49,7 @@ 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 @@ // 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 @@ OutStreamer->emitSymbolAttribute(S, MCSA_Global); return; } - emitStackMaps(SM); } else if (TT.isOSBinFormatELF()) { - emitStackMaps(SM); FM.serializeToFaultMapSection(); } diff --git a/llvm/test/CodeGen/X86/stackmap-macho.ll b/llvm/test/CodeGen/X86/stackmap-macho.ll new file mode 100644 --- /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 --- 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"