mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-11-01 00:17:01 +00:00
Start of revamping the register scavenging in PEI. ARM Thumb1 is the driving
interest for this, as it currently reserves a register rather than using the scavenger for matierializing constants as needed. Instead of scavenging registers on the fly while eliminating frame indices, new virtual registers are created, and then a scavenged collectively in a post-pass over the function. This isolates the bits that need to interact with the scavenger, and sets the stage for more intelligent use, and reuse, of scavenged registers. For the time being, this is disabled by default. Once the bugs are worked out, the current scavenging calls in replaceFrameIndices() will be removed and the post-pass scavenging will be the default. Until then, -enable-frame-index-scavenging enables the new code. Currently, only the Thumb1 back end is set up to use it. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@82734 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -649,10 +649,12 @@ ARMBaseRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
|
||||
// Estimate if we might need to scavenge a register at some point in order
|
||||
// to materialize a stack offset. If so, either spill one additional
|
||||
// callee-saved register or reserve a special spill slot to facilitate
|
||||
// register scavenging.
|
||||
if (RS && !ExtraCSSpill && !AFI->isThumb1OnlyFunction()) {
|
||||
// register scavenging. Thumb1 needs a spill slot for stack pointer
|
||||
// adjustments also, even when the frame itself is small.
|
||||
if (RS && !ExtraCSSpill) {
|
||||
MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||
if (estimateStackSize(MF, MFI) >= estimateRSStackSizeLimit(MF)) {
|
||||
if (estimateStackSize(MF, MFI) >= estimateRSStackSizeLimit(MF)
|
||||
|| AFI->isThumb1OnlyFunction()) {
|
||||
// If any non-reserved CS register isn't spilled, just spill one or two
|
||||
// extra. That should take care of it!
|
||||
unsigned NumExtras = TargetAlign / 4;
|
||||
|
||||
@@ -37,10 +37,10 @@
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
using namespace llvm;
|
||||
|
||||
static cl::opt<bool>
|
||||
ThumbRegScavenging("enable-thumb-reg-scavenging",
|
||||
cl::Hidden,
|
||||
cl::desc("Enable register scavenging on Thumb"));
|
||||
// FIXME: This cmd line option conditionalizes the new register scavenging
|
||||
// implemenation in PEI. Remove the option when scavenging works well enough
|
||||
// to be the default.
|
||||
extern cl::opt<bool> FrameIndexVirtualScavenging;
|
||||
|
||||
Thumb1RegisterInfo::Thumb1RegisterInfo(const ARMBaseInstrInfo &tii,
|
||||
const ARMSubtarget &sti)
|
||||
@@ -84,7 +84,7 @@ Thumb1RegisterInfo::getPhysicalRegisterRegClass(unsigned Reg, EVT VT) const {
|
||||
|
||||
bool
|
||||
Thumb1RegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const {
|
||||
return ThumbRegScavenging;
|
||||
return FrameIndexVirtualScavenging;
|
||||
}
|
||||
|
||||
bool Thumb1RegisterInfo::hasReservedCallFrame(MachineFunction &MF) const {
|
||||
@@ -113,6 +113,7 @@ void emitThumbRegPlusImmInReg(MachineBasicBlock &MBB,
|
||||
const TargetInstrInfo &TII,
|
||||
const Thumb1RegisterInfo& MRI,
|
||||
DebugLoc dl) {
|
||||
MachineFunction &MF = *MBB.getParent();
|
||||
bool isHigh = !isARMLowRegister(DestReg) ||
|
||||
(BaseReg != 0 && !isARMLowRegister(BaseReg));
|
||||
bool isSub = false;
|
||||
@@ -127,9 +128,13 @@ void emitThumbRegPlusImmInReg(MachineBasicBlock &MBB,
|
||||
unsigned LdReg = DestReg;
|
||||
if (DestReg == ARM::SP) {
|
||||
assert(BaseReg == ARM::SP && "Unexpected!");
|
||||
LdReg = ARM::R3;
|
||||
BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVtgpr2gpr), ARM::R12)
|
||||
.addReg(ARM::R3, RegState::Kill);
|
||||
if (FrameIndexVirtualScavenging) {
|
||||
LdReg = MF.getRegInfo().createVirtualRegister(ARM::tGPRRegisterClass);
|
||||
} else {
|
||||
LdReg = ARM::R3;
|
||||
BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVtgpr2gpr), ARM::R12)
|
||||
.addReg(ARM::R3, RegState::Kill);
|
||||
}
|
||||
}
|
||||
|
||||
if (NumBytes <= 255 && NumBytes >= 0)
|
||||
@@ -155,7 +160,7 @@ void emitThumbRegPlusImmInReg(MachineBasicBlock &MBB,
|
||||
MIB.addReg(LdReg).addReg(BaseReg, RegState::Kill);
|
||||
AddDefaultPred(MIB);
|
||||
|
||||
if (DestReg == ARM::SP)
|
||||
if (!FrameIndexVirtualScavenging && DestReg == ARM::SP)
|
||||
BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVgpr2tgpr), ARM::R3)
|
||||
.addReg(ARM::R12, RegState::Kill);
|
||||
}
|
||||
@@ -602,50 +607,73 @@ void Thumb1RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
|
||||
else // tLDR has an extra register operand.
|
||||
MI.addOperand(MachineOperand::CreateReg(0, false));
|
||||
} else if (Desc.mayStore()) {
|
||||
// FIXME! This is horrific!!! We need register scavenging.
|
||||
// Our temporary workaround has marked r3 unavailable. Of course, r3 is
|
||||
// also a ABI register so it's possible that is is the register that is
|
||||
// being storing here. If that's the case, we do the following:
|
||||
// r12 = r2
|
||||
// Use r2 to materialize sp + offset
|
||||
// str r3, r2
|
||||
// r2 = r12
|
||||
unsigned ValReg = MI.getOperand(0).getReg();
|
||||
unsigned TmpReg = ARM::R3;
|
||||
bool UseRR = false;
|
||||
if (ValReg == ARM::R3) {
|
||||
BuildMI(MBB, II, dl, TII.get(ARM::tMOVtgpr2gpr), ARM::R12)
|
||||
.addReg(ARM::R2, RegState::Kill);
|
||||
TmpReg = ARM::R2;
|
||||
}
|
||||
if (TmpReg == ARM::R3 && AFI->isR3LiveIn())
|
||||
BuildMI(MBB, II, dl, TII.get(ARM::tMOVtgpr2gpr), ARM::R12)
|
||||
.addReg(ARM::R3, RegState::Kill);
|
||||
if (Opcode == ARM::tSpill) {
|
||||
if (FrameReg == ARM::SP)
|
||||
emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg,
|
||||
Offset, false, TII, *this, dl);
|
||||
else {
|
||||
emitLoadConstPool(MBB, II, dl, TmpReg, 0, Offset);
|
||||
UseRR = true;
|
||||
if (FrameIndexVirtualScavenging) {
|
||||
unsigned TmpReg =
|
||||
MF.getRegInfo().createVirtualRegister(ARM::tGPRRegisterClass);
|
||||
bool UseRR = false;
|
||||
if (Opcode == ARM::tSpill) {
|
||||
if (FrameReg == ARM::SP)
|
||||
emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg,
|
||||
Offset, false, TII, *this, dl);
|
||||
else {
|
||||
emitLoadConstPool(MBB, II, dl, TmpReg, 0, Offset);
|
||||
UseRR = true;
|
||||
}
|
||||
} else
|
||||
emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset, TII,
|
||||
*this, dl);
|
||||
MI.setDesc(TII.get(ARM::tSTR));
|
||||
MI.getOperand(i).ChangeToRegister(TmpReg, false, false, true);
|
||||
if (UseRR) // Use [reg, reg] addrmode.
|
||||
MI.addOperand(MachineOperand::CreateReg(FrameReg, false));
|
||||
else // tSTR has an extra register operand.
|
||||
MI.addOperand(MachineOperand::CreateReg(0, false));
|
||||
} else {
|
||||
// FIXME! This is horrific!!! We need register scavenging.
|
||||
// Our temporary workaround has marked r3 unavailable. Of course, r3 is
|
||||
// also a ABI register so it's possible that is is the register that is
|
||||
// being storing here. If that's the case, we do the following:
|
||||
// r12 = r2
|
||||
// Use r2 to materialize sp + offset
|
||||
// str r3, r2
|
||||
// r2 = r12
|
||||
unsigned ValReg = MI.getOperand(0).getReg();
|
||||
unsigned TmpReg = ARM::R3;
|
||||
bool UseRR = false;
|
||||
if (ValReg == ARM::R3) {
|
||||
BuildMI(MBB, II, dl, TII.get(ARM::tMOVtgpr2gpr), ARM::R12)
|
||||
.addReg(ARM::R2, RegState::Kill);
|
||||
TmpReg = ARM::R2;
|
||||
}
|
||||
} else
|
||||
emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset, TII,
|
||||
*this, dl);
|
||||
MI.setDesc(TII.get(ARM::tSTR));
|
||||
MI.getOperand(i).ChangeToRegister(TmpReg, false, false, true);
|
||||
if (UseRR) // Use [reg, reg] addrmode.
|
||||
MI.addOperand(MachineOperand::CreateReg(FrameReg, false));
|
||||
else // tSTR has an extra register operand.
|
||||
MI.addOperand(MachineOperand::CreateReg(0, false));
|
||||
if (TmpReg == ARM::R3 && AFI->isR3LiveIn())
|
||||
BuildMI(MBB, II, dl, TII.get(ARM::tMOVtgpr2gpr), ARM::R12)
|
||||
.addReg(ARM::R3, RegState::Kill);
|
||||
if (Opcode == ARM::tSpill) {
|
||||
if (FrameReg == ARM::SP)
|
||||
emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg,
|
||||
Offset, false, TII, *this, dl);
|
||||
else {
|
||||
emitLoadConstPool(MBB, II, dl, TmpReg, 0, Offset);
|
||||
UseRR = true;
|
||||
}
|
||||
} else
|
||||
emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset, TII,
|
||||
*this, dl);
|
||||
MI.setDesc(TII.get(ARM::tSTR));
|
||||
MI.getOperand(i).ChangeToRegister(TmpReg, false, false, true);
|
||||
if (UseRR) // Use [reg, reg] addrmode.
|
||||
MI.addOperand(MachineOperand::CreateReg(FrameReg, false));
|
||||
else // tSTR has an extra register operand.
|
||||
MI.addOperand(MachineOperand::CreateReg(0, false));
|
||||
|
||||
MachineBasicBlock::iterator NII = next(II);
|
||||
if (ValReg == ARM::R3)
|
||||
BuildMI(MBB, NII, dl, TII.get(ARM::tMOVgpr2tgpr), ARM::R2)
|
||||
.addReg(ARM::R12, RegState::Kill);
|
||||
if (TmpReg == ARM::R3 && AFI->isR3LiveIn())
|
||||
BuildMI(MBB, NII, dl, TII.get(ARM::tMOVgpr2tgpr), ARM::R3)
|
||||
.addReg(ARM::R12, RegState::Kill);
|
||||
MachineBasicBlock::iterator NII = next(II);
|
||||
if (ValReg == ARM::R3)
|
||||
BuildMI(MBB, NII, dl, TII.get(ARM::tMOVgpr2tgpr), ARM::R2)
|
||||
.addReg(ARM::R12, RegState::Kill);
|
||||
if (TmpReg == ARM::R3 && AFI->isR3LiveIn())
|
||||
BuildMI(MBB, NII, dl, TII.get(ARM::tMOVgpr2tgpr), ARM::R3)
|
||||
.addReg(ARM::R12, RegState::Kill);
|
||||
}
|
||||
} else
|
||||
assert(false && "Unexpected opcode!");
|
||||
|
||||
@@ -834,11 +862,13 @@ void Thumb1RegisterInfo::emitEpilogue(MachineFunction &MF,
|
||||
if (VARegSaveSize) {
|
||||
// Epilogue for vararg functions: pop LR to R3 and branch off it.
|
||||
// FIXME: Verify this is still ok when R3 is no longer being reserved.
|
||||
AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tPOP))).addReg(ARM::R3);
|
||||
AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tPOP)))
|
||||
.addReg(ARM::R3, RegState::Define);
|
||||
|
||||
emitSPUpdate(MBB, MBBI, TII, dl, *this, VARegSaveSize);
|
||||
|
||||
BuildMI(MBB, MBBI, dl, TII.get(ARM::tBX_RET_vararg)).addReg(ARM::R3);
|
||||
BuildMI(MBB, MBBI, dl, TII.get(ARM::tBX_RET_vararg))
|
||||
.addReg(ARM::R3, RegState::Kill);
|
||||
MBB.erase(MBBI);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user