Skip to content

Commit 8eac8cc

Browse files
committed
[ARM] Refactor generation of push/pop instructions (NFC)
These used a set of callback functions to check which callee-save area a register is in, refactor them to use the same data as other parts of ARMFrameLowering. This will make it easier to add a new variant to the register splitting.
1 parent a48e686 commit 8eac8cc

File tree

3 files changed

+60
-120
lines changed

3 files changed

+60
-120
lines changed

llvm/lib/Target/ARM/ARMBaseRegisterInfo.h

Lines changed: 0 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -41,80 +41,6 @@ namespace ARMRI {
4141

4242
} // end namespace ARMRI
4343

44-
/// isARMArea1Register - Returns true if the register is a low register (r0-r7)
45-
/// or a stack/pc register that we should push/pop.
46-
static inline bool isARMArea1Register(unsigned Reg, bool SplitFramePushPop) {
47-
using namespace ARM;
48-
49-
switch (Reg) {
50-
case R0: case R1: case R2: case R3:
51-
case R4: case R5: case R6: case R7:
52-
case LR: case SP: case PC:
53-
return true;
54-
case R8: case R9: case R10: case R11: case R12:
55-
// For iOS we want r7 and lr to be next to each other.
56-
return !SplitFramePushPop;
57-
default:
58-
return false;
59-
}
60-
}
61-
62-
static inline bool isARMArea2Register(unsigned Reg, bool SplitFramePushPop) {
63-
using namespace ARM;
64-
65-
switch (Reg) {
66-
case R8: case R9: case R10: case R11: case R12:
67-
// iOS has this second area.
68-
return SplitFramePushPop;
69-
default:
70-
return false;
71-
}
72-
}
73-
74-
static inline bool isSplitFPArea1Register(unsigned Reg,
75-
bool SplitFramePushPop) {
76-
using namespace ARM;
77-
78-
switch (Reg) {
79-
case R0: case R1: case R2: case R3:
80-
case R4: case R5: case R6: case R7:
81-
case R8: case R9: case R10: case R12:
82-
case SP: case PC:
83-
return true;
84-
default:
85-
return false;
86-
}
87-
}
88-
89-
static inline bool isSplitFPArea2Register(unsigned Reg,
90-
bool SplitFramePushPop) {
91-
using namespace ARM;
92-
93-
switch (Reg) {
94-
case R11: case LR:
95-
return true;
96-
default:
97-
return false;
98-
}
99-
}
100-
101-
static inline bool isARMArea3Register(unsigned Reg, bool SplitFramePushPop) {
102-
using namespace ARM;
103-
104-
switch (Reg) {
105-
case D15: case D14: case D13: case D12:
106-
case D11: case D10: case D9: case D8:
107-
case D7: case D6: case D5: case D4:
108-
case D3: case D2: case D1: case D0:
109-
case D31: case D30: case D29: case D28:
110-
case D27: case D26: case D25: case D24:
111-
case D23: case D22: case D21: case D20:
112-
case D19: case D18: case D17: case D16:
113-
return true;
114-
default:
115-
return false;
116-
}
117-
}
11844

11945
static inline bool isCalleeSavedRegister(unsigned Reg,
12046
const MCPhysReg *CSRegs) {

llvm/lib/Target/ARM/ARMFrameLowering.cpp

Lines changed: 57 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1538,14 +1538,11 @@ void ARMFrameLowering::emitPushInst(MachineBasicBlock &MBB,
15381538
MachineBasicBlock::iterator MI,
15391539
ArrayRef<CalleeSavedInfo> CSI,
15401540
unsigned StmOpc, unsigned StrOpc,
1541-
bool NoGap, bool (*Func)(unsigned, bool),
1542-
unsigned NumAlignedDPRCS2Regs,
1543-
unsigned MIFlags) const {
1541+
bool NoGap,
1542+
std::function<bool(unsigned)> Func) const {
15441543
MachineFunction &MF = *MBB.getParent();
15451544
const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
15461545
const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
1547-
ARMSubtarget::PushPopSplitVariation PushPopSplit =
1548-
STI.getPushPopSplitVariation(MF);
15491546

15501547
DebugLoc DL;
15511548

@@ -1557,11 +1554,7 @@ void ARMFrameLowering::emitPushInst(MachineBasicBlock &MBB,
15571554
unsigned LastReg = 0;
15581555
for (; i != 0; --i) {
15591556
Register Reg = CSI[i-1].getReg();
1560-
if (!(Func)(Reg, PushPopSplit == ARMSubtarget::SplitR7))
1561-
continue;
1562-
1563-
// D-registers in the aligned area DPRCS2 are NOT spilled here.
1564-
if (Reg >= ARM::D8 && Reg < ARM::D8 + NumAlignedDPRCS2Regs)
1557+
if (!Func(Reg))
15651558
continue;
15661559

15671560
const MachineRegisterInfo &MRI = MF.getRegInfo();
@@ -1592,15 +1585,15 @@ void ARMFrameLowering::emitPushInst(MachineBasicBlock &MBB,
15921585
if (Regs.size() > 1 || StrOpc== 0) {
15931586
MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, TII.get(StmOpc), ARM::SP)
15941587
.addReg(ARM::SP)
1595-
.setMIFlags(MIFlags)
1588+
.setMIFlags(MachineInstr::FrameSetup)
15961589
.add(predOps(ARMCC::AL));
15971590
for (unsigned i = 0, e = Regs.size(); i < e; ++i)
15981591
MIB.addReg(Regs[i].first, getKillRegState(Regs[i].second));
15991592
} else if (Regs.size() == 1) {
16001593
BuildMI(MBB, MI, DL, TII.get(StrOpc), ARM::SP)
16011594
.addReg(Regs[0].first, getKillRegState(Regs[0].second))
16021595
.addReg(ARM::SP)
1603-
.setMIFlags(MIFlags)
1596+
.setMIFlags(MachineInstr::FrameSetup)
16041597
.addImm(-4)
16051598
.add(predOps(ARMCC::AL));
16061599
}
@@ -1619,8 +1612,7 @@ void ARMFrameLowering::emitPopInst(MachineBasicBlock &MBB,
16191612
MutableArrayRef<CalleeSavedInfo> CSI,
16201613
unsigned LdmOpc, unsigned LdrOpc,
16211614
bool isVarArg, bool NoGap,
1622-
bool (*Func)(unsigned, bool),
1623-
unsigned NumAlignedDPRCS2Regs) const {
1615+
std::function<bool(unsigned)> Func) const {
16241616
MachineFunction &MF = *MBB.getParent();
16251617
const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
16261618
const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
@@ -1655,12 +1647,9 @@ void ARMFrameLowering::emitPopInst(MachineBasicBlock &MBB,
16551647
for (; i != 0; --i) {
16561648
CalleeSavedInfo &Info = CSI[i-1];
16571649
Register Reg = Info.getReg();
1658-
if (!(Func)(Reg, PushPopSplit == ARMSubtarget::SplitR7))
1650+
if (!Func(Reg))
16591651
continue;
16601652

1661-
// The aligned reloads from area DPRCS2 are not inserted here.
1662-
if (Reg >= ARM::D8 && Reg < ARM::D8 + NumAlignedDPRCS2Regs)
1663-
continue;
16641653
if (Reg == ARM::LR && !isTailCall && !isVarArg && !isInterrupt &&
16651654
!isCmseEntry && !isTrap && AFI->getArgumentStackToRestore() == 0 &&
16661655
STI.hasV5TOps() && MBB.succ_empty() && !hasPAC &&
@@ -2006,6 +1995,7 @@ bool ARMFrameLowering::spillCalleeSavedRegisters(
20061995
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
20071996
ARMSubtarget::PushPopSplitVariation PushPopSplit =
20081997
STI.getPushPopSplitVariation(MF);
1998+
const ARMBaseRegisterInfo *RegInfo = STI.getRegisterInfo();
20091999

20102000
unsigned PushOpc = AFI->isThumbFunction() ? ARM::t2STMDB_UPD : ARM::STMDB_UPD;
20112001
unsigned PushOneOpc = AFI->isThumbFunction() ?
@@ -2027,20 +2017,33 @@ bool ARMFrameLowering::spillCalleeSavedRegisters(
20272017
.addImm(-4)
20282018
.add(predOps(ARMCC::AL));
20292019
}
2020+
2021+
auto CheckRegArea = [PushPopSplit, NumAlignedDPRCS2Regs,
2022+
RegInfo](unsigned Reg, SpillArea TestArea) {
2023+
return getSpillArea(Reg, PushPopSplit, NumAlignedDPRCS2Regs, RegInfo) ==
2024+
TestArea;
2025+
};
2026+
auto IsGPRCS1 = [&CheckRegArea](unsigned Reg) {
2027+
return CheckRegArea(Reg, SpillArea::GPRCS1);
2028+
};
2029+
auto IsGPRCS2 = [&CheckRegArea](unsigned Reg) {
2030+
return CheckRegArea(Reg, SpillArea::GPRCS2);
2031+
};
2032+
auto IsDPRCS1 = [&CheckRegArea](unsigned Reg) {
2033+
return CheckRegArea(Reg, SpillArea::DPRCS1);
2034+
};
2035+
2036+
// Windows SEH requires the floating-point registers to be pushed between the
2037+
// two blocks of GPRs in some situations. In all other cases, they are pushed
2038+
// below the GPRs.
20302039
if (PushPopSplit == ARMSubtarget::SplitR11WindowsSEH) {
2031-
emitPushInst(MBB, MI, CSI, PushOpc, PushOneOpc, false,
2032-
&isSplitFPArea1Register, 0, MachineInstr::FrameSetup);
2033-
emitPushInst(MBB, MI, CSI, FltOpc, 0, true, &isARMArea3Register,
2034-
NumAlignedDPRCS2Regs, MachineInstr::FrameSetup);
2035-
emitPushInst(MBB, MI, CSI, PushOpc, PushOneOpc, false,
2036-
&isSplitFPArea2Register, 0, MachineInstr::FrameSetup);
2040+
emitPushInst(MBB, MI, CSI, PushOpc, PushOneOpc, false, IsGPRCS1);
2041+
emitPushInst(MBB, MI, CSI, FltOpc, 0, true, IsDPRCS1);
2042+
emitPushInst(MBB, MI, CSI, PushOpc, PushOneOpc, false, IsGPRCS2);
20372043
} else {
2038-
emitPushInst(MBB, MI, CSI, PushOpc, PushOneOpc, false, &isARMArea1Register,
2039-
0, MachineInstr::FrameSetup);
2040-
emitPushInst(MBB, MI, CSI, PushOpc, PushOneOpc, false, &isARMArea2Register,
2041-
0, MachineInstr::FrameSetup);
2042-
emitPushInst(MBB, MI, CSI, FltOpc, 0, true, &isARMArea3Register,
2043-
NumAlignedDPRCS2Regs, MachineInstr::FrameSetup);
2044+
emitPushInst(MBB, MI, CSI, PushOpc, PushOneOpc, false, IsGPRCS1);
2045+
emitPushInst(MBB, MI, CSI, PushOpc, PushOneOpc, false, IsGPRCS2);
2046+
emitPushInst(MBB, MI, CSI, FltOpc, 0, true, IsDPRCS1);
20442047
}
20452048

20462049
// The code above does not insert spill code for the aligned DPRCS2 registers.
@@ -2060,6 +2063,8 @@ bool ARMFrameLowering::restoreCalleeSavedRegisters(
20602063

20612064
MachineFunction &MF = *MBB.getParent();
20622065
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
2066+
const ARMBaseRegisterInfo *RegInfo = STI.getRegisterInfo();
2067+
20632068
bool isVarArg = AFI->getArgRegsSaveSize() > 0;
20642069
unsigned NumAlignedDPRCS2Regs = AFI->getNumAlignedDPRCS2Regs();
20652070
ARMSubtarget::PushPopSplitVariation PushPopSplit =
@@ -2074,20 +2079,30 @@ bool ARMFrameLowering::restoreCalleeSavedRegisters(
20742079
unsigned LdrOpc =
20752080
AFI->isThumbFunction() ? ARM::t2LDR_POST : ARM::LDR_POST_IMM;
20762081
unsigned FltOpc = ARM::VLDMDIA_UPD;
2082+
2083+
auto CheckRegArea = [PushPopSplit, NumAlignedDPRCS2Regs,
2084+
RegInfo](unsigned Reg, SpillArea TestArea) {
2085+
return getSpillArea(Reg, PushPopSplit, NumAlignedDPRCS2Regs, RegInfo) ==
2086+
TestArea;
2087+
};
2088+
auto IsGPRCS1 = [&CheckRegArea](unsigned Reg) {
2089+
return CheckRegArea(Reg, SpillArea::GPRCS1);
2090+
};
2091+
auto IsGPRCS2 = [&CheckRegArea](unsigned Reg) {
2092+
return CheckRegArea(Reg, SpillArea::GPRCS2);
2093+
};
2094+
auto IsDPRCS1 = [&CheckRegArea](unsigned Reg) {
2095+
return CheckRegArea(Reg, SpillArea::DPRCS1);
2096+
};
2097+
20772098
if (PushPopSplit == ARMSubtarget::SplitR11WindowsSEH) {
2078-
emitPopInst(MBB, MI, CSI, PopOpc, LdrOpc, isVarArg, false,
2079-
&isSplitFPArea2Register, 0);
2080-
emitPopInst(MBB, MI, CSI, FltOpc, 0, isVarArg, true, &isARMArea3Register,
2081-
NumAlignedDPRCS2Regs);
2082-
emitPopInst(MBB, MI, CSI, PopOpc, LdrOpc, isVarArg, false,
2083-
&isSplitFPArea1Register, 0);
2099+
emitPopInst(MBB, MI, CSI, PopOpc, LdrOpc, isVarArg, false, IsGPRCS2);
2100+
emitPopInst(MBB, MI, CSI, FltOpc, 0, isVarArg, true, IsDPRCS1);
2101+
emitPopInst(MBB, MI, CSI, PopOpc, LdrOpc, isVarArg, false, IsGPRCS1);
20842102
} else {
2085-
emitPopInst(MBB, MI, CSI, FltOpc, 0, isVarArg, true, &isARMArea3Register,
2086-
NumAlignedDPRCS2Regs);
2087-
emitPopInst(MBB, MI, CSI, PopOpc, LdrOpc, isVarArg, false,
2088-
&isARMArea2Register, 0);
2089-
emitPopInst(MBB, MI, CSI, PopOpc, LdrOpc, isVarArg, false,
2090-
&isARMArea1Register, 0);
2103+
emitPopInst(MBB, MI, CSI, FltOpc, 0, isVarArg, true, IsDPRCS1);
2104+
emitPopInst(MBB, MI, CSI, PopOpc, LdrOpc, isVarArg, false, IsGPRCS2);
2105+
emitPopInst(MBB, MI, CSI, PopOpc, LdrOpc, isVarArg, false, IsGPRCS1);
20912106
}
20922107

20932108
return true;

llvm/lib/Target/ARM/ARMFrameLowering.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,12 @@ class ARMFrameLowering : public TargetFrameLowering {
9090
private:
9191
void emitPushInst(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
9292
ArrayRef<CalleeSavedInfo> CSI, unsigned StmOpc,
93-
unsigned StrOpc, bool NoGap, bool (*Func)(unsigned, bool),
94-
unsigned NumAlignedDPRCS2Regs, unsigned MIFlags = 0) const;
93+
unsigned StrOpc, bool NoGap,
94+
std::function<bool(unsigned)> Func) const;
9595
void emitPopInst(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
9696
MutableArrayRef<CalleeSavedInfo> CSI, unsigned LdmOpc,
9797
unsigned LdrOpc, bool isVarArg, bool NoGap,
98-
bool (*Func)(unsigned, bool),
99-
unsigned NumAlignedDPRCS2Regs) const;
98+
std::function<bool(unsigned)> Func) const;
10099

101100
MachineBasicBlock::iterator
102101
eliminateCallFramePseudoInstr(MachineFunction &MF,

0 commit comments

Comments
 (0)