- Track which callee-saved registers are spilled.

- Some code clean up.

llvm-svn: 34783
This commit is contained in:
Evan Cheng 2007-03-01 08:26:31 +00:00
parent 3f3487918c
commit 8d3d4155e5
3 changed files with 47 additions and 20 deletions

View File

@ -213,7 +213,7 @@ bool ARMConstantIslands::runOnMachineFunction(MachineFunction &Fn) {
// If LR has been forced spilled and no far jumps (i.e. BL) has been issued. // If LR has been forced spilled and no far jumps (i.e. BL) has been issued.
// Undo the spill / restore of LR if possible. // Undo the spill / restore of LR if possible.
if (!HasFarJump && AFI->isLRForceSpilled() && isThumb) if (!HasFarJump && AFI->isLRSpilledForFarJump() && isThumb)
MadeChange |= UndoLRSpillRestore(); MadeChange |= UndoLRSpillRestore();
BBSizes.clear(); BBSizes.clear();

View File

@ -16,6 +16,7 @@
#include "ARMSubtarget.h" #include "ARMSubtarget.h"
#include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFunction.h"
#include "llvm/Target/MRegisterInfo.h"
#include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetMachine.h"
#include "llvm/ADT/BitVector.h" #include "llvm/ADT/BitVector.h"
@ -37,9 +38,9 @@ class ARMFunctionInfo : public MachineFunctionInfo {
/// processFunctionBeforeCalleeSavedScan(). /// processFunctionBeforeCalleeSavedScan().
bool HasStackFrame; bool HasStackFrame;
/// LRSForceSpilled - True if the LR register has been for spilled to enable /// LRSpilledForFarJump - True if the LR register has been for spilled to
/// far jump. /// enable far jump.
bool LRForceSpilled; bool LRSpilledForFarJump;
/// R3IsLiveIn - True if R3 is live in to this function. /// R3IsLiveIn - True if R3 is live in to this function.
/// FIXME: Remove when register scavenger for Thumb is done. /// FIXME: Remove when register scavenger for Thumb is done.
@ -73,6 +74,10 @@ class ARMFunctionInfo : public MachineFunctionInfo {
BitVector GPRCS2Frames; BitVector GPRCS2Frames;
BitVector DPRCSFrames; BitVector DPRCSFrames;
/// SpilledCSRegs - A BitVector mask of all spilled callee-saved registers.
///
BitVector SpilledCSRegs;
/// JumpTableUId - Unique id for jumptables. /// JumpTableUId - Unique id for jumptables.
/// ///
unsigned JumpTableUId; unsigned JumpTableUId;
@ -81,19 +86,20 @@ public:
ARMFunctionInfo() : ARMFunctionInfo() :
isThumb(false), isThumb(false),
VarArgsRegSaveSize(0), HasStackFrame(false), VarArgsRegSaveSize(0), HasStackFrame(false),
LRForceSpilled(false), R3IsLiveIn(false), LRSpilledForFarJump(false), R3IsLiveIn(false),
FramePtrSpillOffset(0), GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0), FramePtrSpillOffset(0), GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0),
GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0), GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0),
GPRCS1Frames(32), GPRCS2Frames(32), DPRCSFrames(32), GPRCS1Frames(0), GPRCS2Frames(0), DPRCSFrames(0),
JumpTableUId(0) {} JumpTableUId(0) {}
ARMFunctionInfo(MachineFunction &MF) : ARMFunctionInfo(MachineFunction &MF) :
isThumb(MF.getTarget().getSubtarget<ARMSubtarget>().isThumb()), isThumb(MF.getTarget().getSubtarget<ARMSubtarget>().isThumb()),
VarArgsRegSaveSize(0), HasStackFrame(false), VarArgsRegSaveSize(0), HasStackFrame(false),
LRForceSpilled(false), R3IsLiveIn(false), LRSpilledForFarJump(false), R3IsLiveIn(false),
FramePtrSpillOffset(0), GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0), FramePtrSpillOffset(0), GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0),
GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0), GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0),
GPRCS1Frames(32), GPRCS2Frames(32), DPRCSFrames(32), GPRCS1Frames(32), GPRCS2Frames(32), DPRCSFrames(32),
SpilledCSRegs(MF.getTarget().getRegisterInfo()->getNumRegs()),
JumpTableUId(0) {} JumpTableUId(0) {}
bool isThumbFunction() const { return isThumb; } bool isThumbFunction() const { return isThumb; }
@ -104,10 +110,11 @@ public:
bool hasStackFrame() const { return HasStackFrame; } bool hasStackFrame() const { return HasStackFrame; }
void setHasStackFrame(bool s) { HasStackFrame = s; } void setHasStackFrame(bool s) { HasStackFrame = s; }
bool isLRForceSpilled() const { return LRForceSpilled; } bool isLRSpilledForFarJump() const { return LRSpilledForFarJump; }
void setLRIsForceSpilled(bool s) { LRForceSpilled = s; } void setLRIsSpilledForFarJump(bool s) { LRSpilledForFarJump = s; }
bool isR3IsLiveIn() const { return R3IsLiveIn; } // FIXME: Remove when register scavenger for Thumb is done.
bool isR3LiveIn() const { return R3IsLiveIn; }
void setR3IsLiveIn(bool l) { R3IsLiveIn = l; } void setR3IsLiveIn(bool l) { R3IsLiveIn = l; }
unsigned getFramePtrSpillOffset() const { return FramePtrSpillOffset; } unsigned getFramePtrSpillOffset() const { return FramePtrSpillOffset; }
@ -182,6 +189,18 @@ public:
} }
} }
void setCSRegisterIsSpilled(unsigned Reg) {
SpilledCSRegs.set(Reg);
}
bool isCSRegisterSpilled(unsigned Reg) {
return SpilledCSRegs[Reg];
}
const BitVector &getSpilledCSRegisters() const {
return SpilledCSRegs;
}
unsigned createJumpTableUId() { unsigned createJumpTableUId() {
return JumpTableUId++; return JumpTableUId++;
} }

View File

@ -869,7 +869,7 @@ void ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
.addReg(ARM::R2, false, false, true); .addReg(ARM::R2, false, false, true);
TmpReg = ARM::R2; TmpReg = ARM::R2;
} }
if (TmpReg == ARM::R3 && AFI->isR3IsLiveIn()) if (TmpReg == ARM::R3 && AFI->isR3LiveIn())
BuildMI(MBB, II, TII.get(ARM::tMOVrr), ARM::R12) BuildMI(MBB, II, TII.get(ARM::tMOVrr), ARM::R12)
.addReg(ARM::R3, false, false, true); .addReg(ARM::R3, false, false, true);
if (Opcode == ARM::tSpill) { if (Opcode == ARM::tSpill) {
@ -892,7 +892,7 @@ void ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
if (ValReg == ARM::R3) if (ValReg == ARM::R3)
BuildMI(MBB, NII, TII.get(ARM::tMOVrr), ARM::R2) BuildMI(MBB, NII, TII.get(ARM::tMOVrr), ARM::R2)
.addReg(ARM::R12, false, false, true); .addReg(ARM::R12, false, false, true);
if (TmpReg == ARM::R3 && AFI->isR3IsLiveIn()) if (TmpReg == ARM::R3 && AFI->isR3LiveIn())
BuildMI(MBB, NII, TII.get(ARM::tMOVrr), ARM::R3) BuildMI(MBB, NII, TII.get(ARM::tMOVrr), ARM::R3)
.addReg(ARM::R12, false, false, true); .addReg(ARM::R12, false, false, true);
} else } else
@ -923,6 +923,7 @@ processFunctionBeforeCalleeSavedScan(MachineFunction &MF) const {
unsigned NumGPRSpills = 0; unsigned NumGPRSpills = 0;
SmallVector<unsigned, 4> UnspilledCS1GPRs; SmallVector<unsigned, 4> UnspilledCS1GPRs;
SmallVector<unsigned, 4> UnspilledCS2GPRs; SmallVector<unsigned, 4> UnspilledCS2GPRs;
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
// Don't spill FP if the frame can be eliminated. This is determined // Don't spill FP if the frame can be eliminated. This is determined
// by scanning the callee-save registers to see if any is used. // by scanning the callee-save registers to see if any is used.
@ -932,6 +933,7 @@ processFunctionBeforeCalleeSavedScan(MachineFunction &MF) const {
unsigned Reg = CSRegs[i]; unsigned Reg = CSRegs[i];
bool Spilled = false; bool Spilled = false;
if (MF.isPhysRegUsed(Reg)) { if (MF.isPhysRegUsed(Reg)) {
AFI->setCSRegisterIsSpilled(Reg);
Spilled = true; Spilled = true;
CanEliminateFrame = false; CanEliminateFrame = false;
} else { } else {
@ -992,13 +994,12 @@ processFunctionBeforeCalleeSavedScan(MachineFunction &MF) const {
} }
} }
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
bool ForceLRSpill = false; bool ForceLRSpill = false;
if (!LRSpilled && AFI->isThumbFunction()) { if (!LRSpilled && AFI->isThumbFunction()) {
unsigned FnSize = ARM::GetFunctionSize(MF); unsigned FnSize = ARM::GetFunctionSize(MF);
// Force LR spill if the Thumb function size is > 2048. This enables the // Force LR to be spilled if the Thumb function size is > 2048. This enables
// use of BL to implement far jump. If it turns out that it's not needed // use of BL to implement far jump. If it turns out that it's not needed
// the branch fix up path will undo it. // then the branch fix up path will undo it.
if (FnSize >= (1 << 11)) { if (FnSize >= (1 << 11)) {
CanEliminateFrame = false; CanEliminateFrame = false;
ForceLRSpill = true; ForceLRSpill = true;
@ -1012,6 +1013,7 @@ processFunctionBeforeCalleeSavedScan(MachineFunction &MF) const {
// Spill LR as well so we can fold BX_RET to the registers restore (LDM). // Spill LR as well so we can fold BX_RET to the registers restore (LDM).
if (!LRSpilled && CS1Spilled) { if (!LRSpilled && CS1Spilled) {
MF.changePhyRegUsed(ARM::LR, true); MF.changePhyRegUsed(ARM::LR, true);
AFI->setCSRegisterIsSpilled(ARM::LR);
NumGPRSpills++; NumGPRSpills++;
UnspilledCS1GPRs.erase(std::find(UnspilledCS1GPRs.begin(), UnspilledCS1GPRs.erase(std::find(UnspilledCS1GPRs.begin(),
UnspilledCS1GPRs.end(), (unsigned)ARM::LR)); UnspilledCS1GPRs.end(), (unsigned)ARM::LR));
@ -1030,16 +1032,22 @@ processFunctionBeforeCalleeSavedScan(MachineFunction &MF) const {
// the integer and double callee save areas. // the integer and double callee save areas.
unsigned TargetAlign = MF.getTarget().getFrameInfo()->getStackAlignment(); unsigned TargetAlign = MF.getTarget().getFrameInfo()->getStackAlignment();
if (TargetAlign == 8 && (NumGPRSpills & 1)) { if (TargetAlign == 8 && (NumGPRSpills & 1)) {
if (CS1Spilled && !UnspilledCS1GPRs.empty()) if (CS1Spilled && !UnspilledCS1GPRs.empty()) {
MF.changePhyRegUsed(UnspilledCS1GPRs.front(), true); unsigned Reg = UnspilledCS1GPRs.front();
else if (!UnspilledCS2GPRs.empty()) MF.changePhyRegUsed(Reg, true);
MF.changePhyRegUsed(UnspilledCS2GPRs.front(), true); AFI->setCSRegisterIsSpilled(Reg);
} else if (!UnspilledCS2GPRs.empty()) {
unsigned Reg = UnspilledCS2GPRs.front();
MF.changePhyRegUsed(Reg, true);
AFI->setCSRegisterIsSpilled(Reg);
}
} }
} }
if (ForceLRSpill) { if (ForceLRSpill) {
MF.changePhyRegUsed(ARM::LR, true); MF.changePhyRegUsed(ARM::LR, true);
AFI->setLRIsForceSpilled(true); AFI->setCSRegisterIsSpilled(ARM::LR);
AFI->setLRIsSpilledForFarJump(true);
} }
} }