Skip to content

Commit 473898f

Browse files
committed
Extract immediately-upstreamable changes from amd-staging
This is largely CFI only, but also includes definitions in BinaryFormat/Dwarf.def that we should try to pin down ASAP. An encoding change is required for some of the DW_AT_* extensions, which I've limited to just: DW_AT_LLVM_lanes DW_AT_LLVM_lane_pc DW_AT_LLVM_vector_size As these are not currently emitted by the compiler I don't think this constitutes a breaking change, so we should be able to flow this back to amd-staging without issue.
1 parent 56cd70b commit 473898f

File tree

172 files changed

+40039
-6450
lines changed

Some content is hidden

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

172 files changed

+40039
-6450
lines changed

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4920,6 +4920,10 @@ renderDebugOptions(const ToolChain &TC, const Driver &D, const llvm::Triple &T,
49204920
renderDwarfFormat(D, T, Args, CmdArgs, EffectiveDWARFVersion);
49214921
RenderDebugInfoCompressionArgs(Args, CmdArgs, D, TC);
49224922

4923+
bool EmitDwarfForAMDGCN = EmitDwarf && T.isAMDGCN();
4924+
if (EmitDwarfForAMDGCN)
4925+
CmdArgs.append({"-mllvm", "-amdgpu-spill-cfi-saved-regs"});
4926+
49234927
// This controls whether or not we perform JustMyCode instrumentation.
49244928
if (Args.hasFlag(options::OPT_fjmc, options::OPT_fno_jmc, false)) {
49254929
if (TC.getTriple().isOSBinFormatELF() ||

llvm/include/llvm/BinaryFormat/Dwarf.def

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@
2525
defined HANDLE_DW_APPLE_PROPERTY || defined HANDLE_DW_UT || \
2626
defined HANDLE_DWARF_SECTION || defined HANDLE_DW_IDX || \
2727
defined HANDLE_DW_END || defined HANDLE_DW_SECT || \
28-
defined HANDLE_DW_APPLE_ENUM_KIND)
28+
defined HANDLE_DW_APPLE_ENUM_KIND || \
29+
defined HANDLE_DW_MSPACE || \
30+
( defined HANDLE_DW_ASPACE && defined HANDLE_DW_ASPACE_PRED) )
2931
#error "Missing macro definition of HANDLE_DW*"
3032
#endif
3133

@@ -151,6 +153,18 @@
151153
#define HANDLE_DW_APPLE_ENUM_KIND(ID, NAME)
152154
#endif
153155

156+
#ifndef HANDLE_DW_MSPACE
157+
#define HANDLE_DW_MSPACE(ID, NAME)
158+
#endif
159+
160+
#ifndef HANDLE_DW_ASPACE
161+
#define HANDLE_DW_ASPACE(ID, NAME)
162+
#endif
163+
164+
#ifndef HANDLE_DW_ASPACE_PRED
165+
#define HANDLE_DW_ASPACE_PRED(ID, NAME, PRED)
166+
#endif
167+
154168
HANDLE_DW_TAG(0x0000, null, 2, DWARF, DW_KIND_NONE)
155169
HANDLE_DW_TAG(0x0001, array_type, 2, DWARF, DW_KIND_TYPE)
156170
HANDLE_DW_TAG(0x0002, class_type, 2, DWARF, DW_KIND_TYPE)
@@ -624,6 +638,28 @@ HANDLE_DW_AT(0x3e09, LLVM_ptrauth_authenticates_null_values, 0, LLVM)
624638
HANDLE_DW_AT(0x3e0a, LLVM_ptrauth_authentication_mode, 0, LLVM)
625639
HANDLE_DW_AT(0x3e0b, LLVM_num_extra_inhabitants, 0, LLVM)
626640
HANDLE_DW_AT(0x3e0c, LLVM_stmt_sequence, 0, LLVM)
641+
// Heterogeneous Debugging Extension defined at
642+
// https://llvm.org/docs/AMDGPUDwarfProposalForHeterogeneousDebugging.html.
643+
HANDLE_DW_AT(0x3e0d, LLVM_memory_space, 0, LLVM)
644+
HANDLE_DW_AT(0x3e0e, LLVM_address_space, 0, LLVM)
645+
HANDLE_DW_AT(0x3e0f, LLVM_lanes, 0, LLVM)
646+
HANDLE_DW_AT(0x3e10, LLVM_lane_pc, 0, LLVM)
647+
HANDLE_DW_AT(0x3e11, LLVM_vector_size, 0, LLVM)
648+
649+
// https://www.llvm.org/docs/AMDGPUDwarfExtensionsForHeterogeneousDebugging.html#a-7-15-memory-space-encodings
650+
HANDLE_DW_MSPACE(0x0, none)
651+
HANDLE_DW_MSPACE(0x1, global)
652+
HANDLE_DW_MSPACE(0x2, constant)
653+
HANDLE_DW_MSPACE(0x3, group)
654+
HANDLE_DW_MSPACE(0x4, private)
655+
656+
// https://llvm.org/docs/AMDGPUUsage.html#address-space-identifier
657+
HANDLE_DW_ASPACE(0x0, none)
658+
HANDLE_DW_ASPACE_PRED(0x1, AMDGPU_generic, SELECT_AMDGPU)
659+
HANDLE_DW_ASPACE_PRED(0x2, AMDGPU_region, SELECT_AMDGPU)
660+
HANDLE_DW_ASPACE_PRED(0x3, AMDGPU_local, SELECT_AMDGPU)
661+
HANDLE_DW_ASPACE_PRED(0x5, AMDGPU_private_lane, SELECT_AMDGPU)
662+
HANDLE_DW_ASPACE_PRED(0x6, AMDGPU_private_wave, SELECT_AMDGPU)
627663

628664
// Apple extensions.
629665

@@ -911,6 +947,19 @@ HANDLE_DW_OP(0xe9, LLVM_user, -1, -1, 0, LLVM)
911947
// location stack or any of its values. It is defined as a placeholder for
912948
// testing purposes.
913949
HANDLE_DW_OP_LLVM_USEROP(0x0001, nop)
950+
// Heterogeneous Debugging Extension defined at
951+
// https://llvm.org/docs/AMDGPUDwarfProposalForHeterogeneousDebugging.html.
952+
HANDLE_DW_OP_LLVM_USEROP(0x0002, form_aspace_address)
953+
HANDLE_DW_OP_LLVM_USEROP(0x0003, push_lane)
954+
HANDLE_DW_OP_LLVM_USEROP(0x0004, offset)
955+
HANDLE_DW_OP_LLVM_USEROP(0x0005, offset_uconst)
956+
HANDLE_DW_OP_LLVM_USEROP(0x0006, bit_offset)
957+
HANDLE_DW_OP_LLVM_USEROP(0x0007, call_frame_entry_reg)
958+
HANDLE_DW_OP_LLVM_USEROP(0x0008, undefined)
959+
HANDLE_DW_OP_LLVM_USEROP(0x0009, aspace_bregx)
960+
HANDLE_DW_OP_LLVM_USEROP(0x000a, piece_end)
961+
HANDLE_DW_OP_LLVM_USEROP(0x000b, extend)
962+
HANDLE_DW_OP_LLVM_USEROP(0x000c, select_bit_piece)
914963

915964
// DWARF languages.
916965
HANDLE_DW_LANG(0x0001, C89, 0, 2, DWARF)
@@ -1380,3 +1429,6 @@ HANDLE_DW_SECT(8, RNGLISTS)
13801429
#undef HANDLE_DW_END
13811430
#undef HANDLE_DW_SECT
13821431
#undef HANDLE_DW_APPLE_ENUM_KIND
1432+
#undef HANDLE_DW_MSPACE
1433+
#undef HANDLE_DW_ASPACE
1434+
#undef HANDLE_DW_ASPACE_PRED

llvm/include/llvm/BinaryFormat/Dwarf.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -757,6 +757,19 @@ enum CallingConvention {
757757
DW_CC_hi_user = 0xff
758758
};
759759

760+
enum MemorySpace {
761+
#define HANDLE_DW_MSPACE(ID, NAME) DW_MSPACE_LLVM_##NAME = ID,
762+
#include "llvm/BinaryFormat/Dwarf.def"
763+
DW_MSPACE_LLVM_lo_user = 0x8000,
764+
DW_MSPACE_LLVM_hi_user = 0xffff
765+
};
766+
767+
enum AddressSpace {
768+
#define HANDLE_DW_ASPACE(ID, NAME) DW_ASPACE_LLVM_##NAME = ID,
769+
#define HANDLE_DW_ASPACE_PRED(ID, NAME, PRED) DW_ASPACE_LLVM_##NAME = ID,
770+
#include "llvm/BinaryFormat/Dwarf.def"
771+
};
772+
760773
enum InlineAttribute {
761774
// Inline codes
762775
DW_INL_not_inlined = 0x00,
@@ -1011,6 +1024,8 @@ StringRef IndexString(unsigned Idx);
10111024
StringRef FormatString(DwarfFormat Format);
10121025
StringRef FormatString(bool IsDWARF64);
10131026
StringRef RLEString(unsigned RLE);
1027+
StringRef MemorySpaceString(unsigned MS);
1028+
StringRef AddressSpaceString(unsigned AS, llvm::Triple TT);
10141029
/// @}
10151030

10161031
/// \defgroup DwarfConstantsParsing Dwarf constants parsing functions
@@ -1031,6 +1046,7 @@ unsigned getVirtuality(StringRef VirtualityString);
10311046
unsigned getEnumKind(StringRef EnumKindString);
10321047
unsigned getLanguage(StringRef LanguageString);
10331048
unsigned getCallingConvention(StringRef LanguageString);
1049+
unsigned getMemorySpace(StringRef LanguageString);
10341050
unsigned getAttributeEncoding(StringRef EncodingString);
10351051
unsigned getMacinfo(StringRef MacinfoString);
10361052
unsigned getMacro(StringRef MacroString);

llvm/include/llvm/CodeGen/MachineFunction.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1186,6 +1186,10 @@ class LLVM_ABI MachineFunction {
11861186

11871187
[[nodiscard]] unsigned addFrameInst(const MCCFIInstruction &Inst);
11881188

1189+
/// Replace all references to register \param From with register \param To in
1190+
/// frame instructions. Note that .cfi_escape instructions will be left as-is.
1191+
void replaceFrameInstRegister(Register From, Register To);
1192+
11891193
/// Returns a reference to a list of symbols immediately following calls to
11901194
/// _setjmp in the function. Used to construct the longjmp target table used
11911195
/// by Windows Control Flow Guard.

llvm/include/llvm/MC/MCAsmInfo.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,11 @@ class MCAsmInfo {
389389
/// location is allowed.
390390
bool SupportsExtendedDwarfLocDirective = true;
391391

392+
/// True if the target supports the extensions defined at
393+
/// https://llvm.org/docs/AMDGPUDwarfProposalForHeterogeneousDebugging.html.
394+
/// Defaults to false.
395+
bool SupportsHeterogeneousDebuggingExtensions = false;
396+
392397
//===--- Prologue State ----------------------------------------------===//
393398

394399
std::vector<MCCFIInstruction> InitialFrameState;
@@ -618,6 +623,10 @@ class MCAsmInfo {
618623

619624
bool doesSupportDebugInformation() const { return SupportsDebugInformation; }
620625

626+
bool doesSupportExceptionHandling() const {
627+
return ExceptionsType != ExceptionHandling::None;
628+
}
629+
621630
ExceptionHandling getExceptionHandlingType() const { return ExceptionsType; }
622631
WinEH::EncodingType getWinEHEncodingType() const { return WinEHEncodingType; }
623632

@@ -656,6 +665,9 @@ class MCAsmInfo {
656665
bool supportsExtendedDwarfLocDirective() const {
657666
return SupportsExtendedDwarfLocDirective;
658667
}
668+
bool supportsHeterogeneousDebuggingExtensions() const {
669+
return SupportsHeterogeneousDebuggingExtensions;
670+
}
659671

660672
bool usesDwarfFileAndLocDirectives() const { return !IsAIX; }
661673

llvm/include/llvm/MC/MCDwarf.h

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,42 @@ class MCCFIInstruction {
519519
OpGnuArgsSize,
520520
OpLabel,
521521
OpValOffset,
522+
OpLLVMRegisterPair,
523+
OpLLVMVectorRegisters,
524+
OpLLVMVectorOffset,
525+
OpLLVMVectorRegisterMask,
526+
};
527+
528+
/// Some extra fields used when Operation is OpLLVMRegisterPair.
529+
struct RegisterPairExtraFields {
530+
unsigned Reg1, Reg2;
531+
unsigned Reg1SizeInBits, Reg2SizeInBits;
532+
};
533+
534+
struct VectorRegisterWithLane {
535+
unsigned Register;
536+
unsigned Lane;
537+
unsigned SizeInBits;
538+
};
539+
540+
/// Some extra fields used when Operation is OpLLVMVectorRegisters.
541+
struct VectorRegistersExtraFields {
542+
std::vector<VectorRegisterWithLane> VectorRegisters;
543+
};
544+
545+
/// Some extra fields used when Operation is OpLLVMVectorOffset.
546+
struct VectorOffsetExtraFields {
547+
unsigned MaskRegister;
548+
unsigned MaskRegisterSizeInBits;
549+
unsigned RegisterSizeInBits;
550+
};
551+
552+
/// Some extra fields used when Operation is OpLLVMVectorRegisterMask.
553+
struct VectorRegisterMaskExtraFields {
554+
unsigned SpillRegister;
555+
unsigned SpillRegisterLaneSizeInBits;
556+
unsigned MaskRegister;
557+
unsigned MaskRegisterSizeInBits;
522558
};
523559

524560
private:
@@ -544,6 +580,14 @@ class MCCFIInstruction {
544580
std::vector<char> Values;
545581
std::string Comment;
546582

583+
// FIXME: We could probably save some space and complexity by moving all
584+
// Operation-specific fields to this variant. Leaving them as-is for now to
585+
// avoid a diff with upstream.
586+
std::variant<std::monostate, RegisterPairExtraFields,
587+
VectorRegistersExtraFields, VectorOffsetExtraFields,
588+
VectorRegisterMaskExtraFields>
589+
ExtraFields;
590+
547591
MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R, int64_t O, SMLoc Loc,
548592
StringRef V = "", StringRef Comment = "")
549593
: Label(L), Operation(Op), Loc(Loc), Values(V.begin(), V.end()),
@@ -563,6 +607,14 @@ class MCCFIInstruction {
563607
U.RIA = {R, O, AS};
564608
}
565609

610+
template <class ExtraFieldsTy>
611+
MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R, int O,
612+
ExtraFieldsTy &&ExtraFields, SMLoc Loc)
613+
: Label(L), Operation(Op), Loc(Loc),
614+
ExtraFields(std::forward<ExtraFieldsTy>(ExtraFields)) {
615+
U.RI = {R, O};
616+
}
617+
566618
MCCFIInstruction(OpType Op, MCSymbol *L, MCSymbol *CfiLabel, SMLoc Loc)
567619
: Label(L), Operation(Op), Loc(Loc) {
568620
assert(Op == OpLabel);
@@ -700,6 +752,62 @@ class MCCFIInstruction {
700752
return MCCFIInstruction(OpLabel, L, CfiLabel, Loc);
701753
}
702754

755+
/// .cfi_llvm_register_pair Previous value of Register is saved in R1:R2.
756+
static MCCFIInstruction
757+
createLLVMRegisterPair(MCSymbol *L, unsigned Register, unsigned R1,
758+
unsigned R1SizeInBits, unsigned R2,
759+
unsigned R2SizeInBits, SMLoc Loc = {}) {
760+
RegisterPairExtraFields Extra{R1, R2, R1SizeInBits, R2SizeInBits};
761+
return MCCFIInstruction(OpLLVMRegisterPair, L, Register, 0, Extra, Loc);
762+
}
763+
764+
/// .cfi_llvm_vector_registers Previous value of Register is saved in lanes of
765+
/// vector registers.
766+
static MCCFIInstruction
767+
createLLVMVectorRegisters(MCSymbol *L, unsigned Register,
768+
std::vector<VectorRegisterWithLane> VectorRegisters,
769+
SMLoc Loc = {}) {
770+
VectorRegistersExtraFields Extra{std::move(VectorRegisters)};
771+
return MCCFIInstruction(OpLLVMVectorRegisters, L, Register, 0,
772+
std::move(Extra), Loc);
773+
}
774+
775+
/// .cfi_llvm_vector_offset Previous value of Register is saved at Offset from
776+
/// CFA. MaskRegister specifies the active lanes of register.
777+
static MCCFIInstruction
778+
createLLVMVectorOffset(MCSymbol *L, unsigned Register,
779+
unsigned RegisterSizeInBits, unsigned MaskRegister,
780+
unsigned MaskRegisterSizeInBits, int Offset,
781+
SMLoc Loc = {}) {
782+
VectorOffsetExtraFields Extra{MaskRegister, MaskRegisterSizeInBits,
783+
RegisterSizeInBits};
784+
return MCCFIInstruction(OpLLVMVectorOffset, L, Register, Offset, Extra,
785+
Loc);
786+
}
787+
788+
/// .cfi_llvm_vector_register_mask Previous value of Register is saved in
789+
/// SpillRegister, predicated on the value of MaskRegister.
790+
static MCCFIInstruction createLLVMVectorRegisterMask(
791+
MCSymbol *L, unsigned Register, unsigned SpillRegister,
792+
unsigned SpillRegisterLaneSizeInBits, unsigned MaskRegister,
793+
unsigned MaskRegisterSizeInBits, SMLoc Loc = {}) {
794+
VectorRegisterMaskExtraFields Extra{
795+
SpillRegister,
796+
SpillRegisterLaneSizeInBits,
797+
MaskRegister,
798+
MaskRegisterSizeInBits,
799+
};
800+
return MCCFIInstruction(OpLLVMVectorRegisterMask, L, Register, 0,
801+
std::move(Extra), Loc);
802+
}
803+
804+
template <class ExtraFieldsTy> ExtraFieldsTy &getExtraFields() {
805+
return std::get<ExtraFieldsTy>(ExtraFields);
806+
}
807+
808+
template <class ExtraFieldsTy> const ExtraFieldsTy &getExtraFields() const {
809+
return std::get<ExtraFieldsTy>(ExtraFields);
810+
}
703811
/// .cfi_val_offset Previous value of Register is offset Offset from the
704812
/// current CFA register.
705813
static MCCFIInstruction createValOffset(MCSymbol *L, unsigned Register,
@@ -718,6 +826,9 @@ class MCCFIInstruction {
718826
assert(Operation == OpDefCfa || Operation == OpOffset ||
719827
Operation == OpRestore || Operation == OpUndefined ||
720828
Operation == OpSameValue || Operation == OpDefCfaRegister ||
829+
Operation == OpLLVMVectorRegisters ||
830+
Operation == OpLLVMRegisterPair || Operation == OpLLVMVectorOffset ||
831+
Operation == OpLLVMVectorRegisterMask ||
721832
Operation == OpRelOffset || Operation == OpValOffset);
722833
return U.RI.Register;
723834
}
@@ -738,6 +849,7 @@ class MCCFIInstruction {
738849
assert(Operation == OpDefCfa || Operation == OpOffset ||
739850
Operation == OpRelOffset || Operation == OpDefCfaOffset ||
740851
Operation == OpAdjustCfaOffset || Operation == OpGnuArgsSize ||
852+
Operation == OpLLVMVectorOffset ||
741853
Operation == OpValOffset);
742854
return U.RI.Offset;
743855
}
@@ -754,6 +866,9 @@ class MCCFIInstruction {
754866

755867
StringRef getComment() const { return Comment; }
756868
SMLoc getLoc() const { return Loc; }
869+
870+
/// Replaces in place all references to FromReg with ToReg.
871+
void replaceRegister(unsigned FromReg, unsigned ToReg);
757872
};
758873

759874
struct MCDwarfFrameInfo {

llvm/include/llvm/MC/MCStreamer.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1000,6 +1000,24 @@ class MCStreamer {
10001000
SMLoc Loc = {});
10011001
virtual void emitCFIWindowSave(SMLoc Loc = {});
10021002
virtual void emitCFINegateRAState(SMLoc Loc = {});
1003+
virtual void emitCFILLVMRegisterPair(int64_t Register, int64_t R1,
1004+
int64_t R1SizeInBits, int64_t R2,
1005+
int64_t R2SizeInBits, SMLoc Loc = {});
1006+
virtual void emitCFILLVMVectorRegisters(
1007+
int64_t Register,
1008+
std::vector<MCCFIInstruction::VectorRegisterWithLane> VRs,
1009+
SMLoc Loc = {});
1010+
virtual void emitCFILLVMVectorOffset(int64_t Register,
1011+
int64_t RegisterSizeInBits,
1012+
int64_t MaskRegister,
1013+
int64_t MaskRegisterSizeInBits,
1014+
int64_t Offset, SMLoc Loc = {});
1015+
virtual void
1016+
emitCFILLVMVectorRegisterMask(int64_t Register, int64_t SpillRegister,
1017+
int64_t SpillRegisterLaneSizeInBits,
1018+
int64_t MaskRegister,
1019+
int64_t MaskRegisterSizeInBits, SMLoc Loc = {});
1020+
10031021
virtual void emitCFINegateRAStateWithPC(SMLoc Loc = {});
10041022
virtual void emitCFILabelDirective(SMLoc Loc, StringRef Name);
10051023
virtual void emitCFIValOffset(int64_t Register, int64_t Offset,

0 commit comments

Comments
 (0)