mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-06 03:08:43 +00:00
- Track which callee-saved registers are spilled.
- Some code clean up. llvm-svn: 34783
This commit is contained in:
parent
3f3487918c
commit
8d3d4155e5
@ -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();
|
||||||
|
@ -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++;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user