mirror of
https://github.com/RPCS3/llvm.git
synced 2024-11-24 20:30:06 +00:00
[mips] Stop reserving register AT and use register scavenger when a scratch
register is needed. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@167341 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
da15a0ed4c
commit
11a45c214c
@ -81,11 +81,11 @@ MipsRegisterInfo::getCallPreservedMask(CallingConv::ID) const {
|
||||
BitVector MipsRegisterInfo::
|
||||
getReservedRegs(const MachineFunction &MF) const {
|
||||
static const uint16_t ReservedCPURegs[] = {
|
||||
Mips::ZERO, Mips::AT, Mips::K0, Mips::K1, Mips::SP
|
||||
Mips::ZERO, Mips::K0, Mips::K1, Mips::SP
|
||||
};
|
||||
|
||||
static const uint16_t ReservedCPU64Regs[] = {
|
||||
Mips::ZERO_64, Mips::AT_64, Mips::K0_64, Mips::K1_64, Mips::SP_64
|
||||
Mips::ZERO_64, Mips::K0_64, Mips::K1_64, Mips::SP_64
|
||||
};
|
||||
|
||||
BitVector Reserved(getNumRegs());
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "llvm/CodeGen/MachineModuleInfo.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/CodeGen/RegisterScavenging.h"
|
||||
#include "llvm/DataLayout.h"
|
||||
#include "llvm/Target/TargetOptions.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
@ -202,6 +203,19 @@ processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
|
||||
// Mark $fp as used if function has dedicated frame pointer.
|
||||
if (hasFP(MF))
|
||||
MRI.setPhysRegUsed(FP);
|
||||
|
||||
// Set scavenging frame index if necessary.
|
||||
uint64_t MaxSPOffset = MF.getInfo<MipsFunctionInfo>()->getIncomingArgSize() +
|
||||
estimateStackSize(MF);
|
||||
|
||||
if (isInt<16>(MaxSPOffset))
|
||||
return;
|
||||
|
||||
const TargetRegisterClass *RC = STI.isABI_N64() ?
|
||||
&Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass;
|
||||
int FI = MF.getFrameInfo()->CreateStackObject(RC->getSize(),
|
||||
RC->getAlignment(), false);
|
||||
RS->setScavengingFrameIndex(FI);
|
||||
}
|
||||
|
||||
const MipsFrameLowering *
|
||||
|
@ -261,7 +261,7 @@ void MipsSEInstrInfo::adjustStackPtr(unsigned SP, int64_t Amount,
|
||||
BuildMI(MBB, I, DL, get(ADDiu), SP).addReg(SP).addImm(Amount);
|
||||
else { // Expand immediate that doesn't fit in 16-bit.
|
||||
unsigned Reg = loadImmediate(Amount, MBB, I, DL, 0);
|
||||
BuildMI(MBB, I, DL, get(ADDu), SP).addReg(SP).addReg(Reg);
|
||||
BuildMI(MBB, I, DL, get(ADDu), SP).addReg(SP).addReg(Reg, RegState::Kill);
|
||||
}
|
||||
}
|
||||
|
||||
@ -273,10 +273,12 @@ MipsSEInstrInfo::loadImmediate(int64_t Imm, MachineBasicBlock &MBB,
|
||||
unsigned *NewImm) const {
|
||||
MipsAnalyzeImmediate AnalyzeImm;
|
||||
const MipsSubtarget &STI = TM.getSubtarget<MipsSubtarget>();
|
||||
MachineRegisterInfo &RegInfo = MBB.getParent()->getRegInfo();
|
||||
unsigned Size = STI.isABI_N64() ? 64 : 32;
|
||||
unsigned LUi = STI.isABI_N64() ? Mips::LUi64 : Mips::LUi;
|
||||
unsigned ZEROReg = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO;
|
||||
unsigned ATReg = STI.isABI_N64() ? Mips::AT_64 : Mips::AT;
|
||||
const TargetRegisterClass *RC = STI.isABI_N64() ?
|
||||
&Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass;
|
||||
bool LastInstrIsADDiu = NewImm;
|
||||
|
||||
const MipsAnalyzeImmediate::InstSeq &Seq =
|
||||
@ -288,22 +290,23 @@ MipsSEInstrInfo::loadImmediate(int64_t Imm, MachineBasicBlock &MBB,
|
||||
// The first instruction can be a LUi, which is different from other
|
||||
// instructions (ADDiu, ORI and SLL) in that it does not have a register
|
||||
// operand.
|
||||
unsigned Reg = RegInfo.createVirtualRegister(RC);
|
||||
|
||||
if (Inst->Opc == LUi)
|
||||
BuildMI(MBB, II, DL, get(LUi), ATReg)
|
||||
.addImm(SignExtend64<16>(Inst->ImmOpnd));
|
||||
BuildMI(MBB, II, DL, get(LUi), Reg).addImm(SignExtend64<16>(Inst->ImmOpnd));
|
||||
else
|
||||
BuildMI(MBB, II, DL, get(Inst->Opc), ATReg).addReg(ZEROReg)
|
||||
BuildMI(MBB, II, DL, get(Inst->Opc), Reg).addReg(ZEROReg)
|
||||
.addImm(SignExtend64<16>(Inst->ImmOpnd));
|
||||
|
||||
// Build the remaining instructions in Seq.
|
||||
for (++Inst; Inst != Seq.end() - LastInstrIsADDiu; ++Inst)
|
||||
BuildMI(MBB, II, DL, get(Inst->Opc), ATReg).addReg(ATReg)
|
||||
BuildMI(MBB, II, DL, get(Inst->Opc), Reg).addReg(Reg, RegState::Kill)
|
||||
.addImm(SignExtend64<16>(Inst->ImmOpnd));
|
||||
|
||||
if (LastInstrIsADDiu)
|
||||
*NewImm = Inst->ImmOpnd;
|
||||
|
||||
return ATReg;
|
||||
return Reg;
|
||||
}
|
||||
|
||||
unsigned MipsSEInstrInfo::GetAnalyzableBrOpc(unsigned Opc) const {
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/Target/TargetFrameLowering.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Target/TargetOptions.h"
|
||||
@ -43,6 +44,16 @@ MipsSERegisterInfo::MipsSERegisterInfo(const MipsSubtarget &ST,
|
||||
const MipsSEInstrInfo &I)
|
||||
: MipsRegisterInfo(ST), TII(I) {}
|
||||
|
||||
bool MipsSERegisterInfo::
|
||||
requiresRegisterScavenging(const MachineFunction &MF) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MipsSERegisterInfo::
|
||||
requiresFrameIndexScavenging(const MachineFunction &MF) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
// This function eliminate ADJCALLSTACKDOWN,
|
||||
// ADJCALLSTACKUP pseudo instructions
|
||||
void MipsSERegisterInfo::
|
||||
@ -102,6 +113,7 @@ void MipsSERegisterInfo::eliminateFI(MachineBasicBlock::iterator II,
|
||||
// - If the frame object is any of the following, its offset must be adjusted
|
||||
// by adding the size of the stack:
|
||||
// incoming argument, callee-saved register location or local variable.
|
||||
bool IsKill = false;
|
||||
int64_t Offset;
|
||||
|
||||
Offset = SPOffset + (int64_t)StackSize;
|
||||
@ -115,16 +127,17 @@ void MipsSERegisterInfo::eliminateFI(MachineBasicBlock::iterator II,
|
||||
MachineBasicBlock &MBB = *MI.getParent();
|
||||
DebugLoc DL = II->getDebugLoc();
|
||||
unsigned ADDu = Subtarget.isABI_N64() ? Mips::DADDu : Mips::ADDu;
|
||||
unsigned ATReg = Subtarget.isABI_N64() ? Mips::AT_64 : Mips::AT;
|
||||
unsigned NewImm;
|
||||
|
||||
unsigned Reg = TII.loadImmediate(Offset, MBB, II, DL, &NewImm);
|
||||
BuildMI(MBB, II, DL, TII.get(ADDu), ATReg).addReg(FrameReg).addReg(Reg);
|
||||
BuildMI(MBB, II, DL, TII.get(ADDu), Reg).addReg(FrameReg)
|
||||
.addReg(Reg, RegState::Kill);
|
||||
|
||||
FrameReg = ATReg;
|
||||
FrameReg = Reg;
|
||||
Offset = SignExtend64<16>(NewImm);
|
||||
IsKill = true;
|
||||
}
|
||||
|
||||
MI.getOperand(OpNo).ChangeToRegister(FrameReg, false);
|
||||
MI.getOperand(OpNo).ChangeToRegister(FrameReg, false, false, IsKill);
|
||||
MI.getOperand(OpNo + 1).ChangeToImmediate(Offset);
|
||||
}
|
||||
|
@ -27,6 +27,10 @@ public:
|
||||
MipsSERegisterInfo(const MipsSubtarget &Subtarget,
|
||||
const MipsSEInstrInfo &TII);
|
||||
|
||||
bool requiresRegisterScavenging(const MachineFunction &MF) const;
|
||||
|
||||
bool requiresFrameIndexScavenging(const MachineFunction &MF) const;
|
||||
|
||||
void eliminateCallFramePseudoInstr(MachineFunction &MF,
|
||||
MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator I) const;
|
||||
|
@ -1,4 +1,6 @@
|
||||
; RUN: llc -march=mipsel -mcpu=mips32r2 < %s | FileCheck %s
|
||||
; RUN: llc -march=mipsel < %s | FileCheck %s -check-prefix=32
|
||||
; RUN: llc -march=mips64el -mcpu=mips64 -mattr=n64 < %s | \
|
||||
; RUN: FileCheck %s -check-prefix=64
|
||||
|
||||
%struct.S1 = type { [65536 x i8] }
|
||||
|
||||
@ -6,9 +8,21 @@
|
||||
|
||||
define void @f() nounwind {
|
||||
entry:
|
||||
; CHECK: lui $[[R0:[0-9]+]], 65535
|
||||
; CHECK: addiu $[[R0]], $[[R0]], -16
|
||||
; CHECK: addu $sp, $sp, $[[R0]]
|
||||
; 32: lui $[[R0:[0-9]+]], 65535
|
||||
; 32: addiu $[[R0]], $[[R0]], -24
|
||||
; 32: addu $sp, $sp, $[[R0]]
|
||||
; 32: lui $[[R1:[0-9]+]], 1
|
||||
; 32: addu $[[R1]], $sp, $[[R1]]
|
||||
; 32: sw $ra, 20($[[R1]])
|
||||
; 64: daddiu $[[R0:[0-9]+]], $zero, 1
|
||||
; 64: dsll $[[R0]], $[[R0]], 48
|
||||
; 64: daddiu $[[R0]], $[[R0]], -1
|
||||
; 64: dsll $[[R0]], $[[R0]], 16
|
||||
; 64: daddiu $[[R0]], $[[R0]], -48
|
||||
; 64: daddu $sp, $sp, $[[R0]]
|
||||
; 64: lui $[[R1:[0-9]+]], 1
|
||||
; 64: daddu $[[R1]], $sp, $[[R1]]
|
||||
; 64: sd $ra, 40($[[R1]])
|
||||
|
||||
%agg.tmp = alloca %struct.S1, align 1
|
||||
%tmp = getelementptr inbounds %struct.S1* %agg.tmp, i32 0, i32 0, i32 0
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
; Sign extend from 32 to 64 was creating nonsense opcodes
|
||||
|
||||
; CHECK: sll ${{[0-9]+}}, ${{[0-9]+}}, 0
|
||||
; CHECK: sll ${{[a-z0-9]+}}, ${{[a-z0-9]+}}, 0
|
||||
|
||||
define i64 @foo(i32 %ival) nounwind readnone {
|
||||
entry:
|
||||
@ -10,7 +10,7 @@ entry:
|
||||
ret i64 %conv
|
||||
}
|
||||
|
||||
; CHECK: dsll32 ${{[0-9]+}}, ${{[0-9]+}}, 0
|
||||
; CHECK: dsll32 ${{[a-z0-9]+}}, ${{[a-z0-9]+}}, 0
|
||||
|
||||
define i64 @foo_2(i32 %ival_2) nounwind readnone {
|
||||
entry:
|
||||
|
Loading…
Reference in New Issue
Block a user