llvm.org GIT mirror llvm / 8b3ca62
Rewrite stack callee saved spills and restores to use push/pop instructions. Remove movePastCSLoadStoreOps and associated code for simple pointer increments. Update routines that depended upon other opcodes for save/restore. Adjust all testcases accordingly. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@119725 91177308-0d34-0410-b5e6-96231b3b80d8 Eric Christopher 9 years ago
7 changed file(s) with 201 addition(s) and 98 deletion(s). Raw diff Collapse all Expand all
196196 return NewMIs[0];
197197 }
198198
199 void
200 ARMBaseInstrInfo::emitPushInst(MachineBasicBlock &MBB,
201 MachineBasicBlock::iterator MI,
202 const std::vector &CSI, unsigned Opc,
203 bool(*Func)(unsigned, bool)) const {
204 MachineFunction &MF = *MBB.getParent();
205 DebugLoc DL;
206 if (MI != MBB.end()) DL = MI->getDebugLoc();
207
208 MachineInstrBuilder MIB = BuildMI(MF, DL, get(Opc));
209 MIB.addReg(ARM::SP, getDefRegState(true));
210 MIB.addReg(ARM::SP);
211 AddDefaultPred(MIB);
212 bool NumRegs = false;
213 for (unsigned i = CSI.size(); i != 0; --i) {
214 unsigned Reg = CSI[i-1].getReg();
215 if (!(Func)(Reg, Subtarget.isTargetDarwin())) continue;
216
217 // Add the callee-saved register as live-in unless it's LR and
218 // @llvm.returnaddress is called. If LR is returned for @llvm.returnaddress
219 // then it's already added to the function and entry block live-in sets.
220 bool isKill = true;
221 if (Reg == ARM::LR) {
222 if (MF.getFrameInfo()->isReturnAddressTaken() &&
223 MF.getRegInfo().isLiveIn(Reg))
224 isKill = false;
225 }
226
227 if (isKill)
228 MBB.addLiveIn(Reg);
229
230 NumRegs = true;
231 MIB.addReg(Reg, getKillRegState(isKill));
232 }
233
234 // It's illegal to emit push instruction without operands.
235 if (NumRegs)
236 MBB.insert(MI, &*MIB);
237 else
238 MF.DeleteMachineInstr(MIB);
239 }
240
199241 bool
200242 ARMBaseInstrInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
201243 MachineBasicBlock::iterator MI,
204246 if (CSI.empty())
205247 return false;
206248
207 DebugLoc DL;
208 if (MI != MBB.end()) DL = MI->getDebugLoc();
209
210 for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
211 unsigned Reg = CSI[i].getReg();
212 bool isKill = true;
213
214 // Add the callee-saved register as live-in unless it's LR and
215 // @llvm.returnaddress is called. If LR is returned for @llvm.returnaddress
216 // then it's already added to the function and entry block live-in sets.
217 if (Reg == ARM::LR) {
218 MachineFunction &MF = *MBB.getParent();
219 if (MF.getFrameInfo()->isReturnAddressTaken() &&
220 MF.getRegInfo().isLiveIn(Reg))
221 isKill = false;
222 }
223
224 if (isKill)
225 MBB.addLiveIn(Reg);
226
227 // Insert the spill to the stack frame. The register is killed at the spill
228 //
229 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
230 storeRegToStackSlot(MBB, MI, Reg, isKill,
231 CSI[i].getFrameIdx(), RC, TRI);
232 }
249 MachineFunction &MF = *MBB.getParent();
250 ARMFunctionInfo *AFI = MF.getInfo();
251 DebugLoc DL = MI->getDebugLoc();
252
253 unsigned PushOpc = AFI->isThumbFunction() ? ARM::t2STMDB_UPD : ARM::STMDB_UPD;
254 unsigned FltOpc = ARM::VSTMDDB_UPD;
255 emitPushInst(MBB, MI, CSI, PushOpc, &isARMArea1Register);
256 emitPushInst(MBB, MI, CSI, PushOpc, &isARMArea2Register);
257 emitPushInst(MBB, MI, CSI, FltOpc, &isARMArea3Register);
258
233259 return true;
234260 }
261
262 void
263 ARMBaseInstrInfo::emitPopInst(MachineBasicBlock &MBB,
264 MachineBasicBlock::iterator MI,
265 const std::vector &CSI, unsigned Opc,
266 bool isVarArg, bool(*Func)(unsigned, bool)) const {
267
268 MachineFunction &MF = *MBB.getParent();
269 ARMFunctionInfo *AFI = MF.getInfo();
270 DebugLoc DL = MI->getDebugLoc();
271
272 MachineInstrBuilder MIB = BuildMI(MF, DL, get(Opc));
273 MIB.addReg(ARM::SP, getDefRegState(true));
274 MIB.addReg(ARM::SP);
275 AddDefaultPred(MIB);
276 bool NumRegs = false;
277 for (unsigned i = CSI.size(); i != 0; --i) {
278 unsigned Reg = CSI[i-1].getReg();
279 if (!(Func)(Reg, Subtarget.isTargetDarwin())) continue;
280
281 if (Reg == ARM::LR && !isVarArg) {
282 Reg = ARM::PC;
283 unsigned Opc = AFI->isThumbFunction() ? ARM::t2LDMIA_RET : ARM::LDMIA_RET;
284 (*MIB).setDesc(get(Opc));
285 MI = MBB.erase(MI);
286 }
287
288 MIB.addReg(Reg, RegState::Define);
289 NumRegs = true;
290 }
291
292 // It's illegal to emit pop instruction without operands.
293 if (NumRegs)
294 MBB.insert(MI, &*MIB);
295 else
296 MF.DeleteMachineInstr(MIB);
297 }
298
299 bool
300 ARMBaseInstrInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
301 MachineBasicBlock::iterator MI,
302 const std::vector &CSI,
303 const TargetRegisterInfo *TRI) const {
304 if (CSI.empty())
305 return false;
306
307 MachineFunction &MF = *MBB.getParent();
308 ARMFunctionInfo *AFI = MF.getInfo();
309 bool isVarArg = AFI->getVarArgsRegSaveSize() > 0;
310 DebugLoc DL = MI->getDebugLoc();
311
312 unsigned PopOpc = AFI->isThumbFunction() ? ARM::t2LDMIA_UPD : ARM::LDMIA_UPD;
313 unsigned FltOpc = ARM::VLDMDIA_UPD;
314 emitPopInst(MBB, MI, CSI, FltOpc, isVarArg, &isARMArea3Register);
315 emitPopInst(MBB, MI, CSI, PopOpc, isVarArg, &isARMArea2Register);
316 emitPopInst(MBB, MI, CSI, PopOpc, isVarArg, &isARMArea1Register);
317
318 return true;
319 }
320
235321
236322 // Branch analysis.
237323 bool
21942280 case ARM::VSTMQIA:
21952281 case ARM::VSTMQDB:
21962282 return 2;
2197 }
2283 }
21982284 }
21992285
22002286 bool ARMBaseInstrInfo::
210210 const std::vector &CSI,
211211 const TargetRegisterInfo *TRI) const;
212212
213 bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
214 MachineBasicBlock::iterator MI,
215 const std::vector &CSI,
216 const TargetRegisterInfo *TRI) const;
217
218 private:
219 void emitPopInst(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
220 const std::vector &CSI, unsigned Opc,
221 bool isVarArg, bool(*Func)(unsigned, bool)) const;
222 void emitPushInst(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
223 const std::vector &CSI, unsigned Opc,
224 bool(*Func)(unsigned, bool)) const;
225
226
227 public:
213228 // Branch analysis.
214229 virtual bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
215230 MachineBasicBlock *&FBB,
4040 return true;
4141 default:
4242 return false;
43 }
44 }
45
46 /// isARMArea1Register - Returns true if the register is a low register (r0-r7)
47 /// or a stack/pc register that we should push/pop.
48 static inline bool isARMArea1Register(unsigned Reg, bool isDarwin) {
49 using namespace ARM;
50 switch (Reg) {
51 case R0: case R1: case R2: case R3:
52 case R4: case R5: case R6: case R7:
53 case LR: case SP: case PC:
54 return true;
55 case R8: case R9: case R10: case R11:
56 // For darwin we want r7 and lr to be next to each other.
57 return !isDarwin;
58 default:
59 return false;
60 }
61 }
62
63 static inline bool isARMArea2Register(unsigned Reg, bool isDarwin) {
64 using namespace ARM;
65 switch (Reg) {
66 case R8: case R9: case R10: case R11:
67 // Darwin has this second area.
68 return isDarwin;
69 default:
70 return false;
71 }
72 }
73
74 static inline bool isARMArea3Register(unsigned Reg, bool isDarwin) {
75 using namespace ARM;
76 switch (Reg) {
77 case D15: case D14: case D13: case D12:
78 case D11: case D10: case D9: case D8:
79 return true;
80 default:
81 return false;
4382 }
4483 }
4584
1919
2020 using namespace llvm;
2121
22 /// Move iterator past the next bunch of callee save load / store ops for
23 /// the particular spill area (1: integer area 1, 2: integer area 2,
24 /// 3: fp area, 0: don't care).
25 static void movePastCSLoadStoreOps(MachineBasicBlock &MBB,
26 MachineBasicBlock::iterator &MBBI,
27 int Opc1, int Opc2, unsigned Area,
28 const ARMSubtarget &STI) {
29 while (MBBI != MBB.end() &&
30 ((MBBI->getOpcode() == Opc1) || (MBBI->getOpcode() == Opc2)) &&
31 MBBI->getOperand(1).isFI()) {
32 if (Area != 0) {
33 bool Done = false;
34 unsigned Category = 0;
35 switch (MBBI->getOperand(0).getReg()) {
36 case ARM::R4: case ARM::R5: case ARM::R6: case ARM::R7:
37 case ARM::LR:
38 Category = 1;
39 break;
40 case ARM::R8: case ARM::R9: case ARM::R10: case ARM::R11:
41 Category = STI.isTargetDarwin() ? 2 : 1;
42 break;
43 case ARM::D8: case ARM::D9: case ARM::D10: case ARM::D11:
44 case ARM::D12: case ARM::D13: case ARM::D14: case ARM::D15:
45 Category = 3;
46 break;
47 default:
48 Done = true;
49 break;
50 }
51 if (Done || Category != Area)
52 break;
53 }
54
55 ++MBBI;
56 }
57 }
58
5922 static bool isCalleeSavedRegister(unsigned Reg, const unsigned *CSRegs) {
6023 for (unsigned i = 0; CSRegs[i]; ++i)
6124 if (Reg == CSRegs[i])
6629 static bool isCSRestore(MachineInstr *MI,
6730 const ARMBaseInstrInfo &TII,
6831 const unsigned *CSRegs) {
69 return ((MI->getOpcode() == (int)ARM::VLDRD ||
70 MI->getOpcode() == (int)ARM::LDRi12 ||
71 MI->getOpcode() == (int)ARM::t2LDRi12) &&
72 MI->getOperand(1).isFI() &&
73 isCalleeSavedRegister(MI->getOperand(0).getReg(), CSRegs));
32 // Integer spill area is handled with "pop".
33 if (MI->getOpcode() == ARM::LDMIA_RET ||
34 MI->getOpcode() == ARM::t2LDMIA_RET ||
35 MI->getOpcode() == ARM::LDMIA_UPD ||
36 MI->getOpcode() == ARM::t2LDMIA_UPD ||
37 MI->getOpcode() == ARM::VLDMDIA_UPD) {
38 // The first two operands are predicates. The last two are
39 // imp-def and imp-use of SP. Check everything in between.
40 for (int i = 5, e = MI->getNumOperands(); i != e; ++i)
41 if (!isCalleeSavedRegister(MI->getOperand(i).getReg(), CSRegs))
42 return false;
43 return true;
44 }
45
46 return false;
7447 }
7548
7649 static void
153126 DPRCSSize += 8;
154127 }
155128 }
156
157 // Build the new SUBri to adjust SP for integer callee-save spill area 1.
158 emitSPUpdate(isARM, MBB, MBBI, dl, TII, -GPRCS1Size);
159 movePastCSLoadStoreOps(MBB, MBBI, ARM::STRi12, ARM::t2STRi12, 1, STI);
160
129
130 // Move past area 1.
131 if (GPRCS1Size > 0) MBBI++;
132
161133 // Set FP to point to the stack slot that contains the previous FP.
162134 // For Darwin, FP is R7, which has now been stored in spill area 1.
163135 // Otherwise, if this is not Darwin, all the callee-saved registers go
171143 .addFrameIndex(FramePtrSpillFI).addImm(0);
172144 AddDefaultCC(AddDefaultPred(MIB));
173145 }
174
175 // Build the new SUBri to adjust SP for integer callee-save spill area 2.
176 emitSPUpdate(isARM, MBB, MBBI, dl, TII, -GPRCS2Size);
177
178 // Build the new SUBri to adjust SP for FP callee-save spill area.
179 movePastCSLoadStoreOps(MBB, MBBI, ARM::STRi12, ARM::t2STRi12, 2, STI);
180 emitSPUpdate(isARM, MBB, MBBI, dl, TII, -DPRCSSize);
181
146
147 // Move past area 2.
148 if (GPRCS2Size > 0) MBBI++;
149
182150 // Determine starting offsets of spill areas.
183151 unsigned DPRCSOffset = NumBytes - (GPRCS1Size + GPRCS2Size + DPRCSSize);
184152 unsigned GPRCS2Offset = DPRCSOffset + DPRCSSize;
190158 AFI->setGPRCalleeSavedArea2Offset(GPRCS2Offset);
191159 AFI->setDPRCalleeSavedAreaOffset(DPRCSOffset);
192160
193 movePastCSLoadStoreOps(MBB, MBBI, ARM::VSTRD, 0, 3, STI);
161 // Move past area 3.
162 if (DPRCSSize > 0) MBBI++;
163
194164 NumBytes = DPRCSOffset;
195165 if (NumBytes) {
196166 // Adjust SP after all the callee-save spills.
324294 } else if (NumBytes)
325295 emitSPUpdate(isARM, MBB, MBBI, dl, TII, NumBytes);
326296
327 // Move SP to start of integer callee save spill area 2.
328 movePastCSLoadStoreOps(MBB, MBBI, ARM::VLDRD, 0, 3, STI);
329 emitSPUpdate(isARM, MBB, MBBI, dl, TII, AFI->getDPRCalleeSavedAreaSize());
330
331 // Move SP to start of integer callee save spill area 1.
332 movePastCSLoadStoreOps(MBB, MBBI, ARM::LDRi12, ARM::t2LDRi12, 2, STI);
333 emitSPUpdate(isARM, MBB, MBBI, dl, TII, AFI->getGPRCalleeSavedArea2Size());
334
335 // Move SP to SP upon entry to the function.
336 movePastCSLoadStoreOps(MBB, MBBI, ARM::LDRi12, ARM::t2LDRi12, 1, STI);
337 emitSPUpdate(isARM, MBB, MBBI, dl, TII, AFI->getGPRCalleeSavedArea1Size());
297 // Increment past our save areas.
298 if (AFI->getDPRCalleeSavedAreaSize()) MBBI++;
299 if (AFI->getGPRCalleeSavedArea2Size()) MBBI++;
300 if (AFI->getGPRCalleeSavedArea1Size()) MBBI++;
338301 }
339302
340303 if (RetOpcode == ARM::TCRETURNdi || RetOpcode == ARM::TCRETURNdiND ||
22 ; LDM instruction, was causing an assertion failure because the microop count
33 ; was being treated as an instruction count.
44
5 ; CHECK: ldmia
5 ; CHECK: push
66 ; CHECK: ldmia
77 ; CHECK: ldmia
88 ; CHECK: ldmia
33
44 define i64 @t(i64 %a) nounwind readonly {
55 entry:
6 ; CHECK: str lr, [sp, #-4]!
7 ; CHECK: ldr lr, [sp], #4
6 ; CHECK: push {lr}
7 ; CHECK: ldmia sp!, {pc}
88 %0 = load i64** @b, align 4
99 %1 = load i64* %0, align 4
1010 %2 = mul i64 %1, %a
3838 ; CHECK: ittt eq
3939 ; CHECK: moveq r0
4040 ; CHECK-NOT: LBB0_
41 ; CHECK: ldreq
41 ; CHECK: popeq
4242 ; CHECK: popeq
4343 switch i32 undef, label %bb7 [
4444 i32 37, label %bb43