[M68k][GloballSel] RegBankSelect implementation

Implementation of RegBankSelect for the M68k backend.

Differential Revision: https://reviews.llvm.org/D107542
This commit is contained in:
Sushma Unnibhavi 2021-08-09 23:36:16 -07:00 committed by Min-Yih Hsu
parent a353edb8d6
commit 7bdce6bcbd
4 changed files with 116 additions and 3 deletions

View File

@ -11,7 +11,8 @@
//===----------------------------------------------------------------------===//
#include "M68kRegisterBankInfo.h"
#include "MCTargetDesc/M68kMCTargetDesc.h"
#include "M68kInstrInfo.h" // For the register classes
#include "M68kSubtarget.h"
#include "llvm/CodeGen/GlobalISel/RegisterBank.h"
#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
@ -19,9 +20,86 @@
#define GET_TARGET_REGBANK_IMPL
#include "M68kGenRegisterBank.inc"
#undef GET_TARGET_REGBANK_IMPL
using namespace llvm;
// FIXME: TableGen this.
// If it grows too much and TableGen still isn't ready to do the job, extract it
// into an M68kGenRegisterBankInfo.def (similar to AArch64).
namespace llvm {
namespace M68k {
enum PartialMappingIdx {
PMI_GPR,
PMI_Min = PMI_GPR,
};
RegisterBankInfo::PartialMapping PartMappings[]{
// GPR Partial Mapping
{0, 32, GPRRegBank},
};
enum ValueMappingIdx {
InvalidIdx = 0,
GPR3OpsIdx = 1,
};
RegisterBankInfo::ValueMapping ValueMappings[] = {
// invalid
{nullptr, 0},
// 3 operands in GPRs
{&PartMappings[PMI_GPR - PMI_Min], 1},
{&PartMappings[PMI_GPR - PMI_Min], 1},
{&PartMappings[PMI_GPR - PMI_Min], 1},
};
} // end namespace M68k
} // end namespace llvm
M68kRegisterBankInfo::M68kRegisterBankInfo(const TargetRegisterInfo &TRI)
: M68kGenRegisterBankInfo() {}
const RegisterBank &
M68kRegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass &RC,
LLT) const {
return getRegBank(M68k::GPRRegBankID);
}
const RegisterBankInfo::InstructionMapping &
M68kRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
auto Opc = MI.getOpcode();
if (!isPreISelGenericOpcode(Opc)) {
const InstructionMapping &Mapping = getInstrMappingImpl(MI);
if (Mapping.isValid())
return Mapping;
}
using namespace TargetOpcode;
unsigned NumOperands = MI.getNumOperands();
const ValueMapping *OperandsMapping = &M68k::ValueMappings[M68k::GPR3OpsIdx];
switch (Opc) {
case G_ADD:
case G_SUB:
case G_MUL:
case G_SDIV:
case G_UDIV:
case G_LOAD:
case G_STORE: {
OperandsMapping = &M68k::ValueMappings[M68k::GPR3OpsIdx];
break;
}
case G_CONSTANT:
case G_FRAME_INDEX:
OperandsMapping =
getOperandsMapping({&M68k::ValueMappings[M68k::GPR3OpsIdx], nullptr});
break;
default:
return getInvalidInstructionMapping();
}
return getInstructionMapping(DefaultMappingID, /*Cost=*/1, OperandsMapping,
NumOperands);
}

View File

@ -34,6 +34,12 @@ protected:
class M68kRegisterBankInfo final : public M68kGenRegisterBankInfo {
public:
M68kRegisterBankInfo(const TargetRegisterInfo &TRI);
const RegisterBank &getRegBankFromRegClass(const TargetRegisterClass &RC,
LLT) const override;
const InstructionMapping &
getInstrMapping(const MachineInstr &MI) const override;
};
} // end namespace llvm
#endif

View File

@ -12,4 +12,4 @@
//===----------------------------------------------------------------------===//
/// General Purpose Registers. Here we define a register bank with name AnyGPR
def GPRRegBank : RegisterBank<"AnyGPR", [DR8]>;
def GPRRegBank : RegisterBank<"AnyGPR", [XR32]>;

View File

@ -0,0 +1,29 @@
; RUN: llc -mtriple=m68k -global-isel -stop-after=regbankselect < %s | FileCheck %s
define i32 @test_add(i32 %x, i32 %y) {
; CHECK-LABEL: name: test_add
; CHECK: bb.1 (%ir-block.0):
; CHECK: [[G_F_I1:%[0-9]+]]:anygpr(p0) = G_FRAME_INDEX
; CHECK: [[G_LOAD1:%[0-9]+]]:anygpr(s32) = G_LOAD [[G_F_I1]](p0)
; CHECK: [[G_F_I2:%[0-9]+]]:anygpr(p0) = G_FRAME_INDEX
; CHECK: [[G_LOAD2:%[0-9]+]]:anygpr(s32) = G_LOAD [[G_F_I2]](p0)
; CHECK: [[G_ADD1:%[0-9]+]]:anygpr(s32) = G_ADD [[G_LOAD1]], [[G_LOAD2]]
; CHECK: $d0 = COPY [[G_ADD1]](s32)
; CHECK: RTS implicit $d0
%sum = add i32 %x, %y
ret i32 %sum
}
define i32 @test_sub(i32 %x, i32 %y) {
; CHECK-LABEL: name: test_sub
; CHECK: bb.1 (%ir-block.0):
; CHECK: [[G_F_I1:%[0-9]+]]:anygpr(p0) = G_FRAME_INDEX
; CHECK: [[G_LOAD1:%[0-9]+]]:anygpr(s32) = G_LOAD [[G_F_I1]](p0)
; CHECK: [[G_F_I2:%[0-9]+]]:anygpr(p0) = G_FRAME_INDEX
; CHECK: [[G_LOAD2:%[0-9]+]]:anygpr(s32) = G_LOAD [[G_F_I2]](p0)
; CHECK: [[G_SUB1:%[0-9]+]]:anygpr(s32) = G_SUB [[G_LOAD1]], [[G_LOAD2]]
; CHECK: $d0 = COPY [[G_SUB1]](s32)
; CHECK: RTS implicit $d0
%diff = sub i32 %x, %y
ret i32 %diff
}