Thumb1FrameLowering.cpp revision cd81d94322a39503e4a3e87b6ee03d4fcb3465fb
1//===-- Thumb1FrameLowering.cpp - Thumb1 Frame Information ----------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains the Thumb1 implementation of TargetFrameLowering class.
11//
12//===----------------------------------------------------------------------===//
13
14#include "Thumb1FrameLowering.h"
15#include "ARMMachineFunctionInfo.h"
16#include "llvm/CodeGen/MachineFrameInfo.h"
17#include "llvm/CodeGen/MachineFunction.h"
18#include "llvm/CodeGen/MachineInstrBuilder.h"
19#include "llvm/CodeGen/MachineModuleInfo.h"
20#include "llvm/CodeGen/MachineRegisterInfo.h"
21
22using namespace llvm;
23
24Thumb1FrameLowering::Thumb1FrameLowering(const ARMSubtarget &sti)
25    : ARMFrameLowering(sti) {}
26
27bool Thumb1FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const{
28  const MachineFrameInfo *FFI = MF.getFrameInfo();
29  unsigned CFSize = FFI->getMaxCallFrameSize();
30  // It's not always a good idea to include the call frame as part of the
31  // stack frame. ARM (especially Thumb) has small immediate offset to
32  // address the stack frame. So a large call frame can cause poor codegen
33  // and may even makes it impossible to scavenge a register.
34  if (CFSize >= ((1 << 8) - 1) * 4 / 2) // Half of imm8 * 4
35    return false;
36
37  return !MF.getFrameInfo()->hasVarSizedObjects();
38}
39
40static void
41emitSPUpdate(MachineBasicBlock &MBB,
42             MachineBasicBlock::iterator &MBBI,
43             const TargetInstrInfo &TII, DebugLoc dl,
44             const Thumb1RegisterInfo &MRI,
45             int NumBytes, unsigned MIFlags = MachineInstr::NoFlags)  {
46  emitThumbRegPlusImmediate(MBB, MBBI, dl, ARM::SP, ARM::SP, NumBytes, TII,
47                            MRI, MIFlags);
48}
49
50
51void Thumb1FrameLowering::
52eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
53                              MachineBasicBlock::iterator I) const {
54  const Thumb1InstrInfo &TII =
55    *static_cast<const Thumb1InstrInfo*>(MF.getTarget().getInstrInfo());
56  const Thumb1RegisterInfo *RegInfo =
57    static_cast<const Thumb1RegisterInfo*>(MF.getTarget().getRegisterInfo());
58  if (!hasReservedCallFrame(MF)) {
59    // If we have alloca, convert as follows:
60    // ADJCALLSTACKDOWN -> sub, sp, sp, amount
61    // ADJCALLSTACKUP   -> add, sp, sp, amount
62    MachineInstr *Old = I;
63    DebugLoc dl = Old->getDebugLoc();
64    unsigned Amount = Old->getOperand(0).getImm();
65    if (Amount != 0) {
66      // We need to keep the stack aligned properly.  To do this, we round the
67      // amount of space needed for the outgoing arguments up to the next
68      // alignment boundary.
69      unsigned Align = getStackAlignment();
70      Amount = (Amount+Align-1)/Align*Align;
71
72      // Replace the pseudo instruction with a new instruction...
73      unsigned Opc = Old->getOpcode();
74      if (Opc == ARM::ADJCALLSTACKDOWN || Opc == ARM::tADJCALLSTACKDOWN) {
75        emitSPUpdate(MBB, I, TII, dl, *RegInfo, -Amount);
76      } else {
77        assert(Opc == ARM::ADJCALLSTACKUP || Opc == ARM::tADJCALLSTACKUP);
78        emitSPUpdate(MBB, I, TII, dl, *RegInfo, Amount);
79      }
80    }
81  }
82  MBB.erase(I);
83}
84
85void Thumb1FrameLowering::emitPrologue(MachineFunction &MF) const {
86  MachineBasicBlock &MBB = MF.front();
87  MachineBasicBlock::iterator MBBI = MBB.begin();
88  MachineFrameInfo  *MFI = MF.getFrameInfo();
89  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
90  MachineModuleInfo &MMI = MF.getMMI();
91  const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo();
92  const Thumb1RegisterInfo *RegInfo =
93    static_cast<const Thumb1RegisterInfo*>(MF.getTarget().getRegisterInfo());
94  const Thumb1InstrInfo &TII =
95    *static_cast<const Thumb1InstrInfo*>(MF.getTarget().getInstrInfo());
96
97  unsigned Align = MF.getTarget().getFrameLowering()->getStackAlignment();
98  unsigned ArgRegsSaveSize = AFI->getArgRegsSaveSize(Align);
99  unsigned NumBytes = MFI->getStackSize();
100  assert(NumBytes >= ArgRegsSaveSize &&
101         "ArgRegsSaveSize is included in NumBytes");
102  const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
103  DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
104  unsigned FramePtr = RegInfo->getFrameRegister(MF);
105  unsigned BasePtr = RegInfo->getBaseRegister();
106  int CFAOffset = 0;
107
108  // Thumb add/sub sp, imm8 instructions implicitly multiply the offset by 4.
109  NumBytes = (NumBytes + 3) & ~3;
110  MFI->setStackSize(NumBytes);
111
112  // Determine the sizes of each callee-save spill areas and record which frame
113  // belongs to which callee-save spill areas.
114  unsigned GPRCS1Size = 0, GPRCS2Size = 0, DPRCSSize = 0;
115  int FramePtrSpillFI = 0;
116
117  if (ArgRegsSaveSize) {
118    emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, -ArgRegsSaveSize,
119                 MachineInstr::FrameSetup);
120    CFAOffset -= ArgRegsSaveSize;
121    unsigned CFIIndex = MMI.addFrameInst(
122        MCCFIInstruction::createDefCfaOffset(nullptr, CFAOffset));
123    BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
124        .addCFIIndex(CFIIndex);
125  }
126
127  if (!AFI->hasStackFrame()) {
128    if (NumBytes - ArgRegsSaveSize != 0) {
129      emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, -(NumBytes - ArgRegsSaveSize),
130                   MachineInstr::FrameSetup);
131      CFAOffset -= NumBytes - ArgRegsSaveSize;
132      unsigned CFIIndex = MMI.addFrameInst(
133          MCCFIInstruction::createDefCfaOffset(nullptr, CFAOffset));
134      BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
135          .addCFIIndex(CFIIndex);
136    }
137    return;
138  }
139
140  for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
141    unsigned Reg = CSI[i].getReg();
142    int FI = CSI[i].getFrameIdx();
143    switch (Reg) {
144    case ARM::R8:
145    case ARM::R9:
146    case ARM::R10:
147    case ARM::R11:
148      if (STI.isTargetMachO()) {
149        GPRCS2Size += 4;
150        break;
151      }
152      // fallthrough
153    case ARM::R4:
154    case ARM::R5:
155    case ARM::R6:
156    case ARM::R7:
157    case ARM::LR:
158      if (Reg == FramePtr)
159        FramePtrSpillFI = FI;
160      GPRCS1Size += 4;
161      break;
162    default:
163      DPRCSSize += 8;
164    }
165  }
166
167  if (MBBI != MBB.end() && MBBI->getOpcode() == ARM::tPUSH) {
168    ++MBBI;
169    if (MBBI != MBB.end())
170      dl = MBBI->getDebugLoc();
171  }
172
173  // Determine starting offsets of spill areas.
174  unsigned DPRCSOffset  = NumBytes - ArgRegsSaveSize - (GPRCS1Size + GPRCS2Size + DPRCSSize);
175  unsigned GPRCS2Offset = DPRCSOffset + DPRCSSize;
176  unsigned GPRCS1Offset = GPRCS2Offset + GPRCS2Size;
177  bool HasFP = hasFP(MF);
178  if (HasFP)
179    AFI->setFramePtrSpillOffset(MFI->getObjectOffset(FramePtrSpillFI) +
180                                NumBytes);
181  AFI->setGPRCalleeSavedArea1Offset(GPRCS1Offset);
182  AFI->setGPRCalleeSavedArea2Offset(GPRCS2Offset);
183  AFI->setDPRCalleeSavedAreaOffset(DPRCSOffset);
184  NumBytes = DPRCSOffset;
185
186  int FramePtrOffsetInBlock = 0;
187  unsigned adjustedGPRCS1Size = GPRCS1Size;
188  if (tryFoldSPUpdateIntoPushPop(STI, MF, std::prev(MBBI), NumBytes)) {
189    FramePtrOffsetInBlock = NumBytes;
190    adjustedGPRCS1Size += NumBytes;
191    NumBytes = 0;
192  }
193
194  if (adjustedGPRCS1Size) {
195    CFAOffset -= adjustedGPRCS1Size;
196    unsigned CFIIndex = MMI.addFrameInst(
197        MCCFIInstruction::createDefCfaOffset(nullptr, CFAOffset));
198    BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
199        .addCFIIndex(CFIIndex);
200  }
201  for (std::vector<CalleeSavedInfo>::const_iterator I = CSI.begin(),
202         E = CSI.end(); I != E; ++I) {
203    unsigned Reg = I->getReg();
204    int FI = I->getFrameIdx();
205    switch (Reg) {
206    case ARM::R8:
207    case ARM::R9:
208    case ARM::R10:
209    case ARM::R11:
210    case ARM::R12:
211      if (STI.isTargetMachO())
212        break;
213      // fallthough
214    case ARM::R0:
215    case ARM::R1:
216    case ARM::R2:
217    case ARM::R3:
218    case ARM::R4:
219    case ARM::R5:
220    case ARM::R6:
221    case ARM::R7:
222    case ARM::LR:
223      unsigned CFIIndex = MMI.addFrameInst(MCCFIInstruction::createOffset(
224          nullptr, MRI->getDwarfRegNum(Reg, true), MFI->getObjectOffset(FI)));
225      BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
226          .addCFIIndex(CFIIndex);
227      break;
228    }
229  }
230
231
232  // Adjust FP so it point to the stack slot that contains the previous FP.
233  if (HasFP) {
234    FramePtrOffsetInBlock += MFI->getObjectOffset(FramePtrSpillFI)
235		                     + GPRCS1Size + ArgRegsSaveSize;
236    AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tADDrSPi), FramePtr)
237      .addReg(ARM::SP).addImm(FramePtrOffsetInBlock / 4)
238      .setMIFlags(MachineInstr::FrameSetup));
239    if(FramePtrOffsetInBlock) {
240      CFAOffset += FramePtrOffsetInBlock;
241      unsigned CFIIndex = MMI.addFrameInst(MCCFIInstruction::createDefCfa(
242          nullptr, MRI->getDwarfRegNum(FramePtr, true), CFAOffset));
243      BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
244          .addCFIIndex(CFIIndex);
245    } else {
246      unsigned CFIIndex =
247          MMI.addFrameInst(MCCFIInstruction::createDefCfaRegister(
248              nullptr, MRI->getDwarfRegNum(FramePtr, true)));
249      BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
250          .addCFIIndex(CFIIndex);
251    }
252    if (NumBytes > 508)
253      // If offset is > 508 then sp cannot be adjusted in a single instruction,
254      // try restoring from fp instead.
255      AFI->setShouldRestoreSPFromFP(true);
256  }
257
258  if (NumBytes) {
259    // Insert it after all the callee-save spills.
260    emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, -NumBytes,
261                 MachineInstr::FrameSetup);
262    if (!HasFP) {
263      CFAOffset -= NumBytes;
264      unsigned CFIIndex = MMI.addFrameInst(
265          MCCFIInstruction::createDefCfaOffset(nullptr, CFAOffset));
266      BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
267          .addCFIIndex(CFIIndex);
268    }
269  }
270
271  if (STI.isTargetELF() && HasFP)
272    MFI->setOffsetAdjustment(MFI->getOffsetAdjustment() -
273                             AFI->getFramePtrSpillOffset());
274
275  AFI->setGPRCalleeSavedArea1Size(GPRCS1Size);
276  AFI->setGPRCalleeSavedArea2Size(GPRCS2Size);
277  AFI->setDPRCalleeSavedAreaSize(DPRCSSize);
278
279  // Thumb1 does not currently support dynamic stack realignment.  Report a
280  // fatal error rather then silently generate bad code.
281  if (RegInfo->needsStackRealignment(MF))
282      report_fatal_error("Dynamic stack realignment not supported for thumb1.");
283
284  // If we need a base pointer, set it up here. It's whatever the value
285  // of the stack pointer is at this point. Any variable size objects
286  // will be allocated after this, so we can still use the base pointer
287  // to reference locals.
288  if (RegInfo->hasBasePointer(MF))
289    AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), BasePtr)
290                   .addReg(ARM::SP));
291
292  // If the frame has variable sized objects then the epilogue must restore
293  // the sp from fp. We can assume there's an FP here since hasFP already
294  // checks for hasVarSizedObjects.
295  if (MFI->hasVarSizedObjects())
296    AFI->setShouldRestoreSPFromFP(true);
297}
298
299static bool isCSRestore(MachineInstr *MI, const MCPhysReg *CSRegs) {
300  if (MI->getOpcode() == ARM::tLDRspi &&
301      MI->getOperand(1).isFI() &&
302      isCalleeSavedRegister(MI->getOperand(0).getReg(), CSRegs))
303    return true;
304  else if (MI->getOpcode() == ARM::tPOP) {
305    // The first two operands are predicates. The last two are
306    // imp-def and imp-use of SP. Check everything in between.
307    for (int i = 2, e = MI->getNumOperands() - 2; i != e; ++i)
308      if (!isCalleeSavedRegister(MI->getOperand(i).getReg(), CSRegs))
309        return false;
310    return true;
311  }
312  return false;
313}
314
315void Thumb1FrameLowering::emitEpilogue(MachineFunction &MF,
316                                   MachineBasicBlock &MBB) const {
317  MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
318  assert((MBBI->getOpcode() == ARM::tBX_RET ||
319          MBBI->getOpcode() == ARM::tPOP_RET) &&
320         "Can only insert epilog into returning blocks");
321  DebugLoc dl = MBBI->getDebugLoc();
322  MachineFrameInfo *MFI = MF.getFrameInfo();
323  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
324  const Thumb1RegisterInfo *RegInfo =
325    static_cast<const Thumb1RegisterInfo*>(MF.getTarget().getRegisterInfo());
326  const Thumb1InstrInfo &TII =
327    *static_cast<const Thumb1InstrInfo*>(MF.getTarget().getInstrInfo());
328
329  unsigned Align = MF.getTarget().getFrameLowering()->getStackAlignment();
330  unsigned ArgRegsSaveSize = AFI->getArgRegsSaveSize(Align);
331  int NumBytes = (int)MFI->getStackSize();
332  assert((unsigned)NumBytes >= ArgRegsSaveSize &&
333         "ArgRegsSaveSize is included in NumBytes");
334  const MCPhysReg *CSRegs = RegInfo->getCalleeSavedRegs();
335  unsigned FramePtr = RegInfo->getFrameRegister(MF);
336
337  if (!AFI->hasStackFrame()) {
338    if (NumBytes - ArgRegsSaveSize != 0)
339      emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, NumBytes - ArgRegsSaveSize);
340  } else {
341    // Unwind MBBI to point to first LDR / VLDRD.
342    if (MBBI != MBB.begin()) {
343      do
344        --MBBI;
345      while (MBBI != MBB.begin() && isCSRestore(MBBI, CSRegs));
346      if (!isCSRestore(MBBI, CSRegs))
347        ++MBBI;
348    }
349
350    // Move SP to start of FP callee save spill area.
351    NumBytes -= (AFI->getGPRCalleeSavedArea1Size() +
352                 AFI->getGPRCalleeSavedArea2Size() +
353                 AFI->getDPRCalleeSavedAreaSize() +
354                 ArgRegsSaveSize);
355
356    if (AFI->shouldRestoreSPFromFP()) {
357      NumBytes = AFI->getFramePtrSpillOffset() - NumBytes;
358      // Reset SP based on frame pointer only if the stack frame extends beyond
359      // frame pointer stack slot, the target is ELF and the function has FP, or
360      // the target uses var sized objects.
361      if (NumBytes) {
362        assert(MF.getRegInfo().isPhysRegUsed(ARM::R4) &&
363               "No scratch register to restore SP from FP!");
364        emitThumbRegPlusImmediate(MBB, MBBI, dl, ARM::R4, FramePtr, -NumBytes,
365                                  TII, *RegInfo);
366        AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr),
367                               ARM::SP)
368          .addReg(ARM::R4));
369      } else
370        AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr),
371                               ARM::SP)
372          .addReg(FramePtr));
373    } else {
374      if (MBBI->getOpcode() == ARM::tBX_RET &&
375          &MBB.front() != MBBI &&
376          std::prev(MBBI)->getOpcode() == ARM::tPOP) {
377        MachineBasicBlock::iterator PMBBI = std::prev(MBBI);
378        if (!tryFoldSPUpdateIntoPushPop(STI, MF, PMBBI, NumBytes))
379          emitSPUpdate(MBB, PMBBI, TII, dl, *RegInfo, NumBytes);
380      } else if (!tryFoldSPUpdateIntoPushPop(STI, MF, MBBI, NumBytes))
381        emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, NumBytes);
382    }
383  }
384
385  if (ArgRegsSaveSize) {
386    // Unlike T2 and ARM mode, the T1 pop instruction cannot restore
387    // to LR, and we can't pop the value directly to the PC since
388    // we need to update the SP after popping the value. Therefore, we
389    // pop the old LR into R3 as a temporary.
390
391    // Get the last instruction, tBX_RET
392    MBBI = MBB.getLastNonDebugInstr();
393    assert (MBBI->getOpcode() == ARM::tBX_RET);
394    // Epilogue for vararg functions: pop LR to R3 and branch off it.
395    AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tPOP)))
396      .addReg(ARM::R3, RegState::Define);
397
398    emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, ArgRegsSaveSize);
399
400    MachineInstrBuilder MIB =
401      BuildMI(MBB, MBBI, dl, TII.get(ARM::tBX_RET_vararg))
402      .addReg(ARM::R3, RegState::Kill);
403    AddDefaultPred(MIB);
404    MIB.copyImplicitOps(&*MBBI);
405    // erase the old tBX_RET instruction
406    MBB.erase(MBBI);
407  }
408}
409
410bool Thumb1FrameLowering::
411spillCalleeSavedRegisters(MachineBasicBlock &MBB,
412                          MachineBasicBlock::iterator MI,
413                          const std::vector<CalleeSavedInfo> &CSI,
414                          const TargetRegisterInfo *TRI) const {
415  if (CSI.empty())
416    return false;
417
418  DebugLoc DL;
419  MachineFunction &MF = *MBB.getParent();
420  const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
421
422  if (MI != MBB.end()) DL = MI->getDebugLoc();
423
424  MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, TII.get(ARM::tPUSH));
425  AddDefaultPred(MIB);
426  for (unsigned i = CSI.size(); i != 0; --i) {
427    unsigned Reg = CSI[i-1].getReg();
428    bool isKill = true;
429
430    // Add the callee-saved register as live-in unless it's LR and
431    // @llvm.returnaddress is called. If LR is returned for @llvm.returnaddress
432    // then it's already added to the function and entry block live-in sets.
433    if (Reg == ARM::LR) {
434      MachineFunction &MF = *MBB.getParent();
435      if (MF.getFrameInfo()->isReturnAddressTaken() &&
436          MF.getRegInfo().isLiveIn(Reg))
437        isKill = false;
438    }
439
440    if (isKill)
441      MBB.addLiveIn(Reg);
442
443    MIB.addReg(Reg, getKillRegState(isKill));
444  }
445  MIB.setMIFlags(MachineInstr::FrameSetup);
446  return true;
447}
448
449bool Thumb1FrameLowering::
450restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
451                            MachineBasicBlock::iterator MI,
452                            const std::vector<CalleeSavedInfo> &CSI,
453                            const TargetRegisterInfo *TRI) const {
454  if (CSI.empty())
455    return false;
456
457  MachineFunction &MF = *MBB.getParent();
458  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
459  const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
460
461  bool isVarArg = AFI->getArgRegsSaveSize() > 0;
462  DebugLoc DL = MI->getDebugLoc();
463  MachineInstrBuilder MIB = BuildMI(MF, DL, TII.get(ARM::tPOP));
464  AddDefaultPred(MIB);
465
466  bool NumRegs = false;
467  for (unsigned i = CSI.size(); i != 0; --i) {
468    unsigned Reg = CSI[i-1].getReg();
469    if (Reg == ARM::LR) {
470      // Special epilogue for vararg functions. See emitEpilogue
471      if (isVarArg)
472        continue;
473      Reg = ARM::PC;
474      (*MIB).setDesc(TII.get(ARM::tPOP_RET));
475      MIB.copyImplicitOps(&*MI);
476      MI = MBB.erase(MI);
477    }
478    MIB.addReg(Reg, getDefRegState(true));
479    NumRegs = true;
480  }
481
482  // It's illegal to emit pop instruction without operands.
483  if (NumRegs)
484    MBB.insert(MI, &*MIB);
485  else
486    MF.DeleteMachineInstr(MIB);
487
488  return true;
489}
490