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,84 @@ +//===- llvm/unittests/MC/AMDGPU/DwarfRegMappings.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 InitializeAMDGPUTarget() { + std::call_once(flag, []() { + LLVMInitializeAMDGPUTargetInfo(); + LLVMInitializeAMDGPUTarget(); + LLVMInitializeAMDGPUTargetMC(); + }); +} + +std::unique_ptr +createTargetMachine(std::string TStr, StringRef CPU, StringRef FS) { + InitializeAMDGPUTarget(); + + std::string Error; + const Target *T = TargetRegistry::lookupTarget(TStr, Error); + if (!T) + return nullptr; + + TargetOptions Options; + return std::unique_ptr(static_cast( + T->createTargetMachine(TStr, CPU, FS, Options, None, None))); +} + +TEST(AMDGPUDwarfRegMappingTests, TestWave64DwarfRegMapping) { + // Test triple OS strings + std::vector OSTestValues = {"", "amdhsa", "amdpal"}; + + for (auto OS : OSTestValues) { + auto TM = + createTargetMachine("amdgcn-amd-" + OS, "gfx1010", "+wavefrontsize64"); + if (TM && TM->getMCRegisterInfo()) { + auto MRI = TM->getMCRegisterInfo(); + // Wave64 Dwarf register mapping test numbers + // PC_64 => 16, EXEC_MASK_64 => 17, S0 => 32, S63 => 95, + // S64 => 1088, S105 => 1129, V0 => 2560, V255 => 2815, + // A0 => 3072, A255 => 3327 + for (int llvmReg : {16, 17, 32, 95, 1088, 1129, 2560, 2815, 3072, 3327}) { + MCRegister PCReg(*MRI->getLLVMRegNum(llvmReg, false)); + EXPECT_EQ(llvmReg, MRI->getDwarfRegNum(PCReg, false)); + } + } + } +} + +TEST(AMDGPUDwarfRegMappingTests, TestWave32DwarfRegMapping) { + + // Test triple OS strings + std::vector OSTestValues = {"", "amdhsa", "amdpal"}; + + for (auto OS : OSTestValues) { + auto TM = + createTargetMachine("amdgcn-amd-" + OS, "gfx1010", "+wavefrontsize32"); + if (TM && TM->getMCRegisterInfo()) { + auto MRI = TM->getMCRegisterInfo(); + // Wave32 Dwarf register mapping test numbers + // PC_32 => 0, EXEC_MASK_32 => 1, S0 => 32, S63 => 95, + // S64 => 1088, S105 => 1129, V0 => 1536, V255 => 1791, + // A0 => 2048, A255 => 2303 + for (int llvmReg : {0, 1, 32, 95, 1088, 1129, 1536, 1791, 2048, 2303}) { + MCRegister PCReg(*MRI->getLLVMRegNum(llvmReg, false)); + EXPECT_EQ(llvmReg, MRI->getDwarfRegNum(PCReg, 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,95 @@ +//===- llvm/unittests/Target/AMDGPU/DwarfRegMappings.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 "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 InitializeAMDGPUTarget() { + std::call_once(flag, []() { + LLVMInitializeAMDGPUTargetInfo(); + LLVMInitializeAMDGPUTarget(); + LLVMInitializeAMDGPUTargetMC(); + }); +} + +std::unique_ptr +createTargetMachine(std::string TStr, StringRef CPU, StringRef FS) { + InitializeAMDGPUTarget(); + + std::string Error; + const Target *T = TargetRegistry::lookupTarget(TStr, Error); + if (!T) + return nullptr; + + TargetOptions Options; + return std::unique_ptr(static_cast( + T->createTargetMachine(TStr, CPU, FS, Options, None, None))); +} + +TEST(AMDGPUDwarfRegMappingTests, TestWave64DwarfRegMapping) { + // Test triple OS strings + std::vector OSTestValues = {"", "amdhsa", "amdpal"}; + + for (auto OS : OSTestValues) { + auto TM = + createTargetMachine("amdgcn-amd-" + OS, "gfx1010", "+wavefrontsize64"); + if (TM) { + GCNSubtarget ST(TM->getTargetTriple(), std::string(TM->getTargetCPU()), + std::string(TM->getTargetFeatureString()), *TM); + auto MRI = ST.getRegisterInfo(); + if (MRI) { + // Wave64 Dwarf register mapping test numbers + // PC_64 => 16, EXEC_MASK_64 => 17, S0 => 32, S63 => 95, + // S64 => 1088, S105 => 1129, V0 => 2560, V255 => 2815, + // A0 => 3072, A255 => 3327 + for (int llvmReg : + {16, 17, 32, 95, 1088, 1129, 2560, 2815, 3072, 3327}) { + MCRegister PCReg(*MRI->getLLVMRegNum(llvmReg, false)); + EXPECT_EQ(llvmReg, MRI->getDwarfRegNum(PCReg, false)); + } + } + } + } +} + +TEST(AMDGPUDwarfRegMappingTests, TestWave32DwarfRegMapping) { + + // Test triple OS strings + std::vector OSTestValues = {"", "amdhsa", "amdpal"}; + + for (auto OS : OSTestValues) { + auto TM = + createTargetMachine("amdgcn-amd-" + OS, "gfx1010", "+wavefrontsize32"); + if (TM) { + GCNSubtarget ST(TM->getTargetTriple(), std::string(TM->getTargetCPU()), + std::string(TM->getTargetFeatureString()), *TM); + auto MRI = ST.getRegisterInfo(); + if (MRI) { + // Wave32 Dwarf register mapping test numbers + // PC_32 => 0, EXEC_MASK_32 => 1, S0 => 32, S63 => 95, + // S64 => 1088, S105 => 1129, V0 => 1536, V255 => 1791, + // A0 => 2048, A255 => 2303 + for (int llvmReg : {0, 1, 32, 95, 1088, 1129, 1536, 1791, 2048, 2303}) { + MCRegister PCReg(*MRI->getLLVMRegNum(llvmReg, false)); + EXPECT_EQ(llvmReg, MRI->getDwarfRegNum(PCReg, false)); + } + } + } + } +}