Skip to content

Commit e817cfd

Browse files
committed
[ARM] Refactor generation of push/pop instructions (NFC) (#110283)
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 2ecf2e2 commit e817cfd

File tree

3 files changed

+60
-121
lines changed

3 files changed

+60
-121
lines changed

llvm/lib/Target/ARM/ARMBaseRegisterInfo.h

Lines changed: 0 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -41,81 +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-
}
118-
11944
static inline bool isCalleeSavedRegister(unsigned Reg,
12045
const MCPhysReg *CSRegs) {
12146
for (unsigned i = 0; CSRegs[i]; ++i)

llvm/lib/Target/ARM/ARMFrameLowering.cpp

Lines changed: 57 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1571,14 +1571,11 @@ void ARMFrameLowering::emitPushInst(MachineBasicBlock &MBB,
15711571
MachineBasicBlock::iterator MI,
15721572
ArrayRef<CalleeSavedInfo> CSI,
15731573
unsigned StmOpc, unsigned StrOpc,
1574-
bool NoGap, bool (*Func)(unsigned, bool),
1575-
unsigned NumAlignedDPRCS2Regs,
1576-
unsigned MIFlags) const {
1574+
bool NoGap,
1575+
function_ref<bool(unsigned)> Func) const {
15771576
MachineFunction &MF = *MBB.getParent();
15781577
const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
15791578
const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
1580-
ARMSubtarget::PushPopSplitVariation PushPopSplit =
1581-
STI.getPushPopSplitVariation(MF);
15821579

15831580
DebugLoc DL;
15841581

@@ -1590,11 +1587,7 @@ void ARMFrameLowering::emitPushInst(MachineBasicBlock &MBB,
15901587
unsigned LastReg = 0;
15911588
for (; i != 0; --i) {
15921589
Register Reg = CSI[i-1].getReg();
1593-
if (!(Func)(Reg, PushPopSplit == ARMSubtarget::SplitR7))
1594-
continue;
1595-
1596-
// D-registers in the aligned area DPRCS2 are NOT spilled here.
1597-
if (Reg >= ARM::D8 && Reg < ARM::D8 + NumAlignedDPRCS2Regs)
1590+
if (!Func(Reg))
15981591
continue;
15991592

16001593
const MachineRegisterInfo &MRI = MF.getRegInfo();
@@ -1625,15 +1618,15 @@ void ARMFrameLowering::emitPushInst(MachineBasicBlock &MBB,
16251618
if (Regs.size() > 1 || StrOpc== 0) {
16261619
MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, TII.get(StmOpc), ARM::SP)
16271620
.addReg(ARM::SP)
1628-
.setMIFlags(MIFlags)
1621+
.setMIFlags(MachineInstr::FrameSetup)
16291622
.add(predOps(ARMCC::AL));
16301623
for (unsigned i = 0, e = Regs.size(); i < e; ++i)
16311624
MIB.addReg(Regs[i].first, getKillRegState(Regs[i].second));
16321625
} else if (Regs.size() == 1) {
16331626
BuildMI(MBB, MI, DL, TII.get(StrOpc), ARM::SP)
16341627
.addReg(Regs[0].first, getKillRegState(Regs[0].second))
16351628
.addReg(ARM::SP)
1636-
.setMIFlags(MIFlags)
1629+
.setMIFlags(MachineInstr::FrameSetup)
16371630
.addImm(-4)
16381631
.add(predOps(ARMCC::AL));
16391632
}
@@ -1652,8 +1645,7 @@ void ARMFrameLowering::emitPopInst(MachineBasicBlock &MBB,
16521645
MutableArrayRef<CalleeSavedInfo> CSI,
16531646
unsigned LdmOpc, unsigned LdrOpc,
16541647
bool isVarArg, bool NoGap,
1655-
bool (*Func)(unsigned, bool),
1656-
unsigned NumAlignedDPRCS2Regs) const {
1648+
function_ref<bool(unsigned)> Func) const {
16571649
MachineFunction &MF = *MBB.getParent();
16581650
const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
16591651
const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
@@ -1688,12 +1680,9 @@ void ARMFrameLowering::emitPopInst(MachineBasicBlock &MBB,
16881680
for (; i != 0; --i) {
16891681
CalleeSavedInfo &Info = CSI[i-1];
16901682
Register Reg = Info.getReg();
1691-
if (!(Func)(Reg, PushPopSplit == ARMSubtarget::SplitR7))
1683+
if (!Func(Reg))
16921684
continue;
16931685

1694-
// The aligned reloads from area DPRCS2 are not inserted here.
1695-
if (Reg >= ARM::D8 && Reg < ARM::D8 + NumAlignedDPRCS2Regs)
1696-
continue;
16971686
if (Reg == ARM::LR && !isTailCall && !isVarArg && !isInterrupt &&
16981687
!isCmseEntry && !isTrap && AFI->getArgumentStackToRestore() == 0 &&
16991688
STI.hasV5TOps() && MBB.succ_empty() && !hasPAC &&
@@ -2039,6 +2028,7 @@ bool ARMFrameLowering::spillCalleeSavedRegisters(
20392028
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
20402029
ARMSubtarget::PushPopSplitVariation PushPopSplit =
20412030
STI.getPushPopSplitVariation(MF);
2031+
const ARMBaseRegisterInfo *RegInfo = STI.getRegisterInfo();
20422032

20432033
unsigned PushOpc = AFI->isThumbFunction() ? ARM::t2STMDB_UPD : ARM::STMDB_UPD;
20442034
unsigned PushOneOpc = AFI->isThumbFunction() ?
@@ -2060,20 +2050,33 @@ bool ARMFrameLowering::spillCalleeSavedRegisters(
20602050
.addImm(-4)
20612051
.add(predOps(ARMCC::AL));
20622052
}
2053+
2054+
auto CheckRegArea = [PushPopSplit, NumAlignedDPRCS2Regs,
2055+
RegInfo](unsigned Reg, SpillArea TestArea) {
2056+
return getSpillArea(Reg, PushPopSplit, NumAlignedDPRCS2Regs, RegInfo) ==
2057+
TestArea;
2058+
};
2059+
auto IsGPRCS1 = [&CheckRegArea](unsigned Reg) {
2060+
return CheckRegArea(Reg, SpillArea::GPRCS1);
2061+
};
2062+
auto IsGPRCS2 = [&CheckRegArea](unsigned Reg) {
2063+
return CheckRegArea(Reg, SpillArea::GPRCS2);
2064+
};
2065+
auto IsDPRCS1 = [&CheckRegArea](unsigned Reg) {
2066+
return CheckRegArea(Reg, SpillArea::DPRCS1);
2067+
};
2068+
2069+
// Windows SEH requires the floating-point registers to be pushed between the
2070+
// two blocks of GPRs in some situations. In all other cases, they are pushed
2071+
// below the GPRs.
20632072
if (PushPopSplit == ARMSubtarget::SplitR11WindowsSEH) {
2064-
emitPushInst(MBB, MI, CSI, PushOpc, PushOneOpc, false,
2065-
&isSplitFPArea1Register, 0, MachineInstr::FrameSetup);
2066-
emitPushInst(MBB, MI, CSI, FltOpc, 0, true, &isARMArea3Register,
2067-
NumAlignedDPRCS2Regs, MachineInstr::FrameSetup);
2068-
emitPushInst(MBB, MI, CSI, PushOpc, PushOneOpc, false,
2069-
&isSplitFPArea2Register, 0, MachineInstr::FrameSetup);
2073+
emitPushInst(MBB, MI, CSI, PushOpc, PushOneOpc, false, IsGPRCS1);
2074+
emitPushInst(MBB, MI, CSI, FltOpc, 0, true, IsDPRCS1);
2075+
emitPushInst(MBB, MI, CSI, PushOpc, PushOneOpc, false, IsGPRCS2);
20702076
} else {
2071-
emitPushInst(MBB, MI, CSI, PushOpc, PushOneOpc, false, &isARMArea1Register,
2072-
0, MachineInstr::FrameSetup);
2073-
emitPushInst(MBB, MI, CSI, PushOpc, PushOneOpc, false, &isARMArea2Register,
2074-
0, MachineInstr::FrameSetup);
2075-
emitPushInst(MBB, MI, CSI, FltOpc, 0, true, &isARMArea3Register,
2076-
NumAlignedDPRCS2Regs, MachineInstr::FrameSetup);
2077+
emitPushInst(MBB, MI, CSI, PushOpc, PushOneOpc, false, IsGPRCS1);
2078+
emitPushInst(MBB, MI, CSI, PushOpc, PushOneOpc, false, IsGPRCS2);
2079+
emitPushInst(MBB, MI, CSI, FltOpc, 0, true, IsDPRCS1);
20772080
}
20782081

20792082
// The code above does not insert spill code for the aligned DPRCS2 registers.
@@ -2093,6 +2096,8 @@ bool ARMFrameLowering::restoreCalleeSavedRegisters(
20932096

20942097
MachineFunction &MF = *MBB.getParent();
20952098
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
2099+
const ARMBaseRegisterInfo *RegInfo = STI.getRegisterInfo();
2100+
20962101
bool isVarArg = AFI->getArgRegsSaveSize() > 0;
20972102
unsigned NumAlignedDPRCS2Regs = AFI->getNumAlignedDPRCS2Regs();
20982103
ARMSubtarget::PushPopSplitVariation PushPopSplit =
@@ -2107,20 +2112,30 @@ bool ARMFrameLowering::restoreCalleeSavedRegisters(
21072112
unsigned LdrOpc =
21082113
AFI->isThumbFunction() ? ARM::t2LDR_POST : ARM::LDR_POST_IMM;
21092114
unsigned FltOpc = ARM::VLDMDIA_UPD;
2115+
2116+
auto CheckRegArea = [PushPopSplit, NumAlignedDPRCS2Regs,
2117+
RegInfo](unsigned Reg, SpillArea TestArea) {
2118+
return getSpillArea(Reg, PushPopSplit, NumAlignedDPRCS2Regs, RegInfo) ==
2119+
TestArea;
2120+
};
2121+
auto IsGPRCS1 = [&CheckRegArea](unsigned Reg) {
2122+
return CheckRegArea(Reg, SpillArea::GPRCS1);
2123+
};
2124+
auto IsGPRCS2 = [&CheckRegArea](unsigned Reg) {
2125+
return CheckRegArea(Reg, SpillArea::GPRCS2);
2126+
};
2127+
auto IsDPRCS1 = [&CheckRegArea](unsigned Reg) {
2128+
return CheckRegArea(Reg, SpillArea::DPRCS1);
2129+
};
2130+
21102131
if (PushPopSplit == ARMSubtarget::SplitR11WindowsSEH) {
2111-
emitPopInst(MBB, MI, CSI, PopOpc, LdrOpc, isVarArg, false,
2112-
&isSplitFPArea2Register, 0);
2113-
emitPopInst(MBB, MI, CSI, FltOpc, 0, isVarArg, true, &isARMArea3Register,
2114-
NumAlignedDPRCS2Regs);
2115-
emitPopInst(MBB, MI, CSI, PopOpc, LdrOpc, isVarArg, false,
2116-
&isSplitFPArea1Register, 0);
2132+
emitPopInst(MBB, MI, CSI, PopOpc, LdrOpc, isVarArg, false, IsGPRCS2);
2133+
emitPopInst(MBB, MI, CSI, FltOpc, 0, isVarArg, true, IsDPRCS1);
2134+
emitPopInst(MBB, MI, CSI, PopOpc, LdrOpc, isVarArg, false, IsGPRCS1);
21172135
} else {
2118-
emitPopInst(MBB, MI, CSI, FltOpc, 0, isVarArg, true, &isARMArea3Register,
2119-
NumAlignedDPRCS2Regs);
2120-
emitPopInst(MBB, MI, CSI, PopOpc, LdrOpc, isVarArg, false,
2121-
&isARMArea2Register, 0);
2122-
emitPopInst(MBB, MI, CSI, PopOpc, LdrOpc, isVarArg, false,
2123-
&isARMArea1Register, 0);
2136+
emitPopInst(MBB, MI, CSI, FltOpc, 0, isVarArg, true, IsDPRCS1);
2137+
emitPopInst(MBB, MI, CSI, PopOpc, LdrOpc, isVarArg, false, IsGPRCS2);
2138+
emitPopInst(MBB, MI, CSI, PopOpc, LdrOpc, isVarArg, false, IsGPRCS1);
21242139
}
21252140

21262141
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+
function_ref<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+
function_ref<bool(unsigned)> Func) const;
10099

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

0 commit comments

Comments
 (0)