Index: llvm/lib/Target/AMDGPU/AMDGPUSubtarget.h =================================================================== --- llvm/lib/Target/AMDGPU/AMDGPUSubtarget.h +++ llvm/lib/Target/AMDGPU/AMDGPUSubtarget.h @@ -16,6 +16,7 @@ #include "AMDGPU.h" #include "AMDGPUCallLowering.h" +#include "MCTargetDesc/AMDGPUMCTargetDesc.h" #include "R600FrameLowering.h" #include "R600ISelLowering.h" #include "R600InstrInfo.h" @@ -246,6 +247,13 @@ uint64_t getExplicitKernArgSize(const Function &F, Align &MaxAlign) const; unsigned getKernArgSegmentSize(const Function &F, Align &MaxAlign) const; + /// \returns Corresponsing DWARF register number mapping flavour for the + /// \p WavefrontSize. + AMDGPUDwarfFlavour getAMDGPUDwarfFlavour() const { + return WavefrontSize == 32 ? AMDGPUDwarfFlavour::Wave32 + : AMDGPUDwarfFlavour::Wave64; + } + virtual ~AMDGPUSubtarget() {} }; Index: llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp =================================================================== --- llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp +++ llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp @@ -23,6 +23,7 @@ #include "AMDGPUTargetTransformInfo.h" #include "GCNIterativeScheduler.h" #include "GCNSchedStrategy.h" +#include "MCTargetDesc/AMDGPUMCTargetDesc.h" #include "R600MachineScheduler.h" #include "SIMachineFunctionInfo.h" #include "SIMachineScheduler.h" @@ -375,6 +376,12 @@ getEffectiveCodeModel(CM, CodeModel::Small), OptLevel), TLOF(createTLOF(getTargetTriple())) { initAsmInfo(); + if (TT.getArch() == Triple::amdgcn) { + if (getMCSubtargetInfo()->checkFeatures("+wavefrontsize64")) + MRI.reset(llvm::createGCNMCRegisterInfo(AMDGPUDwarfFlavour::Wave64)); + else if (getMCSubtargetInfo()->checkFeatures("+wavefrontsize32")) + MRI.reset(llvm::createGCNMCRegisterInfo(AMDGPUDwarfFlavour::Wave32)); + } } bool AMDGPUTargetMachine::EnableLateStructurizeCFG = false; Index: llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.h =================================================================== --- llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.h +++ llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.h @@ -33,6 +33,10 @@ class Triple; class raw_pwrite_stream; +enum AMDGPUDwarfFlavour { Wave64 = 0, Wave32 = 1 }; + +MCRegisterInfo *createGCNMCRegisterInfo(AMDGPUDwarfFlavour DwarfFlavour); + MCCodeEmitter *createR600MCCodeEmitter(const MCInstrInfo &MCII, const MCRegisterInfo &MRI, MCContext &Ctx); Index: llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.cpp =================================================================== --- llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.cpp +++ llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.cpp @@ -65,6 +65,12 @@ return X; } +MCRegisterInfo *llvm::createGCNMCRegisterInfo(AMDGPUDwarfFlavour DwarfFlavour) { + MCRegisterInfo *X = new MCRegisterInfo(); + InitAMDGPUMCRegisterInfo(X, AMDGPU::PC_REG, DwarfFlavour); + return X; +} + static MCSubtargetInfo * createAMDGPUMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) { if (TT.getArch() == Triple::r600) Index: llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp =================================================================== --- llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp +++ llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp @@ -38,12 +38,9 @@ cl::ReallyHidden, cl::init(true)); -SIRegisterInfo::SIRegisterInfo(const GCNSubtarget &ST) : - AMDGPUGenRegisterInfo(0), - ST(ST), - SpillSGPRToVGPR(EnableSpillSGPRToVGPR), - isWave32(ST.isWave32()) { -} +SIRegisterInfo::SIRegisterInfo(const GCNSubtarget &ST) + : AMDGPUGenRegisterInfo(AMDGPU::PC_REG, ST.getAMDGPUDwarfFlavour()), ST(ST), + SpillSGPRToVGPR(EnableSpillSGPRToVGPR), isWave32(ST.isWave32()) {} void SIRegisterInfo::reserveRegisterTuples(BitVector &Reserved, unsigned Reg) const { Index: llvm/lib/Target/AMDGPU/SIRegisterInfo.td =================================================================== --- llvm/lib/Target/AMDGPU/SIRegisterInfo.td +++ llvm/lib/Target/AMDGPU/SIRegisterInfo.td @@ -104,7 +104,7 @@ def SCRATCH_WAVE_OFFSET_REG : SIReg<"scratch_wave_offset", 0>; // Pseudo-register to represent the program-counter DWARF register. -def PC_REG : SIReg<"pc", 0>, DwarfRegNum<[16]> { +def PC_REG : SIReg<"pc", 0>, DwarfRegNum<[16, 0]> { // There is no physical register corresponding to a "program counter", but // we need to encode the concept in debug information in order to represent // things like the return value in unwind information. @@ -118,10 +118,10 @@ let HWEncoding = 106; } -def EXEC_LO : SIReg<"exec_lo", 126>, DwarfRegNum<[1]>; +def EXEC_LO : SIReg<"exec_lo", 126>, DwarfRegNum<[1, 1]>; def EXEC_HI : SIReg<"exec_hi", 127>; -def EXEC : RegisterWithSubRegs<"exec", [EXEC_LO, EXEC_HI]>, DwarfRegNum<[17]> { +def EXEC : RegisterWithSubRegs<"exec", [EXEC_LO, EXEC_HI]>, DwarfRegNum<[17, 1]> { let Namespace = "AMDGPU"; let SubRegIndices = [sub0, sub1]; let HWEncoding = 126; @@ -212,14 +212,15 @@ foreach Index = 0-105 in { def SGPR#Index : SIReg <"s"#Index, Index>, - DwarfRegNum<[!if(!le(Index, 63), !add(Index, 32), !add(Index, 1024))]>; + DwarfRegNum<[!if(!le(Index, 63), !add(Index, 32), !add(Index, 1024)), + !if(!le(Index, 63), !add(Index, 32), !add(Index, 1024))]>; } // VGPR registers foreach Index = 0-255 in { def VGPR#Index : SIReg <"v"#Index, Index>, - DwarfRegNum<[!add(Index, 2560)]> { + DwarfRegNum<[!add(Index, 2560), !add(Index, 1536)]> { let HWEncoding{8} = 1; } } @@ -228,7 +229,7 @@ foreach Index = 0-255 in { def AGPR#Index : SIReg <"a"#Index, Index>, - DwarfRegNum<[!add(Index, 3072)]> { + DwarfRegNum<[!add(Index, 3072), !add(Index, 2048)]> { let HWEncoding{8} = 1; } } Index: llvm/unittests/MC/AMDGPU/CMakeLists.txt =================================================================== --- /dev/null +++ llvm/unittests/MC/AMDGPU/CMakeLists.txt @@ -0,0 +1,9 @@ +set(LLVM_LINK_COMPONENTS + ${LLVM_TARGETS_TO_BUILD} + MC + Support + ) + +add_llvm_unittest(AMDGPUDwarfTests + DwarfRegMappings.cpp + ) Index: llvm/unittests/MC/AMDGPU/DwarfRegMappings.cpp =================================================================== --- /dev/null +++ llvm/unittests/MC/AMDGPU/DwarfRegMappings.cpp @@ -0,0 +1,138 @@ +//===- llvm/unittest/MC/DwarfLineTables.cpp ------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm/MC/MCRegisterInfo.h" +#include "llvm/MC/MCTargetOptions.h" +#include "llvm/Support/TargetRegistry.h" +#include "llvm/Support/TargetSelect.h" +#include "llvm/Target/TargetMachine.h" +#include "gtest/gtest.h" +#include + +using namespace llvm; + +std::once_flag flag; + +void InitializeTargets() { + std::call_once(flag, []() { + InitializeAllTargets(); + InitializeAllTargetMCs(); + }); +} + +TEST(AMDGPUDwarfRegMappingTests, TestWave64DwarfRegMapping) { + InitializeTargets(); + + std::string Error; + const Target *T = TargetRegistry::lookupTarget("amdgcn-amd", Error); + ASSERT_TRUE(T); + + TargetOptions Options; + auto TM = static_cast(T->createTargetMachine( + "amdgcn", "gfx1010", "+wavefrontsize64", Options, None, None)); + ASSERT_TRUE(TM); + + auto MRI = TM->getMCRegisterInfo(); + ASSERT_TRUE(MRI); + + // PC_64 => 16 + MCRegister PCReg(*MRI->getLLVMRegNum(16, false)); + EXPECT_EQ(16, MRI->getDwarfRegNum(PCReg, false)); + + // EXEC_MASK_64 => 17 + MCRegister EXECReg(*MRI->getLLVMRegNum(17, false)); + EXPECT_EQ(17, MRI->getDwarfRegNum(EXECReg, false)); + + // S0 => 32 + MCRegister S0Reg(*MRI->getLLVMRegNum(32, false)); + EXPECT_EQ(32, MRI->getDwarfRegNum(S0Reg, false)); + + // S63 => 95 + MCRegister S63Reg(*MRI->getLLVMRegNum(95, false)); + EXPECT_EQ(95, MRI->getDwarfRegNum(S63Reg, false)); + + // S64 => 1088 + MCRegister S64Reg(*MRI->getLLVMRegNum(1088, false)); + EXPECT_EQ(1088, MRI->getDwarfRegNum(S64Reg, false)); + + // S105 => 1129 + MCRegister S105Reg(*MRI->getLLVMRegNum(1129, false)); + EXPECT_EQ(1129, MRI->getDwarfRegNum(S105Reg, false)); + + // V0 => 2560 + MCRegister V0Reg(*MRI->getLLVMRegNum(2560, false)); + EXPECT_EQ(2560, MRI->getDwarfRegNum(V0Reg, false)); + + // V255 => 2815 + MCRegister V255Reg(*MRI->getLLVMRegNum(2815, false)); + EXPECT_EQ(2815, MRI->getDwarfRegNum(V255Reg, false)); + + // A0 => 3072 + MCRegister A0Reg(*MRI->getLLVMRegNum(3072, false)); + EXPECT_EQ(3072, MRI->getDwarfRegNum(A0Reg, false)); + + // A255 => 3327 + MCRegister A255Reg(*MRI->getLLVMRegNum(3327, false)); + EXPECT_EQ(3327, MRI->getDwarfRegNum(A255Reg, false)); +} + +TEST(AMDGPUDwarfRegMappingTests, TestWave32DwarfRegMapping) { + InitializeTargets(); + + std::string Error; + const Target *T = TargetRegistry::lookupTarget("amdgcn-amd", Error); + ASSERT_TRUE(T); + + TargetOptions Options; + auto TM = static_cast(T->createTargetMachine( + "amdgcn", "gfx1010", "+wavefrontsize32", Options, None, None)); + ASSERT_TRUE(TM); + + auto MRI = TM->getMCRegisterInfo(); + ASSERT_TRUE(MRI); + + // PC_32 => 0 + MCRegister PCReg(*MRI->getLLVMRegNum(0, false)); + EXPECT_EQ(0, MRI->getDwarfRegNum(PCReg, false)); + + // EXEC_MASK_32 => 1 + MCRegister EXECReg(*MRI->getLLVMRegNum(1, false)); + EXPECT_EQ(1, MRI->getDwarfRegNum(EXECReg, false)); + + // S0 => 32 + MCRegister S0Reg(*MRI->getLLVMRegNum(32, false)); + EXPECT_EQ(32, MRI->getDwarfRegNum(S0Reg, false)); + + // S63 => 95 + MCRegister S63Reg(*MRI->getLLVMRegNum(95, false)); + EXPECT_EQ(95, MRI->getDwarfRegNum(S63Reg, false)); + + // S64 => 1088 + MCRegister S64Reg(*MRI->getLLVMRegNum(1088, false)); + EXPECT_EQ(1088, MRI->getDwarfRegNum(S64Reg, false)); + + // S105 => 1129 + MCRegister S105Reg(*MRI->getLLVMRegNum(1129, false)); + EXPECT_EQ(1129, MRI->getDwarfRegNum(S105Reg, false)); + + // V0 => 1536 + MCRegister V0Reg(*MRI->getLLVMRegNum(1536, false)); + EXPECT_EQ(1536, MRI->getDwarfRegNum(V0Reg, false)); + + // V255 => 1791 + MCRegister V255Reg(*MRI->getLLVMRegNum(1791, false)); + EXPECT_EQ(1791, MRI->getDwarfRegNum(V255Reg, false)); + + // A0 => 2048 + MCRegister A0Reg(*MRI->getLLVMRegNum(2048, false)); + EXPECT_EQ(2048, MRI->getDwarfRegNum(A0Reg, false)); + + // A255 => 2303 + MCRegister A255Reg(*MRI->getLLVMRegNum(2303, false)); + EXPECT_EQ(2303, MRI->getDwarfRegNum(A255Reg, false)); +} Index: llvm/unittests/MC/CMakeLists.txt =================================================================== --- llvm/unittests/MC/CMakeLists.txt +++ llvm/unittests/MC/CMakeLists.txt @@ -12,3 +12,5 @@ StringTableBuilderTest.cpp TargetRegistry.cpp ) + +add_subdirectory(AMDGPU) Index: llvm/unittests/Target/AMDGPU/CMakeLists.txt =================================================================== --- /dev/null +++ llvm/unittests/Target/AMDGPU/CMakeLists.txt @@ -0,0 +1,14 @@ +include_directories( + ${CMAKE_SOURCE_DIR}/lib/Target/AMDGPU + ${CMAKE_BINARY_DIR}/lib/Target/AMDGPU + ) + +set(LLVM_LINK_COMPONENTS + ${LLVM_TARGETS_TO_BUILD} + Support + Target + ) + +add_llvm_target_unittest(AMDGPUTests + DwarfRegMappings.cpp + ) Index: llvm/unittests/Target/AMDGPU/DwarfRegMappings.cpp =================================================================== --- /dev/null +++ llvm/unittests/Target/AMDGPU/DwarfRegMappings.cpp @@ -0,0 +1,137 @@ +#include "AMDGPUSubtarget.h" +#include "AMDGPUTargetMachine.h" +#include "llvm/CodeGen/TargetSubtargetInfo.h" +#include "llvm/MC/MCTargetOptions.h" +#include "llvm/Support/TargetRegistry.h" +#include "llvm/Support/TargetSelect.h" +#include "llvm/Target/TargetMachine.h" +#include "gtest/gtest.h" +#include + +using namespace llvm; + +std::once_flag flag; +void InitializeTargets() { + std::call_once(flag, []() { + InitializeAllTargets(); + InitializeAllTargetMCs(); + }); +} + +TEST(DwarfRegMappingTests, TestWave64DwarfRegMapping) { + InitializeTargets(); + + std::string Error; + const Target *T = TargetRegistry::lookupTarget("amdgcn-amd", Error); + ASSERT_TRUE(T); + + TargetOptions Options; + auto TM = static_cast(T->createTargetMachine( + "amdgcn", "gfx1010", "+wavefrontsize64", Options, None, None)); + ASSERT_TRUE(TM); + + GCNSubtarget ST(TM->getTargetTriple(), std::string(TM->getTargetCPU()), + std::string(TM->getTargetFeatureString()), *TM); + + auto MRI = ST.getRegisterInfo(); + ASSERT_TRUE(MRI); + + // PC_64 => 16 + MCRegister PCReg(*MRI->getLLVMRegNum(16, false)); + EXPECT_EQ(16, MRI->getDwarfRegNum(PCReg, false)); + + // EXEC_MASK_64 => 17 + MCRegister EXECReg(*MRI->getLLVMRegNum(17, false)); + EXPECT_EQ(17, MRI->getDwarfRegNum(EXECReg, false)); + + // S0 => 32 + MCRegister S0Reg(*MRI->getLLVMRegNum(32, false)); + EXPECT_EQ(32, MRI->getDwarfRegNum(S0Reg, false)); + + // S63 => 95 + MCRegister S63Reg(*MRI->getLLVMRegNum(95, false)); + EXPECT_EQ(95, MRI->getDwarfRegNum(S63Reg, false)); + + // S64 => 1088 + MCRegister S64Reg(*MRI->getLLVMRegNum(1088, false)); + EXPECT_EQ(1088, MRI->getDwarfRegNum(S64Reg, false)); + + // S105 => 1129 + MCRegister S105Reg(*MRI->getLLVMRegNum(1129, false)); + EXPECT_EQ(1129, MRI->getDwarfRegNum(S105Reg, false)); + + // V0 => 2560 + MCRegister V0Reg(*MRI->getLLVMRegNum(2560, false)); + EXPECT_EQ(2560, MRI->getDwarfRegNum(V0Reg, false)); + + // V255 => 2815 + MCRegister V255Reg(*MRI->getLLVMRegNum(2815, false)); + EXPECT_EQ(2815, MRI->getDwarfRegNum(V255Reg, false)); + + // A0 => 3072 + MCRegister A0Reg(*MRI->getLLVMRegNum(3072, false)); + EXPECT_EQ(3072, MRI->getDwarfRegNum(A0Reg, false)); + + // A255 => 3327 + MCRegister A255Reg(*MRI->getLLVMRegNum(3327, false)); + EXPECT_EQ(3327, MRI->getDwarfRegNum(A255Reg, false)); +} + +TEST(DwarfRegMappingTests, TestWave32DwarfRegMapping) { + InitializeTargets(); + + std::string Error; + const Target *T = TargetRegistry::lookupTarget("amdgcn-amd", Error); + ASSERT_TRUE(T); + + TargetOptions Options; + auto TM = static_cast(T->createTargetMachine( + "amdgcn", "gfx1010", "+wavefrontsize32", Options, None, None)); + ASSERT_TRUE(TM); + + GCNSubtarget ST(TM->getTargetTriple(), std::string(TM->getTargetCPU()), + std::string(TM->getTargetFeatureString()), *TM); + + auto MRI = ST.getRegisterInfo(); + ASSERT_TRUE(MRI); + + // PC_32 => 0 + MCRegister PCReg(*MRI->getLLVMRegNum(0, false)); + EXPECT_EQ(0, MRI->getDwarfRegNum(PCReg, false)); + + // EXEC_MASK_32 => 1 + MCRegister EXECReg(*MRI->getLLVMRegNum(1, false)); + EXPECT_EQ(1, MRI->getDwarfRegNum(EXECReg, false)); + + // S0 => 32 + MCRegister S0Reg(*MRI->getLLVMRegNum(32, false)); + EXPECT_EQ(32, MRI->getDwarfRegNum(S0Reg, false)); + + // S63 => 95 + MCRegister S63Reg(*MRI->getLLVMRegNum(95, false)); + EXPECT_EQ(95, MRI->getDwarfRegNum(S63Reg, false)); + + // S64 => 1088 + MCRegister S64Reg(*MRI->getLLVMRegNum(1088, false)); + EXPECT_EQ(1088, MRI->getDwarfRegNum(S64Reg, false)); + + // S105 => 1129 + MCRegister S105Reg(*MRI->getLLVMRegNum(1129, false)); + EXPECT_EQ(1129, MRI->getDwarfRegNum(S105Reg, false)); + + // V0 => 1536 + MCRegister V0Reg(*MRI->getLLVMRegNum(1536, false)); + EXPECT_EQ(1536, MRI->getDwarfRegNum(V0Reg, false)); + + // V255 => 1791 + MCRegister V255Reg(*MRI->getLLVMRegNum(1791, false)); + EXPECT_EQ(1791, MRI->getDwarfRegNum(V255Reg, false)); + + // A0 => 2048 + MCRegister A0Reg(*MRI->getLLVMRegNum(2048, false)); + EXPECT_EQ(2048, MRI->getDwarfRegNum(A0Reg, false)); + + // A255 => 2303 + MCRegister A255Reg(*MRI->getLLVMRegNum(2303, false)); + EXPECT_EQ(2303, MRI->getDwarfRegNum(A255Reg, false)); +}