Skip to content

Commit 0c0273f

Browse files
committed
Squashed version of all CFI patches
This is being reviewed upstream (see Differential Revisions in each per-commit message below) but has stalled while we go through the LLVM RFC process. The latest version of these patches should not present a large maintenance burden in amd-stg-open as it no longer relies on certain function attributes being present in lit tests. This is the 1st commit message: Implement DW_CFA_LLVM_* for Heterogeneous Debugging Summary: Add support in MC/MIR for writing/parsing, and DebugInfo. Tags: #llvm Differential Revision: https://reviews.llvm.org/D76877 This is the commit message #2: Add SupportsDebugUnwindInformation to MCAsmInfo Summary: Generating unwind information is entangled with supporting exceptions, even when AsmPrinter explicitly recognizes that the unwind tables are being generated only as debug information. Add SupportsDebugUnwindInformation as a workaround for targets which do not have EH support but which do support unwind information for debugging. This new option only has an effect when the `None` EH model is specified. The option requests that .debug_frame be generated when debug info is requested. Add a new AsmPrinterHandler called UnwindStreamer which just ensures the proper .cfi_sections and .cfi_startproc/.cfi_endproc directives are emitted when the option is in effect. This duplicates trivial amounts of DwarfException, but not enough to make factoring it out helpful. In the future this could be unified/simplified with the existing EH support if debug handling is made orthogonal to unwind information generation. Subscribers: mgorny, aprantl, hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D78778 This is the commit message #3: Implement DW_{OP,AT}_LLVM_* for Heterogeneous Debugging Summary: The chosen encoding has some collisions, which are resolved by using the new augmentation attribute on the compilation unit and in unwind information CIEs for any target which wishes to use the operations defined by the extension. Tags: #llvm Differential Revision: https://reviews.llvm.org/D76878 This is the commit message #4: [AMDGPU] Begin emitting CFI for AMDGCN Summary: Enable SupportsDebugUnwindInformation for AMDGCN, so we get unwind information when debug information is requested. Tags: #llvm Differential Revision: https://reviews.llvm.org/D76879 This is the commit message #5: [AMDGPU] Emit entry function CFI Summary: Entry functions represent the end of unwinding, as they are the outer-most frame. This implies they can only have a meaningful definition for the CFA, which AMDGPU defines using a memory location description with a literal private address space address. The return address is set to `undefined` as a sentinel value to signal the end of unwinding. Tags: #llvm Differential Revision: https://reviews.llvm.org/D76880 This is the commit message #6: [AMDGPU] Skip MetaInstructions in SIInsertWaitcnts Summary: CFI emitted during PEI at the beginning of the prologue needs to apply to any inserted waitcnts on function entry. Tags: #llvm Differential Revision: https://reviews.llvm.org/D76881 This is the commit message #7: [AMDGPU] Implement CFI for non-kernel functions Summary: This does not implement CSR spills other than those AMDGPU handles during PEI. Tags: #llvm Differential Revision: https://reviews.llvm.org/D76882 This is the commit message #8: [AMDGPU] Implement CFI for CSR spills Summary: Introduce new SPILL pseudos to allow CFI to be generated for only CSR spills, and to make ISA-instruction-level accurate information. Other targets either generate slightly incorrect information or rely on conventions for how spills are placed within the entry block. The approach in this change produces larger unwind tables, with the increased size being spent on additional DW_CFA_advance_location instructions needed to describe the unwinding accurately. Tags: #llvm Differential Revision: https://reviews.llvm.org/D76883 This is the commit message #9: [AMDGPU] Implement -amdgpu-spill-cfi-saved-regs Summary: These spills need special CFI anyway, so implementing them directly where CFI is emitted avoids the need to invent a mechanism to track them from ISel. Tags: #llvm Differential Revision: https://reviews.llvm.org/D76884 This is the commit message #10: Imply -amdgpu-spill-cfi-saved-regs with -ggdb for AMDGPU (cherry picked from commit d02227f) Change-Id: Idf10a3f6b4fd316c02267e2c74639afe52ad8e40
1 parent 301849d commit 0c0273f

56 files changed

Lines changed: 1711 additions & 143 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3733,6 +3733,8 @@ static void RenderDebugOptions(const ToolChain &TC, const Driver &D,
37333733
if (T.getArch() == llvm::Triple::amdgcn) {
37343734
CmdArgs.push_back("-disable-O0-optnone");
37353735
CmdArgs.push_back("-disable-O0-noinline");
3736+
CmdArgs.push_back("-mllvm");
3737+
CmdArgs.push_back("-amdgpu-spill-cfi-saved-regs");
37363738
// -ggdb with AMDGCN does not currently compose with options that
37373739
// affect the debug info kind. The behavior of commands like `-ggdb
37383740
// -g` may be surprising (the -g is effectively ignored).

clang/test/Driver/amdgpu-debug.cl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
// CHECK-SIMPLE-DAG: "-debug-info-kind=line-tables-only"
77
// CHECK-SIMPLE-DAG: "-disable-O0-optnone"
88
// CHECK-SIMPLE-DAG: "-disable-O0-noinline"
9+
// CHECK-SIMPLE-DAG: "-mllvm" "-amdgpu-spill-cfi-saved-regs"
910
// CHECK-SIMPLE-DAG: "-debugger-tuning=gdb"
1011

1112
// Check that a debug-related option which does not affect the debug-info-kind
@@ -15,6 +16,7 @@
1516
// CHECK-DWARF2-DAG: "-debug-info-kind=line-tables-only"
1617
// CHECK-DWARF2-DAG: "-disable-O0-optnone"
1718
// CHECK-DWARF2-DAG: "-disable-O0-noinline"
19+
// CHECK-DWARF2-DAG: "-mllvm" "-amdgpu-spill-cfi-saved-regs"
1820
// CHECK-DWARF2-DAG: "-debugger-tuning=gdb"
1921
// CHECK-DWARF2-DAG: "-dwarf-version=2"
2022

@@ -34,6 +36,7 @@
3436
// CHECK-LLDBBEFORE-DAG: "-debug-info-kind=line-tables-only"
3537
// CHECK-LLDBBEFORE-DAG: "-disable-O0-optnone"
3638
// CHECK-LLDBBEFORE-DAG: "-disable-O0-noinline"
39+
// CHECK-LLDBBEFORE-DAG: "-mllvm" "-amdgpu-spill-cfi-saved-regs"
3740
// CHECK-LLDBBEFORE-DAG: "-debugger-tuning=gdb"
3841
// RUN: %clang -### -target amdgcn-amd-amdhsa -x cl -c -emit-llvm -ggdb -glldb %s 2>&1 | FileCheck -check-prefix=CHECK-LLDBAFTER %s
3942
// CHECK-LLDBAFTER: "-cc1"

clang/test/Driver/hip-debug.hip

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,15 @@
1212
// CHECK-DAG: "-debug-info-kind=line-tables-only"
1313
// CHECK-DAG: "-disable-O0-optnone"
1414
// CHECK-DAG: "-disable-O0-noinline"
15+
// CHECK-DAG: "-mllvm" "-amdgpu-spill-cfi-saved-regs"
1516
// CHECK-DAG: "-debugger-tuning=gdb"
1617
// CHECK-LABEL: clang-offload-bundler
1718
// CHECK: {{.*}}clang{{.*}}"-triple" "x86_64-unknown-linux-gnu"
1819
// CHECK-NOT: "-disable-O0-optnone"
1920
// CHECK-NOT: "-disable-O0-noinline"
21+
// CHECK-NOT: "-amdgpu-spill-cfi-saved-regs"
2022
// CHECK-DAG: "-debug-info-kind=limited"
2123
// CHECK-DAG: "-debugger-tuning=gdb"
2224
// CHECK-NOT: "-disable-O0-optnone"
2325
// CHECK-NOT: "-disable-O0-noinline"
26+
// CHECK-NOT: "-amdgpu-spill-cfi-saved-regs"

llvm/include/llvm/BinaryFormat/Dwarf.def

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,13 @@ HANDLE_DW_AT(0x3e02, LLVM_sysroot, 0, LLVM)
418418
HANDLE_DW_AT(0x3e03, LLVM_tag_offset, 0, LLVM)
419419
// The missing numbers here are reserved for ptrauth support.
420420
HANDLE_DW_AT(0x3e07, LLVM_apinotes, 0, APPLE)
421+
// Heterogeneous Debugging Extension defined at
422+
// https://llvm.org/docs/AMDGPUDwarfProposalForHeterogeneousDebugging.html.
423+
HANDLE_DW_AT(0x3e08, LLVM_active_lane, 0, LLVM)
424+
HANDLE_DW_AT(0x3e09, LLVM_augmentation, 0, LLVM)
425+
HANDLE_DW_AT(0x3e0a, LLVM_lanes, 0, LLVM)
426+
HANDLE_DW_AT(0x3e0b, LLVM_lane_pc, 0, LLVM)
427+
HANDLE_DW_AT(0x3e0c, LLVM_vector_size, 0, LLVM)
421428

422429
// Apple extensions.
423430

@@ -669,6 +676,23 @@ HANDLE_DW_OP(0xf3, GNU_entry_value, 0, GNU)
669676
// Extensions for Fission proposal.
670677
HANDLE_DW_OP(0xfb, GNU_addr_index, 0, GNU)
671678
HANDLE_DW_OP(0xfc, GNU_const_index, 0, GNU)
679+
// Heterogeneous Debugging Extension defined at
680+
// https://llvm.org/docs/AMDGPUDwarfProposalForHeterogeneousDebugging.html.
681+
// These collide with some HP and PGI vendor extensions, but this ambiguity is
682+
// resolved by ensuring CIE augmentation strings and compilation unit
683+
// DW_AT_LLVM_augmentation strings include "[llvm:v0.0]".
684+
HANDLE_DW_OP(0xe1, LLVM_form_aspace_address, 0, LLVM)
685+
HANDLE_DW_OP(0xe2, LLVM_push_lane, 0, LLVM)
686+
HANDLE_DW_OP(0xe3, LLVM_offset, 0, LLVM)
687+
HANDLE_DW_OP(0xe4, LLVM_offset_uconst, 0, LLVM)
688+
HANDLE_DW_OP(0xe5, LLVM_bit_offset, 0, LLVM)
689+
HANDLE_DW_OP(0xe6, LLVM_call_frame_entry_reg, 0, LLVM)
690+
HANDLE_DW_OP(0xe7, LLVM_undefined, 0, LLVM)
691+
HANDLE_DW_OP(0xe8, LLVM_aspace_bregx, 0, LLVM)
692+
HANDLE_DW_OP(0xe9, LLVM_aspace_implicit_pointer, 0, LLVM)
693+
HANDLE_DW_OP(0xea, LLVM_piece_end, 0, LLVM)
694+
HANDLE_DW_OP(0xeb, LLVM_extend, 0, LLVM)
695+
HANDLE_DW_OP(0xec, LLVM_select_bit_piece, 0, LLVM)
672696

673697
// DWARF languages.
674698
HANDLE_DW_LANG(0x0001, C89, 0, 2, DWARF)
@@ -895,6 +919,10 @@ HANDLE_DW_CFA_PRED(0x1d, MIPS_advance_loc8, SELECT_MIPS64)
895919
HANDLE_DW_CFA_PRED(0x2d, GNU_window_save, SELECT_SPARC)
896920
HANDLE_DW_CFA_PRED(0x2d, AARCH64_negate_ra_state, SELECT_AARCH64)
897921
HANDLE_DW_CFA_PRED(0x2e, GNU_args_size, SELECT_X86)
922+
// Heterogeneous Debugging Extension defined at
923+
// https://llvm.org/docs/AMDGPUDwarfProposalForHeterogeneousDebugging.html
924+
HANDLE_DW_CFA(0x30, LLVM_def_aspace_cfa)
925+
HANDLE_DW_CFA(0x31, LLVM_def_aspace_cfa_sf)
898926

899927
// Apple Objective-C Property Attributes.
900928
// Keep this list in sync with clang's DeclSpec.h ObjCPropertyAttributeKind!

llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,15 @@ class CFIProgram {
9898
Instructions.back().Ops.push_back(Operand2);
9999
}
100100

101+
/// Add a new instruction that has three operands.
102+
void addInstruction(uint8_t Opcode, uint64_t Operand1, uint64_t Operand2,
103+
uint64_t Operand3) {
104+
Instructions.push_back(Instruction(Opcode));
105+
Instructions.back().Ops.push_back(Operand1);
106+
Instructions.back().Ops.push_back(Operand2);
107+
Instructions.back().Ops.push_back(Operand3);
108+
}
109+
101110
/// Types of operands to CFI instructions
102111
/// In DWARF, this type is implicitly tied to a CFI instruction opcode and
103112
/// thus this type doesn't need to be explictly written to the file (this is
@@ -113,12 +122,13 @@ class CFIProgram {
113122
OT_SignedFactDataOffset,
114123
OT_UnsignedFactDataOffset,
115124
OT_Register,
125+
OT_AddressSpace,
116126
OT_Expression
117127
};
118128

119129
/// Retrieve the array describing the types of operands according to the enum
120130
/// above. This is indexed by opcode.
121-
static ArrayRef<OperandType[2]> getOperandTypes();
131+
static ArrayRef<OperandType[3]> getOperandTypes();
122132

123133
/// Print \p Opcode's operand number \p OperandIdx which has value \p Operand.
124134
void printOperand(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH,

llvm/include/llvm/MC/MCAsmInfo.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,11 @@ class MCAsmInfo {
353353
/// false.
354354
bool SupportsDebugInformation = false;
355355

356+
/// True if target supports emitting .debug_frame unwind information when
357+
/// ExceptionsType = ExceptionHandling::None and debug info is requested.
358+
/// Defaults to false.
359+
bool SupportsDebugUnwindInformation = false;
360+
356361
/// Exception handling format for the target. Defaults to None.
357362
ExceptionHandling ExceptionsType = ExceptionHandling::None;
358363

@@ -379,6 +384,11 @@ class MCAsmInfo {
379384
/// location is allowed.
380385
bool SupportsExtendedDwarfLocDirective = true;
381386

387+
/// True if the target supports the extensions defined at
388+
/// https://llvm.org/docs/AMDGPUDwarfProposalForHeterogeneousDebugging.html.
389+
/// Defaults to false.
390+
bool SupportsHeterogeneousDebuggingExtensions = false;
391+
382392
//===--- Prologue State ----------------------------------------------===//
383393

384394
std::vector<MCCFIInstruction> InitialFrameState;
@@ -609,6 +619,10 @@ class MCAsmInfo {
609619

610620
bool doesSupportDebugInformation() const { return SupportsDebugInformation; }
611621

622+
bool doesSupportDebugUnwindInformation() const {
623+
return SupportsDebugUnwindInformation;
624+
}
625+
612626
bool doesSupportExceptionHandling() const {
613627
return ExceptionsType != ExceptionHandling::None;
614628
}
@@ -643,6 +657,9 @@ class MCAsmInfo {
643657
bool supportsExtendedDwarfLocDirective() const {
644658
return SupportsExtendedDwarfLocDirective;
645659
}
660+
bool supportsHeterogeneousDebuggingExtensions() const {
661+
return SupportsHeterogeneousDebuggingExtensions;
662+
}
646663

647664
void addInitialFrameState(const MCCFIInstruction &Inst);
648665

llvm/include/llvm/MC/MCDwarf.h

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,7 @@ class MCCFIInstruction {
444444
OpRememberState,
445445
OpRestoreState,
446446
OpOffset,
447+
OpLLVMDefAspaceCfa,
447448
OpDefCfaRegister,
448449
OpDefCfaOffset,
449450
OpDefCfa,
@@ -466,19 +467,25 @@ class MCCFIInstruction {
466467
int Offset;
467468
unsigned Register2;
468469
};
470+
unsigned AddressSpace;
469471
std::vector<char> Values;
470472

471473
MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R, int O, StringRef V)
472474
: Operation(Op), Label(L), Register(R), Offset(O),
473475
Values(V.begin(), V.end()) {
474-
assert(Op != OpRegister);
476+
assert(Op != OpRegister && Op != OpLLVMDefAspaceCfa);
475477
}
476478

477479
MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R1, unsigned R2)
478480
: Operation(Op), Label(L), Register(R1), Register2(R2) {
479481
assert(Op == OpRegister);
480482
}
481483

484+
MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R, int O, unsigned AS)
485+
: Operation(Op), Label(L), Register(R), Offset(O), AddressSpace(AS) {
486+
assert(Op == OpLLVMDefAspaceCfa);
487+
}
488+
482489
public:
483490
/// .cfi_def_cfa defines a rule for computing CFA as: take address from
484491
/// Register and add Offset to it.
@@ -507,6 +514,17 @@ class MCCFIInstruction {
507514
return MCCFIInstruction(OpAdjustCfaOffset, L, 0, Adjustment, "");
508515
}
509516

517+
// FIXME: Update the remaining docs to use the new proposal wording.
518+
/// .cfi_llvm_def_aspace_cfa defines the rule for computing the CFA to
519+
/// be the result of evaluating the DWARF operation expression
520+
/// `DW_OP_constu AS; DW_OP_aspace_bregx R, B` as a location description.
521+
static MCCFIInstruction createLLVMDefAspaceCfa(MCSymbol *L, unsigned Register,
522+
int Offset,
523+
unsigned AddressSpace) {
524+
return MCCFIInstruction(OpLLVMDefAspaceCfa, L, Register, -Offset,
525+
AddressSpace);
526+
}
527+
510528
/// .cfi_offset Previous value of Register is saved at offset Offset
511529
/// from CFA.
512530
static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register,
@@ -586,7 +604,8 @@ class MCCFIInstruction {
586604
assert(Operation == OpDefCfa || Operation == OpOffset ||
587605
Operation == OpRestore || Operation == OpUndefined ||
588606
Operation == OpSameValue || Operation == OpDefCfaRegister ||
589-
Operation == OpRelOffset || Operation == OpRegister);
607+
Operation == OpRelOffset || Operation == OpRegister ||
608+
Operation == OpLLVMDefAspaceCfa);
590609
return Register;
591610
}
592611

@@ -595,10 +614,16 @@ class MCCFIInstruction {
595614
return Register2;
596615
}
597616

617+
unsigned getAddressSpace() const {
618+
assert(Operation == OpLLVMDefAspaceCfa);
619+
return AddressSpace;
620+
}
621+
598622
int getOffset() const {
599623
assert(Operation == OpDefCfa || Operation == OpOffset ||
600624
Operation == OpRelOffset || Operation == OpDefCfaOffset ||
601-
Operation == OpAdjustCfaOffset || Operation == OpGnuArgsSize);
625+
Operation == OpAdjustCfaOffset || Operation == OpGnuArgsSize ||
626+
Operation == OpLLVMDefAspaceCfa);
602627
return Offset;
603628
}
604629

llvm/include/llvm/MC/MCStreamer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -942,6 +942,8 @@ class MCStreamer {
942942
virtual void emitCFIDefCfa(int64_t Register, int64_t Offset);
943943
virtual void emitCFIDefCfaOffset(int64_t Offset);
944944
virtual void emitCFIDefCfaRegister(int64_t Register);
945+
virtual void emitCFILLVMDefAspaceCfa(int64_t Register, int64_t Offset,
946+
int64_t AddressSpace);
945947
virtual void emitCFIOffset(int64_t Register, int64_t Offset);
946948
virtual void emitCFIPersonality(const MCSymbol *Sym, unsigned Encoding);
947949
virtual void emitCFILsda(const MCSymbol *Sym, unsigned Encoding);

llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "CodeViewDebug.h"
1515
#include "DwarfDebug.h"
1616
#include "DwarfException.h"
17+
#include "UnwindStreamer.h"
1718
#include "WasmException.h"
1819
#include "WinCFGuard.h"
1920
#include "WinException.h"
@@ -139,6 +140,8 @@ static const char *const DWARFGroupName = "dwarf";
139140
static const char *const DWARFGroupDescription = "DWARF Emission";
140141
static const char *const DbgTimerName = "emit";
141142
static const char *const DbgTimerDescription = "Debug Info Emission";
143+
static const char *const UnwindTimerName = "write_unwind";
144+
static const char *const UnwindTimerDescription = "DWARF Unwind Writer";
142145
static const char *const EHTimerName = "write_exception";
143146
static const char *const EHTimerDescription = "DWARF Exception Writer";
144147
static const char *const CFGuardName = "Control Flow Guard";
@@ -328,6 +331,16 @@ bool AsmPrinter::doInitialization(Module &M) {
328331
}
329332
}
330333

334+
if (MMI->hasDebugInfo() &&
335+
MAI->getExceptionHandlingType() == ExceptionHandling::None &&
336+
MAI->doesSupportDebugUnwindInformation()) {
337+
isCFIMoveForDebugging = true;
338+
Handlers.emplace_back(std::make_unique<UnwindStreamer>(this),
339+
UnwindTimerName, UnwindTimerDescription,
340+
DWARFGroupName, DWARFGroupDescription);
341+
return false;
342+
}
343+
331344
switch (MAI->getExceptionHandlingType()) {
332345
case ExceptionHandling::SjLj:
333346
case ExceptionHandling::DwarfCFI:
@@ -995,7 +1008,8 @@ bool AsmPrinter::needsSEHMoves() {
9951008

9961009
void AsmPrinter::emitCFIInstruction(const MachineInstr &MI) {
9971010
ExceptionHandling ExceptionHandlingType = MAI->getExceptionHandlingType();
998-
if (ExceptionHandlingType != ExceptionHandling::DwarfCFI &&
1011+
if (!MAI->doesSupportDebugUnwindInformation() &&
1012+
ExceptionHandlingType != ExceptionHandling::DwarfCFI &&
9991013
ExceptionHandlingType != ExceptionHandling::ARM)
10001014
return;
10011015

llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,10 @@ void AsmPrinter::emitCFIInstruction(const MCCFIInstruction &Inst) const {
221221
case MCCFIInstruction::OpDefCfaRegister:
222222
OutStreamer->emitCFIDefCfaRegister(Inst.getRegister());
223223
break;
224+
case MCCFIInstruction::OpLLVMDefAspaceCfa:
225+
OutStreamer->emitCFILLVMDefAspaceCfa(Inst.getRegister(), Inst.getOffset(),
226+
Inst.getAddressSpace());
227+
break;
224228
case MCCFIInstruction::OpOffset:
225229
OutStreamer->emitCFIOffset(Inst.getRegister(), Inst.getOffset());
226230
break;

0 commit comments

Comments
 (0)