1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 02:33:06 +01:00

Implement wave32 DWARF register mapping

Implement the DWARF register mapping described in llvm/docs/AMDGPUUsage.rst.

This enables generating appropriate DWARF register numbers for wave64 and
wave32 modes.
This commit is contained in:
Ram Nalamothu 2020-03-23 16:26:51 +05:30 committed by Matt Arsenault
parent 9de2bc1313
commit 329ca52029
11 changed files with 225 additions and 12 deletions

View File

@ -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 @@ public:
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() {}
};

View File

@ -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 @@ AMDGPUTargetMachine::AMDGPUTargetMachine(const Target &T, const Triple &TT,
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;

View File

@ -65,6 +65,12 @@ static MCRegisterInfo *createAMDGPUMCRegisterInfo(const Triple &TT) {
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)

View File

@ -33,6 +33,10 @@ class Target;
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);

View File

@ -38,12 +38,9 @@ static cl::opt<bool> EnableSpillSGPRToVGPR(
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 {

View File

@ -103,7 +103,7 @@ def FP_REG : SIReg<"fp", 0>;
def SP_REG : SIReg<"sp", 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.
@ -117,10 +117,10 @@ def VCC : RegisterWithSubRegs<"vcc", [VCC_LO, VCC_HI]> {
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;
@ -211,7 +211,8 @@ def FLAT_SCR : FlatReg<FLAT_SCR_LO, FLAT_SCR_HI, 0>;
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
@ -222,7 +223,7 @@ foreach Index = 0-255 in {
let CostPerUse=!if(!gt(Index, 31), !srl(Index, 2), 0) in {
def VGPR#Index :
SIReg <"v"#Index, Index>,
DwarfRegNum<[!add(Index, 2560)]> {
DwarfRegNum<[!add(Index, 2560), !add(Index, 1536)]> {
let HWEncoding{8} = 1;
}
}
@ -232,7 +233,7 @@ foreach Index = 0-255 in {
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;
}
}

View File

@ -0,0 +1,9 @@
set(LLVM_LINK_COMPONENTS
${LLVM_TARGETS_TO_BUILD}
MC
Support
)
add_llvm_unittest(AMDGPUDwarfTests
DwarfRegMappings.cpp
)

View File

@ -0,0 +1,77 @@
//===- 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 <thread>
using namespace llvm;
std::once_flag flag;
void InitializeAMDGPUTarget() {
std::call_once(flag, []() {
LLVMInitializeAMDGPUTargetInfo();
LLVMInitializeAMDGPUTarget();
LLVMInitializeAMDGPUTargetMC();
});
}
std::unique_ptr<LLVMTargetMachine>
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<LLVMTargetMachine>(static_cast<LLVMTargetMachine *>(
T->createTargetMachine(TStr, CPU, FS, Options, None, None)));
}
TEST(AMDGPUDwarfRegMappingTests, TestWave64DwarfRegMapping) {
for (auto Triple :
{"amdgcn-amd-", "amdgcn-amd-amdhsa", "amdgcn-amd-amdpal"}) {
auto TM = createTargetMachine(Triple, "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) {
for (auto Triple :
{"amdgcn-amd-", "amdgcn-amd-amdhsa", "amdgcn-amd-amdpal"}) {
auto TM = createTargetMachine(Triple, "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));
}
}
}
}

View File

@ -12,3 +12,5 @@ add_llvm_unittest(MCTests
StringTableBuilderTest.cpp
TargetRegistry.cpp
)
add_subdirectory(AMDGPU)

View File

@ -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
)

View File

@ -0,0 +1,88 @@
//===- 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 <thread>
using namespace llvm;
std::once_flag flag;
void InitializeAMDGPUTarget() {
std::call_once(flag, []() {
LLVMInitializeAMDGPUTargetInfo();
LLVMInitializeAMDGPUTarget();
LLVMInitializeAMDGPUTargetMC();
});
}
std::unique_ptr<const GCNTargetMachine>
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<GCNTargetMachine>(static_cast<GCNTargetMachine *>(
T->createTargetMachine(TStr, CPU, FS, Options, None, None)));
}
TEST(AMDGPUDwarfRegMappingTests, TestWave64DwarfRegMapping) {
for (auto Triple :
{"amdgcn-amd-", "amdgcn-amd-amdhsa", "amdgcn-amd-amdpal"}) {
auto TM = createTargetMachine(Triple, "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) {
for (auto Triple :
{"amdgcn-amd-", "amdgcn-amd-amdhsa", "amdgcn-amd-amdpal"}) {
auto TM = createTargetMachine(Triple, "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));
}
}
}
}
}