mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-28 03:25:23 +00:00
Simplify ARM callee-saved register handling by removing the distinction
between the high and low registers for prologue/epilogue code. This was a Darwin-only thing that wasn't providing a realistic benefit anymore. Combining the save areas simplifies the compiler code and results in better ARM/Thumb2 codegen. For example, previously we would generate code like: push {r4, r5, r6, r7, lr} add r7, sp, #12 stmdb sp!, {r8, r10, r11} With this change, we combine the register saves and generate: push {r4, r5, r6, r7, r8, r10, r11, lr} add r7, sp, #12 rdar://8445635 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@114340 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -77,8 +77,8 @@ ARMBaseRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
|
|||||||
static const unsigned DarwinCalleeSavedRegs[] = {
|
static const unsigned DarwinCalleeSavedRegs[] = {
|
||||||
// Darwin ABI deviates from ARM standard ABI. R9 is not a callee-saved
|
// Darwin ABI deviates from ARM standard ABI. R9 is not a callee-saved
|
||||||
// register.
|
// register.
|
||||||
ARM::LR, ARM::R7, ARM::R6, ARM::R5, ARM::R4,
|
ARM::LR, ARM::R11, ARM::R10, ARM::R8,
|
||||||
ARM::R11, ARM::R10, ARM::R8,
|
ARM::R7, ARM::R6, ARM::R5, ARM::R4,
|
||||||
|
|
||||||
ARM::D15, ARM::D14, ARM::D13, ARM::D12,
|
ARM::D15, ARM::D14, ARM::D13, ARM::D12,
|
||||||
ARM::D11, ARM::D10, ARM::D9, ARM::D8,
|
ARM::D11, ARM::D10, ARM::D9, ARM::D8,
|
||||||
@@ -701,7 +701,6 @@ ARMBaseRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
|
|||||||
bool LRSpilled = false;
|
bool LRSpilled = false;
|
||||||
unsigned NumGPRSpills = 0;
|
unsigned NumGPRSpills = 0;
|
||||||
SmallVector<unsigned, 4> UnspilledCS1GPRs;
|
SmallVector<unsigned, 4> UnspilledCS1GPRs;
|
||||||
SmallVector<unsigned, 4> UnspilledCS2GPRs;
|
|
||||||
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
|
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
|
||||||
MachineFrameInfo *MFI = MF.getFrameInfo();
|
MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||||
|
|
||||||
@@ -768,23 +767,7 @@ ARMBaseRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!STI.isTargetDarwin()) {
|
UnspilledCS1GPRs.push_back(Reg);
|
||||||
UnspilledCS1GPRs.push_back(Reg);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (Reg) {
|
|
||||||
case ARM::R4:
|
|
||||||
case ARM::R5:
|
|
||||||
case ARM::R6:
|
|
||||||
case ARM::R7:
|
|
||||||
case ARM::LR:
|
|
||||||
UnspilledCS1GPRs.push_back(Reg);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
UnspilledCS2GPRs.push_back(Reg);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -860,13 +843,6 @@ ARMBaseRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (!UnspilledCS2GPRs.empty() &&
|
|
||||||
!AFI->isThumb1OnlyFunction()) {
|
|
||||||
unsigned Reg = UnspilledCS2GPRs.front();
|
|
||||||
MF.getRegInfo().setPhysRegUsed(Reg);
|
|
||||||
AFI->setCSRegisterIsSpilled(Reg);
|
|
||||||
if (!isReservedReg(MF, Reg))
|
|
||||||
ExtraCSSpill = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -890,17 +866,6 @@ ARMBaseRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
|
|||||||
NumExtras--;
|
NumExtras--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// For non-Thumb1 functions, also check for hi-reg CS registers
|
|
||||||
if (!AFI->isThumb1OnlyFunction()) {
|
|
||||||
while (NumExtras && !UnspilledCS2GPRs.empty()) {
|
|
||||||
unsigned Reg = UnspilledCS2GPRs.back();
|
|
||||||
UnspilledCS2GPRs.pop_back();
|
|
||||||
if (!isReservedReg(MF, Reg)) {
|
|
||||||
Extras.push_back(Reg);
|
|
||||||
NumExtras--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Extras.size() && NumExtras == 0) {
|
if (Extras.size() && NumExtras == 0) {
|
||||||
for (unsigned i = 0, e = Extras.size(); i != e; ++i) {
|
for (unsigned i = 0, e = Extras.size(); i != e; ++i) {
|
||||||
MF.getRegInfo().setPhysRegUsed(Extras[i]);
|
MF.getRegInfo().setPhysRegUsed(Extras[i]);
|
||||||
@@ -958,10 +923,8 @@ ARMBaseRegisterInfo::ResolveFrameIndexReference(const MachineFunction &MF,
|
|||||||
|
|
||||||
FrameReg = ARM::SP;
|
FrameReg = ARM::SP;
|
||||||
Offset += SPAdj;
|
Offset += SPAdj;
|
||||||
if (AFI->isGPRCalleeSavedArea1Frame(FI))
|
if (AFI->isGPRCalleeSavedAreaFrame(FI))
|
||||||
return Offset - AFI->getGPRCalleeSavedArea1Offset();
|
return Offset - AFI->getGPRCalleeSavedAreaOffset();
|
||||||
else if (AFI->isGPRCalleeSavedArea2Frame(FI))
|
|
||||||
return Offset - AFI->getGPRCalleeSavedArea2Offset();
|
|
||||||
else if (AFI->isDPRCalleeSavedAreaFrame(FI))
|
else if (AFI->isDPRCalleeSavedAreaFrame(FI))
|
||||||
return Offset - AFI->getDPRCalleeSavedAreaOffset();
|
return Offset - AFI->getDPRCalleeSavedAreaOffset();
|
||||||
|
|
||||||
@@ -1651,8 +1614,7 @@ ARMBaseRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Move iterator past the next bunch of callee save load / store ops for
|
/// Move iterator past the next bunch of callee save load / store ops for
|
||||||
/// the particular spill area (1: integer area 1, 2: integer area 2,
|
/// the particular spill area (1: integer area 1, 2: fp area, 0: don't care).
|
||||||
/// 3: fp area, 0: don't care).
|
|
||||||
static void movePastCSLoadStoreOps(MachineBasicBlock &MBB,
|
static void movePastCSLoadStoreOps(MachineBasicBlock &MBB,
|
||||||
MachineBasicBlock::iterator &MBBI,
|
MachineBasicBlock::iterator &MBBI,
|
||||||
int Opc1, int Opc2, unsigned Area,
|
int Opc1, int Opc2, unsigned Area,
|
||||||
@@ -1665,15 +1627,13 @@ static void movePastCSLoadStoreOps(MachineBasicBlock &MBB,
|
|||||||
unsigned Category = 0;
|
unsigned Category = 0;
|
||||||
switch (MBBI->getOperand(0).getReg()) {
|
switch (MBBI->getOperand(0).getReg()) {
|
||||||
case ARM::R4: case ARM::R5: case ARM::R6: case ARM::R7:
|
case ARM::R4: case ARM::R5: case ARM::R6: case ARM::R7:
|
||||||
|
case ARM::R8: case ARM::R9: case ARM::R10: case ARM::R11:
|
||||||
case ARM::LR:
|
case ARM::LR:
|
||||||
Category = 1;
|
Category = 1;
|
||||||
break;
|
break;
|
||||||
case ARM::R8: case ARM::R9: case ARM::R10: case ARM::R11:
|
|
||||||
Category = STI.isTargetDarwin() ? 2 : 1;
|
|
||||||
break;
|
|
||||||
case ARM::D8: case ARM::D9: case ARM::D10: case ARM::D11:
|
case ARM::D8: case ARM::D9: case ARM::D10: case ARM::D11:
|
||||||
case ARM::D12: case ARM::D13: case ARM::D14: case ARM::D15:
|
case ARM::D12: case ARM::D13: case ARM::D14: case ARM::D15:
|
||||||
Category = 3;
|
Category = 2;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Done = true;
|
Done = true;
|
||||||
@@ -1703,7 +1663,7 @@ emitPrologue(MachineFunction &MF) const {
|
|||||||
|
|
||||||
// Determine the sizes of each callee-save spill areas and record which frame
|
// Determine the sizes of each callee-save spill areas and record which frame
|
||||||
// belongs to which callee-save spill areas.
|
// belongs to which callee-save spill areas.
|
||||||
unsigned GPRCS1Size = 0, GPRCS2Size = 0, DPRCSSize = 0;
|
unsigned GPRCSSize = 0/*, GPRCS2Size = 0*/, DPRCSSize = 0;
|
||||||
int FramePtrSpillFI = 0;
|
int FramePtrSpillFI = 0;
|
||||||
|
|
||||||
// Allocate the vararg register save area. This is not counted in NumBytes.
|
// Allocate the vararg register save area. This is not counted in NumBytes.
|
||||||
@@ -1724,25 +1684,15 @@ emitPrologue(MachineFunction &MF) const {
|
|||||||
case ARM::R5:
|
case ARM::R5:
|
||||||
case ARM::R6:
|
case ARM::R6:
|
||||||
case ARM::R7:
|
case ARM::R7:
|
||||||
case ARM::LR:
|
|
||||||
if (Reg == FramePtr)
|
|
||||||
FramePtrSpillFI = FI;
|
|
||||||
AFI->addGPRCalleeSavedArea1Frame(FI);
|
|
||||||
GPRCS1Size += 4;
|
|
||||||
break;
|
|
||||||
case ARM::R8:
|
case ARM::R8:
|
||||||
case ARM::R9:
|
case ARM::R9:
|
||||||
case ARM::R10:
|
case ARM::R10:
|
||||||
case ARM::R11:
|
case ARM::R11:
|
||||||
|
case ARM::LR:
|
||||||
if (Reg == FramePtr)
|
if (Reg == FramePtr)
|
||||||
FramePtrSpillFI = FI;
|
FramePtrSpillFI = FI;
|
||||||
if (STI.isTargetDarwin()) {
|
AFI->addGPRCalleeSavedAreaFrame(FI);
|
||||||
AFI->addGPRCalleeSavedArea2Frame(FI);
|
GPRCSSize += 4;
|
||||||
GPRCS2Size += 4;
|
|
||||||
} else {
|
|
||||||
AFI->addGPRCalleeSavedArea1Frame(FI);
|
|
||||||
GPRCS1Size += 4;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
AFI->addDPRCalleeSavedAreaFrame(FI);
|
AFI->addDPRCalleeSavedAreaFrame(FI);
|
||||||
@@ -1750,15 +1700,11 @@ emitPrologue(MachineFunction &MF) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build the new SUBri to adjust SP for integer callee-save spill area 1.
|
// Build the new SUBri to adjust SP for integer callee-save spill area.
|
||||||
emitSPUpdate(isARM, MBB, MBBI, dl, TII, -GPRCS1Size);
|
emitSPUpdate(isARM, MBB, MBBI, dl, TII, -GPRCSSize);
|
||||||
movePastCSLoadStoreOps(MBB, MBBI, ARM::STR, ARM::t2STRi12, 1, STI);
|
movePastCSLoadStoreOps(MBB, MBBI, ARM::STR, ARM::t2STRi12, 1, STI);
|
||||||
|
|
||||||
// Set FP to point to the stack slot that contains the previous FP.
|
// Set FP to point to the stack slot that contains the previous FP.
|
||||||
// For Darwin, FP is R7, which has now been stored in spill area 1.
|
|
||||||
// Otherwise, if this is not Darwin, all the callee-saved registers go
|
|
||||||
// into spill area 1, including the FP in R11. In either case, it is
|
|
||||||
// now safe to emit this assignment.
|
|
||||||
bool HasFP = hasFP(MF);
|
bool HasFP = hasFP(MF);
|
||||||
if (HasFP) {
|
if (HasFP) {
|
||||||
unsigned ADDriOpc = !AFI->isThumbFunction() ? ARM::ADDri : ARM::t2ADDri;
|
unsigned ADDriOpc = !AFI->isThumbFunction() ? ARM::ADDri : ARM::t2ADDri;
|
||||||
@@ -1768,25 +1714,19 @@ emitPrologue(MachineFunction &MF) const {
|
|||||||
AddDefaultCC(AddDefaultPred(MIB));
|
AddDefaultCC(AddDefaultPred(MIB));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build the new SUBri to adjust SP for integer callee-save spill area 2.
|
|
||||||
emitSPUpdate(isARM, MBB, MBBI, dl, TII, -GPRCS2Size);
|
|
||||||
|
|
||||||
// Build the new SUBri to adjust SP for FP callee-save spill area.
|
// Build the new SUBri to adjust SP for FP callee-save spill area.
|
||||||
movePastCSLoadStoreOps(MBB, MBBI, ARM::STR, ARM::t2STRi12, 2, STI);
|
|
||||||
emitSPUpdate(isARM, MBB, MBBI, dl, TII, -DPRCSSize);
|
emitSPUpdate(isARM, MBB, MBBI, dl, TII, -DPRCSSize);
|
||||||
|
|
||||||
// Determine starting offsets of spill areas.
|
// Determine starting offsets of spill areas.
|
||||||
unsigned DPRCSOffset = NumBytes - (GPRCS1Size + GPRCS2Size + DPRCSSize);
|
unsigned DPRCSOffset = NumBytes - (GPRCSSize + DPRCSSize);
|
||||||
unsigned GPRCS2Offset = DPRCSOffset + DPRCSSize;
|
unsigned GPRCSOffset = DPRCSOffset + DPRCSSize;
|
||||||
unsigned GPRCS1Offset = GPRCS2Offset + GPRCS2Size;
|
|
||||||
if (HasFP)
|
if (HasFP)
|
||||||
AFI->setFramePtrSpillOffset(MFI->getObjectOffset(FramePtrSpillFI) +
|
AFI->setFramePtrSpillOffset(MFI->getObjectOffset(FramePtrSpillFI) +
|
||||||
NumBytes);
|
NumBytes);
|
||||||
AFI->setGPRCalleeSavedArea1Offset(GPRCS1Offset);
|
AFI->setGPRCalleeSavedAreaOffset(GPRCSOffset);
|
||||||
AFI->setGPRCalleeSavedArea2Offset(GPRCS2Offset);
|
|
||||||
AFI->setDPRCalleeSavedAreaOffset(DPRCSOffset);
|
AFI->setDPRCalleeSavedAreaOffset(DPRCSOffset);
|
||||||
|
|
||||||
movePastCSLoadStoreOps(MBB, MBBI, ARM::VSTRD, 0, 3, STI);
|
movePastCSLoadStoreOps(MBB, MBBI, ARM::VSTRD, 0, 2, STI);
|
||||||
NumBytes = DPRCSOffset;
|
NumBytes = DPRCSOffset;
|
||||||
if (NumBytes) {
|
if (NumBytes) {
|
||||||
// Adjust SP after all the callee-save spills.
|
// Adjust SP after all the callee-save spills.
|
||||||
@@ -1801,8 +1741,7 @@ emitPrologue(MachineFunction &MF) const {
|
|||||||
AFI->setShouldRestoreSPFromFP(true);
|
AFI->setShouldRestoreSPFromFP(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
AFI->setGPRCalleeSavedArea1Size(GPRCS1Size);
|
AFI->setGPRCalleeSavedAreaSize(GPRCSSize);
|
||||||
AFI->setGPRCalleeSavedArea2Size(GPRCS2Size);
|
|
||||||
AFI->setDPRCalleeSavedAreaSize(DPRCSSize);
|
AFI->setDPRCalleeSavedAreaSize(DPRCSSize);
|
||||||
|
|
||||||
// If we need dynamic stack realignment, do it here. Be paranoid and make
|
// If we need dynamic stack realignment, do it here. Be paranoid and make
|
||||||
@@ -1904,8 +1843,7 @@ emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Move SP to start of FP callee save spill area.
|
// Move SP to start of FP callee save spill area.
|
||||||
NumBytes -= (AFI->getGPRCalleeSavedArea1Size() +
|
NumBytes -= (AFI->getGPRCalleeSavedAreaSize() +
|
||||||
AFI->getGPRCalleeSavedArea2Size() +
|
|
||||||
AFI->getDPRCalleeSavedAreaSize());
|
AFI->getDPRCalleeSavedAreaSize());
|
||||||
|
|
||||||
// Reset SP based on frame pointer only if the stack frame extends beyond
|
// Reset SP based on frame pointer only if the stack frame extends beyond
|
||||||
@@ -1931,17 +1869,13 @@ emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const {
|
|||||||
} else if (NumBytes)
|
} else if (NumBytes)
|
||||||
emitSPUpdate(isARM, MBB, MBBI, dl, TII, NumBytes);
|
emitSPUpdate(isARM, MBB, MBBI, dl, TII, NumBytes);
|
||||||
|
|
||||||
// Move SP to start of integer callee save spill area 2.
|
// Move SP to start of integer callee save spill area.
|
||||||
movePastCSLoadStoreOps(MBB, MBBI, ARM::VLDRD, 0, 3, STI);
|
movePastCSLoadStoreOps(MBB, MBBI, ARM::VLDRD, 0, 2, STI);
|
||||||
emitSPUpdate(isARM, MBB, MBBI, dl, TII, AFI->getDPRCalleeSavedAreaSize());
|
emitSPUpdate(isARM, MBB, MBBI, dl, TII, AFI->getDPRCalleeSavedAreaSize());
|
||||||
|
|
||||||
// Move SP to start of integer callee save spill area 1.
|
|
||||||
movePastCSLoadStoreOps(MBB, MBBI, ARM::LDR, ARM::t2LDRi12, 2, STI);
|
|
||||||
emitSPUpdate(isARM, MBB, MBBI, dl, TII, AFI->getGPRCalleeSavedArea2Size());
|
|
||||||
|
|
||||||
// Move SP to SP upon entry to the function.
|
// Move SP to SP upon entry to the function.
|
||||||
movePastCSLoadStoreOps(MBB, MBBI, ARM::LDR, ARM::t2LDRi12, 1, STI);
|
movePastCSLoadStoreOps(MBB, MBBI, ARM::LDR, ARM::t2LDRi12, 1, STI);
|
||||||
emitSPUpdate(isARM, MBB, MBBI, dl, TII, AFI->getGPRCalleeSavedArea1Size());
|
emitSPUpdate(isARM, MBB, MBBI, dl, TII, AFI->getGPRCalleeSavedAreaSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RetOpcode == ARM::TCRETURNdi || RetOpcode == ARM::TCRETURNdiND ||
|
if (RetOpcode == ARM::TCRETURNdi || RetOpcode == ARM::TCRETURNdiND ||
|
||||||
|
@@ -55,28 +55,23 @@ class ARMFunctionInfo : public MachineFunctionInfo {
|
|||||||
/// spill stack offset.
|
/// spill stack offset.
|
||||||
unsigned FramePtrSpillOffset;
|
unsigned FramePtrSpillOffset;
|
||||||
|
|
||||||
/// GPRCS1Offset, GPRCS2Offset, DPRCSOffset - Starting offset of callee saved
|
/// GPRCSOffset, GPRCS2Offset, DPRCSOffset - Starting offset of callee saved
|
||||||
/// register spills areas. For Mac OS X:
|
/// register spills areas (excluding R9 for Mac OS X):
|
||||||
///
|
///
|
||||||
/// GPR callee-saved (1) : r4, r5, r6, r7, lr
|
/// GPR callee-saved (1) : r4, r5, r6, r7, r8, r9, r10, r11, lr
|
||||||
/// --------------------------------------------
|
|
||||||
/// GPR callee-saved (2) : r8, r10, r11
|
|
||||||
/// --------------------------------------------
|
/// --------------------------------------------
|
||||||
/// DPR callee-saved : d8 - d15
|
/// DPR callee-saved : d8 - d15
|
||||||
unsigned GPRCS1Offset;
|
unsigned GPRCSOffset;
|
||||||
unsigned GPRCS2Offset;
|
|
||||||
unsigned DPRCSOffset;
|
unsigned DPRCSOffset;
|
||||||
|
|
||||||
/// GPRCS1Size, GPRCS2Size, DPRCSSize - Sizes of callee saved register spills
|
/// GPRCSSize, GPRCS2Size, DPRCSSize - Sizes of callee saved register spills
|
||||||
/// areas.
|
/// areas.
|
||||||
unsigned GPRCS1Size;
|
unsigned GPRCSSize;
|
||||||
unsigned GPRCS2Size;
|
|
||||||
unsigned DPRCSSize;
|
unsigned DPRCSSize;
|
||||||
|
|
||||||
/// GPRCS1Frames, GPRCS2Frames, DPRCSFrames - Keeps track of frame indices
|
/// GPRCSFrames, GPRCS2Frames, DPRCSFrames - Keeps track of frame indices
|
||||||
/// which belong to these spill areas.
|
/// which belong to these spill areas.
|
||||||
BitVector GPRCS1Frames;
|
BitVector GPRCSFrames;
|
||||||
BitVector GPRCS2Frames;
|
|
||||||
BitVector DPRCSFrames;
|
BitVector DPRCSFrames;
|
||||||
|
|
||||||
/// SpilledCSRegs - A BitVector mask of all spilled callee-saved registers.
|
/// SpilledCSRegs - A BitVector mask of all spilled callee-saved registers.
|
||||||
@@ -101,9 +96,9 @@ public:
|
|||||||
hasThumb2(false),
|
hasThumb2(false),
|
||||||
VarArgsRegSaveSize(0), HasStackFrame(false), RestoreSPFromFP(false),
|
VarArgsRegSaveSize(0), HasStackFrame(false), RestoreSPFromFP(false),
|
||||||
LRSpilledForFarJump(false),
|
LRSpilledForFarJump(false),
|
||||||
FramePtrSpillOffset(0), GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0),
|
FramePtrSpillOffset(0), GPRCSOffset(0), DPRCSOffset(0),
|
||||||
GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0),
|
GPRCSSize(0), DPRCSSize(0),
|
||||||
GPRCS1Frames(0), GPRCS2Frames(0), DPRCSFrames(0),
|
GPRCSFrames(0), DPRCSFrames(0),
|
||||||
JumpTableUId(0), ConstPoolEntryUId(0), VarArgsFrameIndex(0),
|
JumpTableUId(0), ConstPoolEntryUId(0), VarArgsFrameIndex(0),
|
||||||
HasITBlocks(false) {}
|
HasITBlocks(false) {}
|
||||||
|
|
||||||
@@ -112,9 +107,9 @@ public:
|
|||||||
hasThumb2(MF.getTarget().getSubtarget<ARMSubtarget>().hasThumb2()),
|
hasThumb2(MF.getTarget().getSubtarget<ARMSubtarget>().hasThumb2()),
|
||||||
VarArgsRegSaveSize(0), HasStackFrame(false), RestoreSPFromFP(false),
|
VarArgsRegSaveSize(0), HasStackFrame(false), RestoreSPFromFP(false),
|
||||||
LRSpilledForFarJump(false),
|
LRSpilledForFarJump(false),
|
||||||
FramePtrSpillOffset(0), GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0),
|
FramePtrSpillOffset(0), GPRCSOffset(0), DPRCSOffset(0),
|
||||||
GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0),
|
GPRCSSize(0), DPRCSSize(0),
|
||||||
GPRCS1Frames(32), GPRCS2Frames(32), DPRCSFrames(32),
|
GPRCSFrames(32), DPRCSFrames(32),
|
||||||
SpilledCSRegs(MF.getTarget().getRegisterInfo()->getNumRegs()),
|
SpilledCSRegs(MF.getTarget().getRegisterInfo()->getNumRegs()),
|
||||||
JumpTableUId(0), ConstPoolEntryUId(0), VarArgsFrameIndex(0),
|
JumpTableUId(0), ConstPoolEntryUId(0), VarArgsFrameIndex(0),
|
||||||
HasITBlocks(false) {}
|
HasITBlocks(false) {}
|
||||||
@@ -138,31 +133,22 @@ public:
|
|||||||
unsigned getFramePtrSpillOffset() const { return FramePtrSpillOffset; }
|
unsigned getFramePtrSpillOffset() const { return FramePtrSpillOffset; }
|
||||||
void setFramePtrSpillOffset(unsigned o) { FramePtrSpillOffset = o; }
|
void setFramePtrSpillOffset(unsigned o) { FramePtrSpillOffset = o; }
|
||||||
|
|
||||||
unsigned getGPRCalleeSavedArea1Offset() const { return GPRCS1Offset; }
|
unsigned getGPRCalleeSavedAreaOffset() const { return GPRCSOffset; }
|
||||||
unsigned getGPRCalleeSavedArea2Offset() const { return GPRCS2Offset; }
|
|
||||||
unsigned getDPRCalleeSavedAreaOffset() const { return DPRCSOffset; }
|
unsigned getDPRCalleeSavedAreaOffset() const { return DPRCSOffset; }
|
||||||
|
|
||||||
void setGPRCalleeSavedArea1Offset(unsigned o) { GPRCS1Offset = o; }
|
void setGPRCalleeSavedAreaOffset(unsigned o) { GPRCSOffset = o; }
|
||||||
void setGPRCalleeSavedArea2Offset(unsigned o) { GPRCS2Offset = o; }
|
|
||||||
void setDPRCalleeSavedAreaOffset(unsigned o) { DPRCSOffset = o; }
|
void setDPRCalleeSavedAreaOffset(unsigned o) { DPRCSOffset = o; }
|
||||||
|
|
||||||
unsigned getGPRCalleeSavedArea1Size() const { return GPRCS1Size; }
|
unsigned getGPRCalleeSavedAreaSize() const { return GPRCSSize; }
|
||||||
unsigned getGPRCalleeSavedArea2Size() const { return GPRCS2Size; }
|
|
||||||
unsigned getDPRCalleeSavedAreaSize() const { return DPRCSSize; }
|
unsigned getDPRCalleeSavedAreaSize() const { return DPRCSSize; }
|
||||||
|
|
||||||
void setGPRCalleeSavedArea1Size(unsigned s) { GPRCS1Size = s; }
|
void setGPRCalleeSavedAreaSize(unsigned s) { GPRCSSize = s; }
|
||||||
void setGPRCalleeSavedArea2Size(unsigned s) { GPRCS2Size = s; }
|
|
||||||
void setDPRCalleeSavedAreaSize(unsigned s) { DPRCSSize = s; }
|
void setDPRCalleeSavedAreaSize(unsigned s) { DPRCSSize = s; }
|
||||||
|
|
||||||
bool isGPRCalleeSavedArea1Frame(int fi) const {
|
bool isGPRCalleeSavedAreaFrame(int fi) const {
|
||||||
if (fi < 0 || fi >= (int)GPRCS1Frames.size())
|
if (fi < 0 || fi >= (int)GPRCSFrames.size())
|
||||||
return false;
|
return false;
|
||||||
return GPRCS1Frames[fi];
|
return GPRCSFrames[fi];
|
||||||
}
|
|
||||||
bool isGPRCalleeSavedArea2Frame(int fi) const {
|
|
||||||
if (fi < 0 || fi >= (int)GPRCS2Frames.size())
|
|
||||||
return false;
|
|
||||||
return GPRCS2Frames[fi];
|
|
||||||
}
|
}
|
||||||
bool isDPRCalleeSavedAreaFrame(int fi) const {
|
bool isDPRCalleeSavedAreaFrame(int fi) const {
|
||||||
if (fi < 0 || fi >= (int)DPRCSFrames.size())
|
if (fi < 0 || fi >= (int)DPRCSFrames.size())
|
||||||
@@ -170,28 +156,16 @@ public:
|
|||||||
return DPRCSFrames[fi];
|
return DPRCSFrames[fi];
|
||||||
}
|
}
|
||||||
|
|
||||||
void addGPRCalleeSavedArea1Frame(int fi) {
|
void addGPRCalleeSavedAreaFrame(int fi) {
|
||||||
if (fi >= 0) {
|
if (fi >= 0) {
|
||||||
int Size = GPRCS1Frames.size();
|
int Size = GPRCSFrames.size();
|
||||||
if (fi >= Size) {
|
if (fi >= Size) {
|
||||||
Size *= 2;
|
Size *= 2;
|
||||||
if (fi >= Size)
|
if (fi >= Size)
|
||||||
Size = fi+1;
|
Size = fi+1;
|
||||||
GPRCS1Frames.resize(Size);
|
GPRCSFrames.resize(Size);
|
||||||
}
|
}
|
||||||
GPRCS1Frames[fi] = true;
|
GPRCSFrames[fi] = true;
|
||||||
}
|
|
||||||
}
|
|
||||||
void addGPRCalleeSavedArea2Frame(int fi) {
|
|
||||||
if (fi >= 0) {
|
|
||||||
int Size = GPRCS2Frames.size();
|
|
||||||
if (fi >= Size) {
|
|
||||||
Size *= 2;
|
|
||||||
if (fi >= Size)
|
|
||||||
Size = fi+1;
|
|
||||||
GPRCS2Frames.resize(Size);
|
|
||||||
}
|
|
||||||
GPRCS2Frames[fi] = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void addDPRCalleeSavedAreaFrame(int fi) {
|
void addDPRCalleeSavedAreaFrame(int fi) {
|
||||||
|
@@ -597,10 +597,8 @@ Thumb1RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
|
|||||||
int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) +
|
int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) +
|
||||||
MF.getFrameInfo()->getStackSize() + SPAdj;
|
MF.getFrameInfo()->getStackSize() + SPAdj;
|
||||||
|
|
||||||
if (AFI->isGPRCalleeSavedArea1Frame(FrameIndex))
|
if (AFI->isGPRCalleeSavedAreaFrame(FrameIndex))
|
||||||
Offset -= AFI->getGPRCalleeSavedArea1Offset();
|
Offset -= AFI->getGPRCalleeSavedAreaOffset();
|
||||||
else if (AFI->isGPRCalleeSavedArea2Frame(FrameIndex))
|
|
||||||
Offset -= AFI->getGPRCalleeSavedArea2Offset();
|
|
||||||
else if (MF.getFrameInfo()->hasVarSizedObjects()) {
|
else if (MF.getFrameInfo()->hasVarSizedObjects()) {
|
||||||
assert(SPAdj == 0 && hasFP(MF) && "Unexpected");
|
assert(SPAdj == 0 && hasFP(MF) && "Unexpected");
|
||||||
// There are alloca()'s in this function, must reference off the frame
|
// There are alloca()'s in this function, must reference off the frame
|
||||||
@@ -709,7 +707,7 @@ void Thumb1RegisterInfo::emitPrologue(MachineFunction &MF) const {
|
|||||||
|
|
||||||
// Determine the sizes of each callee-save spill areas and record which frame
|
// Determine the sizes of each callee-save spill areas and record which frame
|
||||||
// belongs to which callee-save spill areas.
|
// belongs to which callee-save spill areas.
|
||||||
unsigned GPRCS1Size = 0, GPRCS2Size = 0, DPRCSSize = 0;
|
unsigned GPRCSSize = 0, DPRCSSize = 0;
|
||||||
int FramePtrSpillFI = 0;
|
int FramePtrSpillFI = 0;
|
||||||
|
|
||||||
if (VARegSaveSize)
|
if (VARegSaveSize)
|
||||||
@@ -729,25 +727,15 @@ void Thumb1RegisterInfo::emitPrologue(MachineFunction &MF) const {
|
|||||||
case ARM::R5:
|
case ARM::R5:
|
||||||
case ARM::R6:
|
case ARM::R6:
|
||||||
case ARM::R7:
|
case ARM::R7:
|
||||||
case ARM::LR:
|
|
||||||
if (Reg == FramePtr)
|
|
||||||
FramePtrSpillFI = FI;
|
|
||||||
AFI->addGPRCalleeSavedArea1Frame(FI);
|
|
||||||
GPRCS1Size += 4;
|
|
||||||
break;
|
|
||||||
case ARM::R8:
|
case ARM::R8:
|
||||||
case ARM::R9:
|
case ARM::R9:
|
||||||
case ARM::R10:
|
case ARM::R10:
|
||||||
case ARM::R11:
|
case ARM::R11:
|
||||||
|
case ARM::LR:
|
||||||
if (Reg == FramePtr)
|
if (Reg == FramePtr)
|
||||||
FramePtrSpillFI = FI;
|
FramePtrSpillFI = FI;
|
||||||
if (STI.isTargetDarwin()) {
|
AFI->addGPRCalleeSavedAreaFrame(FI);
|
||||||
AFI->addGPRCalleeSavedArea2Frame(FI);
|
GPRCSSize += 4;
|
||||||
GPRCS2Size += 4;
|
|
||||||
} else {
|
|
||||||
AFI->addGPRCalleeSavedArea1Frame(FI);
|
|
||||||
GPRCS1Size += 4;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
AFI->addDPRCalleeSavedAreaFrame(FI);
|
AFI->addDPRCalleeSavedAreaFrame(FI);
|
||||||
@@ -769,12 +757,10 @@ void Thumb1RegisterInfo::emitPrologue(MachineFunction &MF) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Determine starting offsets of spill areas.
|
// Determine starting offsets of spill areas.
|
||||||
unsigned DPRCSOffset = NumBytes - (GPRCS1Size + GPRCS2Size + DPRCSSize);
|
unsigned DPRCSOffset = NumBytes - (GPRCSSize + DPRCSSize);
|
||||||
unsigned GPRCS2Offset = DPRCSOffset + DPRCSSize;
|
unsigned GPRCSOffset = DPRCSOffset + DPRCSSize;
|
||||||
unsigned GPRCS1Offset = GPRCS2Offset + GPRCS2Size;
|
|
||||||
AFI->setFramePtrSpillOffset(MFI->getObjectOffset(FramePtrSpillFI) + NumBytes);
|
AFI->setFramePtrSpillOffset(MFI->getObjectOffset(FramePtrSpillFI) + NumBytes);
|
||||||
AFI->setGPRCalleeSavedArea1Offset(GPRCS1Offset);
|
AFI->setGPRCalleeSavedAreaOffset(GPRCSOffset);
|
||||||
AFI->setGPRCalleeSavedArea2Offset(GPRCS2Offset);
|
|
||||||
AFI->setDPRCalleeSavedAreaOffset(DPRCSOffset);
|
AFI->setDPRCalleeSavedAreaOffset(DPRCSOffset);
|
||||||
|
|
||||||
NumBytes = DPRCSOffset;
|
NumBytes = DPRCSOffset;
|
||||||
@@ -787,8 +773,7 @@ void Thumb1RegisterInfo::emitPrologue(MachineFunction &MF) const {
|
|||||||
MFI->setOffsetAdjustment(MFI->getOffsetAdjustment() -
|
MFI->setOffsetAdjustment(MFI->getOffsetAdjustment() -
|
||||||
AFI->getFramePtrSpillOffset());
|
AFI->getFramePtrSpillOffset());
|
||||||
|
|
||||||
AFI->setGPRCalleeSavedArea1Size(GPRCS1Size);
|
AFI->setGPRCalleeSavedAreaSize(GPRCSSize);
|
||||||
AFI->setGPRCalleeSavedArea2Size(GPRCS2Size);
|
|
||||||
AFI->setDPRCalleeSavedAreaSize(DPRCSSize);
|
AFI->setDPRCalleeSavedAreaSize(DPRCSSize);
|
||||||
|
|
||||||
// If we need a base pointer, set it up here. It's whatever the value
|
// If we need a base pointer, set it up here. It's whatever the value
|
||||||
@@ -849,8 +834,7 @@ void Thumb1RegisterInfo::emitEpilogue(MachineFunction &MF,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Move SP to start of FP callee save spill area.
|
// Move SP to start of FP callee save spill area.
|
||||||
NumBytes -= (AFI->getGPRCalleeSavedArea1Size() +
|
NumBytes -= (AFI->getGPRCalleeSavedAreaSize() +
|
||||||
AFI->getGPRCalleeSavedArea2Size() +
|
|
||||||
AFI->getDPRCalleeSavedAreaSize());
|
AFI->getDPRCalleeSavedAreaSize());
|
||||||
|
|
||||||
if (AFI->shouldRestoreSPFromFP()) {
|
if (AFI->shouldRestoreSPFromFP()) {
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -stats |& grep {38.*Number of machine instrs printed}
|
; RUN: llc < %s -stats |& grep {36.*Number of machine instrs printed}
|
||||||
; RUN: llc < %s -stats |& not grep {.*Number of re-materialization}
|
; RUN: llc < %s -stats |& not grep {.*Number of re-materialization}
|
||||||
; This test really wants to check that the resultant "cond_true" block only
|
; This test really wants to check that the resultant "cond_true" block only
|
||||||
; has a single store in it, and that cond_true55 only has code to materialize
|
; has a single store in it, and that cond_true55 only has code to materialize
|
||||||
|
@@ -32,15 +32,14 @@
|
|||||||
|
|
||||||
define fastcc i32 @parse_percent_token() nounwind {
|
define fastcc i32 @parse_percent_token() nounwind {
|
||||||
entry:
|
entry:
|
||||||
; CHECK: ittt eq
|
; CHECK: itt eq
|
||||||
; CHECK: ittt eq
|
; CHECK: itt eq
|
||||||
; CHECK: ittt eq
|
; CHECK: itt eq
|
||||||
; CHECK: ittt eq
|
; CHECK: itt eq
|
||||||
; CHECK: ittt eq
|
; CHECK: itt eq
|
||||||
; CHECK: moveq r0
|
; CHECK: moveq r0
|
||||||
; CHECK-NOT: LBB0_
|
; CHECK-NOT: LBB0_
|
||||||
; CHECK: ldreq
|
; CHECK: ldmiaeq
|
||||||
; CHECK: popeq
|
|
||||||
switch i32 undef, label %bb7 [
|
switch i32 undef, label %bb7 [
|
||||||
i32 37, label %bb43
|
i32 37, label %bb43
|
||||||
i32 48, label %bb5
|
i32 48, label %bb5
|
||||||
|
Reference in New Issue
Block a user