[ARC] ARCRegisterInfo cleanup prior to adding core register pairs (ARC32) and 64-bit core registers (ARC64)

Differential Revision: https://reviews.llvm.org/D11108
This commit is contained in:
Mark Schimmel 2021-10-07 12:59:39 -07:00
parent 9f9ed7a81a
commit 417f8ea4ba
8 changed files with 111 additions and 103 deletions

View File

@ -43,8 +43,9 @@ enum TSFlagsConstants {
// Pin the vtable to this file.
void ARCInstrInfo::anchor() {}
ARCInstrInfo::ARCInstrInfo()
: ARCGenInstrInfo(ARC::ADJCALLSTACKDOWN, ARC::ADJCALLSTACKUP), RI() {}
ARCInstrInfo::ARCInstrInfo(const ARCSubtarget &ST)
: ARCGenInstrInfo(ARC::ADJCALLSTACKDOWN, ARC::ADJCALLSTACKUP), ST(ST),
RI(ST) {}
static bool isZeroImm(const MachineOperand &Op) {
return Op.isImm() && Op.getImm() == 0;
@ -99,7 +100,7 @@ unsigned ARCInstrInfo::isStoreToStackSlot(const MachineInstr &MI,
}
/// Return the inverse of passed condition, i.e. turning COND_E to COND_NE.
static ARCCC::CondCode GetOppositeBranchCondition(ARCCC::CondCode CC) {
static ARCCC::CondCode getOppositeBranchCondition(ARCCC::CondCode CC) {
switch (CC) {
default:
llvm_unreachable("Illegal condition code!");
@ -280,23 +281,23 @@ unsigned ARCInstrInfo::removeBranch(MachineBasicBlock &MBB,
void ARCInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I,
const DebugLoc &dl, MCRegister DestReg,
const DebugLoc &DL, MCRegister DestReg,
MCRegister SrcReg, bool KillSrc) const {
assert(ARC::GPR32RegClass.contains(SrcReg) &&
"Only GPR32 src copy supported.");
assert(ARC::GPR32RegClass.contains(DestReg) &&
"Only GPR32 dest copy supported.");
BuildMI(MBB, I, dl, get(ARC::MOV_rr), DestReg)
BuildMI(MBB, I, DL, get(ARC::MOV_rr), DestReg)
.addReg(SrcReg, getKillRegState(KillSrc));
}
void ARCInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I,
Register SrcReg, bool isKill,
Register SrcReg, bool IsKill,
int FrameIndex,
const TargetRegisterClass *RC,
const TargetRegisterInfo *TRI) const {
DebugLoc dl = MBB.findDebugLoc(I);
DebugLoc DL = MBB.findDebugLoc(I);
MachineFunction &MF = *MBB.getParent();
MachineFrameInfo &MFI = MF.getFrameInfo();
@ -312,8 +313,8 @@ void ARCInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
"Only support GPR32 stores to stack now.");
LLVM_DEBUG(dbgs() << "Created store reg=" << printReg(SrcReg, TRI)
<< " to FrameIndex=" << FrameIndex << "\n");
BuildMI(MBB, I, dl, get(ARC::ST_rs9))
.addReg(SrcReg, getKillRegState(isKill))
BuildMI(MBB, I, DL, get(ARC::ST_rs9))
.addReg(SrcReg, getKillRegState(IsKill))
.addFrameIndex(FrameIndex)
.addImm(0)
.addMemOperand(MMO);
@ -324,7 +325,7 @@ void ARCInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
Register DestReg, int FrameIndex,
const TargetRegisterClass *RC,
const TargetRegisterInfo *TRI) const {
DebugLoc dl = MBB.findDebugLoc(I);
DebugLoc DL = MBB.findDebugLoc(I);
MachineFunction &MF = *MBB.getParent();
MachineFrameInfo &MFI = MF.getFrameInfo();
MachineMemOperand *MMO = MF.getMachineMemOperand(
@ -339,7 +340,7 @@ void ARCInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
"Only support GPR32 stores to stack now.");
LLVM_DEBUG(dbgs() << "Created load reg=" << printReg(DestReg, TRI)
<< " from FrameIndex=" << FrameIndex << "\n");
BuildMI(MBB, I, dl, get(ARC::LD_rs9))
BuildMI(MBB, I, DL, get(ARC::LD_rs9))
.addReg(DestReg, RegState::Define)
.addFrameIndex(FrameIndex)
.addImm(0)
@ -350,7 +351,7 @@ void ARCInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
bool ARCInstrInfo::reverseBranchCondition(
SmallVectorImpl<MachineOperand> &Cond) const {
assert((Cond.size() == 3) && "Invalid ARC branch condition!");
Cond[2].setImm(GetOppositeBranchCondition((ARCCC::CondCode)Cond[2].getImm()));
Cond[2].setImm(getOppositeBranchCondition((ARCCC::CondCode)Cond[2].getImm()));
return false;
}
@ -358,9 +359,9 @@ MachineBasicBlock::iterator
ARCInstrInfo::loadImmediate(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI, unsigned Reg,
uint64_t Value) const {
DebugLoc dl = MBB.findDebugLoc(MI);
DebugLoc DL = MBB.findDebugLoc(MI);
if (isInt<12>(Value)) {
return BuildMI(MBB, MI, dl, get(ARC::MOV_rs12), Reg)
return BuildMI(MBB, MI, DL, get(ARC::MOV_rs12), Reg)
.addImm(Value)
.getInstr();
}
@ -371,7 +372,7 @@ unsigned ARCInstrInfo::insertBranch(MachineBasicBlock &MBB,
MachineBasicBlock *TBB,
MachineBasicBlock *FBB,
ArrayRef<MachineOperand> Cond,
const DebugLoc &dl, int *BytesAdded) const {
const DebugLoc &DL, int *BytesAdded) const {
assert(!BytesAdded && "Code size not handled.");
// Shouldn't be a fall through.
@ -380,11 +381,11 @@ unsigned ARCInstrInfo::insertBranch(MachineBasicBlock &MBB,
"ARC branch conditions have two components!");
if (Cond.empty()) {
BuildMI(&MBB, dl, get(ARC::BR)).addMBB(TBB);
BuildMI(&MBB, DL, get(ARC::BR)).addMBB(TBB);
return 1;
}
int BccOpc = Cond[1].isImm() ? ARC::BRcc_ru6_p : ARC::BRcc_rr_p;
MachineInstrBuilder MIB = BuildMI(&MBB, dl, get(BccOpc));
MachineInstrBuilder MIB = BuildMI(&MBB, DL, get(BccOpc));
MIB.addMBB(TBB);
for (unsigned i = 0; i < 3; i++) {
MIB.add(Cond[i]);
@ -396,7 +397,7 @@ unsigned ARCInstrInfo::insertBranch(MachineBasicBlock &MBB,
}
// Two-way conditional branch.
BuildMI(&MBB, dl, get(ARC::BR)).addMBB(FBB);
BuildMI(&MBB, DL, get(ARC::BR)).addMBB(FBB);
return 2;
}

View File

@ -24,11 +24,12 @@ namespace llvm {
class ARCSubtarget;
class ARCInstrInfo : public ARCGenInstrInfo {
const ARCSubtarget &ST;
const ARCRegisterInfo RI;
virtual void anchor();
public:
ARCInstrInfo();
ARCInstrInfo(const ARCSubtarget &);
const ARCRegisterInfo &getRegisterInfo() const { return RI; }
@ -57,19 +58,19 @@ public:
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond,
const DebugLoc &dl,
const DebugLoc &,
int *BytesAdded = nullptr) const override;
unsigned removeBranch(MachineBasicBlock &MBB,
int *BytesRemoved = nullptr) const override;
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
const DebugLoc &dl, MCRegister DestReg, MCRegister SrcReg,
const DebugLoc &, MCRegister DestReg, MCRegister SrcReg,
bool KillSrc) const override;
void storeRegToStackSlot(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI, Register SrcReg,
bool isKill, int FrameIndex,
bool IsKill, int FrameIndex,
const TargetRegisterClass *RC,
const TargetRegisterInfo *TRI) const override;

View File

@ -84,9 +84,9 @@ private:
// instruction \p To
bool canHoistLoadStoreTo(MachineInstr *Ldst, MachineInstr *To);
// Returns true if load/store instruction \p Ldst can be sunk down
// to instruction \p To
bool canSinkLoadStoreTo(MachineInstr *Ldst, MachineInstr *To);
// // Returns true if load/store instruction \p Ldst can be sunk down
// // to instruction \p To
// bool canSinkLoadStoreTo(MachineInstr *Ldst, MachineInstr *To);
// Check if instructions \p Ldst and \p Add can be moved to become adjacent
// If they can return instruction which need not to move.
@ -424,30 +424,30 @@ bool ARCOptAddrMode::canHoistLoadStoreTo(MachineInstr *Ldst, MachineInstr *To) {
return true;
}
bool ARCOptAddrMode::canSinkLoadStoreTo(MachineInstr *Ldst, MachineInstr *To) {
// Can only sink load/store within same BB
if (Ldst->getParent() != To->getParent())
return false;
MachineBasicBlock::const_iterator MI(Ldst), ME(To),
End(Ldst->getParent()->end());
// bool ARCOptAddrMode::canSinkLoadStoreTo(MachineInstr *Ldst, MachineInstr *To) {
// // Can only sink load/store within same BB
// if (Ldst->getParent() != To->getParent())
// return false;
// MachineBasicBlock::const_iterator MI(Ldst), ME(To),
// End(Ldst->getParent()->end());
bool IsStore = Ldst->mayStore();
bool IsLoad = Ldst->mayLoad();
// bool IsStore = Ldst->mayStore();
// bool IsLoad = Ldst->mayLoad();
Register ValReg = IsLoad ? Ldst->getOperand(0).getReg() : Register();
for (; MI != ME && MI != End; ++MI) {
if (MI->isDebugValue())
continue;
if (MI->mayStore() || MI->isCall() || MI->isInlineAsm() ||
MI->hasUnmodeledSideEffects())
return false;
if (IsStore && MI->mayLoad())
return false;
if (ValReg && MI->readsVirtualRegister(ValReg))
return false;
}
return true;
}
// Register ValReg = IsLoad ? Ldst->getOperand(0).getReg() : Register();
// for (; MI != ME && MI != End; ++MI) {
// if (MI->isDebugValue())
// continue;
// if (MI->mayStore() || MI->isCall() || MI->isInlineAsm() ||
// MI->hasUnmodeledSideEffects())
// return false;
// if (IsStore && MI->mayLoad())
// return false;
// if (ValReg && MI->readsVirtualRegister(ValReg))
// return false;
// }
// return true;
// }
void ARCOptAddrMode::changeToAddrMode(MachineInstr &Ldst, unsigned NewOpcode,
unsigned NewBase,

View File

@ -35,19 +35,19 @@ using namespace llvm;
#define GET_REGINFO_TARGET_DESC
#include "ARCGenRegisterInfo.inc"
static void ReplaceFrameIndex(MachineBasicBlock::iterator II,
static void replaceFrameIndex(MachineBasicBlock::iterator II,
const ARCInstrInfo &TII, unsigned Reg,
unsigned FrameReg, int Offset, int StackSize,
int ObjSize, RegScavenger *RS, int SPAdj) {
assert(RS && "Need register scavenger.");
MachineInstr &MI = *II;
MachineBasicBlock &MBB = *MI.getParent();
DebugLoc dl = MI.getDebugLoc();
DebugLoc DL = MI.getDebugLoc();
unsigned BaseReg = FrameReg;
unsigned KillState = 0;
if (MI.getOpcode() == ARC::LD_rs9 && (Offset >= 256 || Offset < -256)) {
// Loads can always be reached with LD_rlimm.
BuildMI(MBB, II, dl, TII.get(ARC::LD_rlimm), Reg)
BuildMI(MBB, II, DL, TII.get(ARC::LD_rlimm), Reg)
.addReg(BaseReg)
.addImm(Offset)
.addMemOperand(*MI.memoperands_begin());
@ -72,7 +72,7 @@ static void ReplaceFrameIndex(MachineBasicBlock::iterator II,
RS->setRegUsed(BaseReg);
}
unsigned AddOpc = isUInt<6>(Offset) ? ARC::ADD_rru6 : ARC::ADD_rrlimm;
BuildMI(MBB, II, dl, TII.get(AddOpc))
BuildMI(MBB, II, DL, TII.get(AddOpc))
.addReg(BaseReg, RegState::Define)
.addReg(FrameReg)
.addImm(Offset);
@ -90,7 +90,7 @@ static void ReplaceFrameIndex(MachineBasicBlock::iterator II,
case ARC::LDB_rs9:
case ARC::LDB_X_rs9:
LLVM_DEBUG(dbgs() << "Building LDFI\n");
BuildMI(MBB, II, dl, TII.get(MI.getOpcode()), Reg)
BuildMI(MBB, II, DL, TII.get(MI.getOpcode()), Reg)
.addReg(BaseReg, KillState)
.addImm(Offset)
.addMemOperand(*MI.memoperands_begin());
@ -103,7 +103,7 @@ static void ReplaceFrameIndex(MachineBasicBlock::iterator II,
LLVM_FALLTHROUGH;
case ARC::STB_rs9:
LLVM_DEBUG(dbgs() << "Building STFI\n");
BuildMI(MBB, II, dl, TII.get(MI.getOpcode()))
BuildMI(MBB, II, DL, TII.get(MI.getOpcode()))
.addReg(Reg, getKillRegState(MI.getOperand(0).isKill()))
.addReg(BaseReg, KillState)
.addImm(Offset)
@ -111,7 +111,7 @@ static void ReplaceFrameIndex(MachineBasicBlock::iterator II,
break;
case ARC::GETFI:
LLVM_DEBUG(dbgs() << "Building GETFI\n");
BuildMI(MBB, II, dl,
BuildMI(MBB, II, DL,
TII.get(isUInt<6>(Offset) ? ARC::ADD_rru6 : ARC::ADD_rrlimm))
.addReg(Reg, RegState::Define)
.addReg(FrameReg)
@ -125,7 +125,8 @@ static void ReplaceFrameIndex(MachineBasicBlock::iterator II,
MBB.erase(II);
}
ARCRegisterInfo::ARCRegisterInfo() : ARCGenRegisterInfo(ARC::BLINK) {}
ARCRegisterInfo::ARCRegisterInfo(const ARCSubtarget &ST)
: ARCGenRegisterInfo(ARC::BLINK), ST(ST) {}
bool ARCRegisterInfo::needsFrameMoves(const MachineFunction &MF) {
return MF.needsFrameMoves();
@ -145,6 +146,7 @@ BitVector ARCRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
Reserved.set(ARC::R25);
Reserved.set(ARC::BLINK);
Reserved.set(ARC::FP);
return Reserved;
}
@ -214,7 +216,7 @@ void ARCRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
"FP Offset not in bounds.");
}
}
ReplaceFrameIndex(II, TII, Reg, getFrameRegister(MF), Offset, StackSize,
replaceFrameIndex(II, TII, Reg, getFrameRegister(MF), Offset, StackSize,
ObjSize, RS, SPAdj);
}

View File

@ -21,10 +21,13 @@
namespace llvm {
class TargetInstrInfo;
class ARCSubtarget;
struct ARCRegisterInfo : public ARCGenRegisterInfo {
const ARCSubtarget &ST;
public:
ARCRegisterInfo();
ARCRegisterInfo(const ARCSubtarget &);
/// Code Generation virtual methods...

View File

@ -21,56 +21,56 @@ class Core<int num, string n, list<string>altNames=[]> : ARCReg<n, altNames> {
let HWEncoding = num;
}
class Status<string n> : ARCReg<n, []> {
// Auxilary register
class Aux<int num, string n, list<string> altNames=[]> : ARCReg<n, altNames> {
let HWEncoding = num;
}
// Integer registers
def R0 : Core< 0, "%r0">, DwarfRegNum<[0]>;
def R1 : Core< 1, "%r1">, DwarfRegNum<[1]>;
def R2 : Core< 2, "%r2">, DwarfRegNum<[2]>;
def R3 : Core< 3, "%r3">, DwarfRegNum<[3]>;
let CostPerUse=[1] in {
def R4 : Core< 4, "%r4">, DwarfRegNum<[4]>;
def R5 : Core< 5, "%r5">, DwarfRegNum<[5]>;
def R6 : Core< 6, "%r6">, DwarfRegNum<[6]>;
def R7 : Core< 7, "%r7">, DwarfRegNum<[7]>;
def R8 : Core< 8, "%r8">, DwarfRegNum<[8]>;
def R9 : Core< 9, "%r9">, DwarfRegNum<[9]>;
def R10 : Core<10, "%r10">, DwarfRegNum<[10]>;
def R11 : Core<11, "%r11">, DwarfRegNum<[11]>;
}
def R12 : Core<12, "%r12">, DwarfRegNum<[12]>;
def R13 : Core<13, "%r13">, DwarfRegNum<[13]>;
def R14 : Core<14, "%r14">, DwarfRegNum<[14]>;
def R15 : Core<15, "%r15">, DwarfRegNum<[15]>;
foreach i = 0 - 3 in
def R#i : Core<i, "%r"#i>, DwarfRegNum<[i]>;
let CostPerUse=[1] in {
def R16 : Core<16, "%r16">, DwarfRegNum<[16]>;
def R17 : Core<17, "%r17">, DwarfRegNum<[17]>;
def R18 : Core<18, "%r18">, DwarfRegNum<[18]>;
def R19 : Core<19, "%r19">, DwarfRegNum<[19]>;
def R20 : Core<20, "%r20">, DwarfRegNum<[20]>;
def R21 : Core<21, "%r21">, DwarfRegNum<[21]>;
def R22 : Core<22, "%r22">, DwarfRegNum<[22]>;
def R23 : Core<23, "%r23">, DwarfRegNum<[23]>;
def R24 : Core<24, "%r24">, DwarfRegNum<[24]>;
def R25 : Core<25, "%r25">, DwarfRegNum<[25]>;
def GP : Core<26, "%gp",["%r26"]>, DwarfRegNum<[26]>;
def FP : Core<27, "%fp", ["%r27"]>, DwarfRegNum<[27]>;
def SP : Core<28, "%sp", ["%r28"]>, DwarfRegNum<[28]>;
def ILINK : Core<29, "%ilink">, DwarfRegNum<[29]>;
def R30 : Core<30, "%r30">, DwarfRegNum<[30]>;
def BLINK: Core<31, "%blink">, DwarfRegNum<[31]>;
def STATUS32 : Status<"status32">, DwarfRegNum<[32]>;
foreach i = 4 - 11 in
def R#i : Core<i, "%r"#i>, DwarfRegNum<[i]>;
}
foreach i = 12 - 15 in
def R#i : Core<i, "%r"#i>, DwarfRegNum<[i]>;
let CostPerUse=[1] in {
foreach i = 16 - 25 in
def R#i : Core<i, "%r"#i>, DwarfRegNum<[i]>;
def GP : Core<26, "%gp",["%r26"]>, DwarfRegNum<[26]>;
def FP : Core<27, "%fp", ["%r27"]>, DwarfRegNum<[27]>;
def SP : Core<28, "%sp", ["%r28"]>, DwarfRegNum<[28]>;
def ILINK : Core<29, "%ilink">, DwarfRegNum<[29]>;
def R30 : Core<30, "%r30">, DwarfRegNum<[30]>;
def BLINK : Core<31, "%blink">, DwarfRegNum<[31]>;
// Define extended core registers R32..R63
foreach i = 32 - 63 in
def R#i : Core<i, "%r"#i>, DwarfRegNum<[i]>;
}
// Auxilary registers
let CostPerUse=[1] in {
def STATUS32 : Aux<10, "status32">; // No DwarfRegNum defined in the ARC ABI
}
// Register classes.
//
def GPR32: RegisterClass<"ARC", [i32], 32,
(add R0, R1, R2, R3,
R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, R16, R17, R18, R19,
R20, R21, R22, R23, R24, R25, GP, FP, SP, ILINK, R30, BLINK)>;
(add (sequence "R%u", 0, 25), GP, FP, SP, ILINK, R30, BLINK, (sequence "R%u", 32, 63))> {
let AltOrders=[(add (sequence "R%u", 0, 25), GP, FP, SP, ILINK, R30, BLINK)];
let AltOrderSelect = [{
// When referenced in a C++ code block like this
// 0 is all Core32 regs
// 1 is AltOrders[0]
// 2 is AltOrders[1] and so on
return 1;
}];
}
def SREG : RegisterClass<"ARC", [i32], 1, (add STATUS32)>;

View File

@ -26,5 +26,5 @@ void ARCSubtarget::anchor() {}
ARCSubtarget::ARCSubtarget(const Triple &TT, const std::string &CPU,
const std::string &FS, const TargetMachine &TM)
: ARCGenSubtargetInfo(TT, CPU, /*TuneCPU=*/CPU, FS), FrameLowering(*this),
TLInfo(TM, *this) {}
: ARCGenSubtargetInfo(TT, CPU, /*TuneCPU=*/CPU, FS), InstrInfo(*this),
FrameLowering(*this), TLInfo(TM, *this) {}

View File

@ -29,14 +29,15 @@ class StringRef;
class TargetMachine;
class ARCSubtarget : public ARCGenSubtargetInfo {
bool Xnorm = false;
virtual void anchor();
ARCInstrInfo InstrInfo;
ARCFrameLowering FrameLowering;
ARCTargetLowering TLInfo;
SelectionDAGTargetInfo TSInfo;
// ARC processor extensions
bool Xnorm = false;
public:
/// This constructor initializes the data members to match that
/// of the specified triple.