[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:
Akira Hatanaka 2012-11-03 00:05:43 +00:00
parent da15a0ed4c
commit 11a45c214c
7 changed files with 67 additions and 19 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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