xref: /llvm-project/llvm/lib/Target/Xtensa/XtensaFrameLowering.cpp (revision 1a935d7a17519e9b75d12c3caf9a54a3405a0af3)
1 //===- XtensaFrameLowering.cpp - Xtensa Frame Information -----------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains the Xtensa implementation of TargetFrameLowering class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "XtensaFrameLowering.h"
14 #include "XtensaInstrInfo.h"
15 #include "XtensaMachineFunctionInfo.h"
16 #include "XtensaSubtarget.h"
17 #include "llvm/CodeGen/MachineFrameInfo.h"
18 #include "llvm/CodeGen/MachineInstrBuilder.h"
19 #include "llvm/CodeGen/MachineModuleInfo.h"
20 #include "llvm/CodeGen/MachineRegisterInfo.h"
21 #include "llvm/CodeGen/RegisterScavenging.h"
22 #include "llvm/IR/Function.h"
23 
24 using namespace llvm;
25 
26 XtensaFrameLowering::XtensaFrameLowering(const XtensaSubtarget &STI)
27     : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, Align(4), 0,
28                           Align(4)),
29       TII(*STI.getInstrInfo()), TRI(STI.getRegisterInfo()) {}
30 
31 bool XtensaFrameLowering::hasFPImpl(const MachineFunction &MF) const {
32   const MachineFrameInfo &MFI = MF.getFrameInfo();
33   return MF.getTarget().Options.DisableFramePointerElim(MF) ||
34          MFI.hasVarSizedObjects();
35 }
36 
37 void XtensaFrameLowering::emitPrologue(MachineFunction &MF,
38                                        MachineBasicBlock &MBB) const {
39   assert(&MBB == &MF.front() && "Shrink-wrapping not yet implemented");
40   MachineFrameInfo &MFI = MF.getFrameInfo();
41   MachineBasicBlock::iterator MBBI = MBB.begin();
42   DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
43   MCRegister SP = Xtensa::SP;
44   MCRegister FP = TRI->getFrameRegister(MF);
45   const MCRegisterInfo *MRI = MF.getContext().getRegisterInfo();
46 
47   // First, compute final stack size.
48   uint64_t StackSize = MFI.getStackSize();
49   uint64_t PrevStackSize = StackSize;
50 
51   // Round up StackSize to 16*N
52   StackSize += (16 - StackSize) & 0xf;
53 
54   // No need to allocate space on the stack.
55   if (StackSize == 0 && !MFI.adjustsStack())
56     return;
57 
58   // Adjust stack.
59   TII.adjustStackPtr(SP, -StackSize, MBB, MBBI);
60 
61   // emit ".cfi_def_cfa_offset StackSize"
62   unsigned CFIIndex =
63       MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, StackSize));
64   BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
65       .addCFIIndex(CFIIndex);
66 
67   const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
68 
69   if (!CSI.empty()) {
70     // Find the instruction past the last instruction that saves a
71     // callee-saved register to the stack. The callee-saved store
72     // instructions are placed at the begin of basic block, so
73     //  iterate over instruction sequence and check that
74     // save instructions are placed correctly.
75     for (unsigned i = 0, e = CSI.size(); i < e; ++i) {
76 #ifndef NDEBUG
77       const CalleeSavedInfo &Info = CSI[i];
78       int FI = Info.getFrameIdx();
79       int StoreFI = 0;
80 
81       // Checking that the instruction is exactly as expected
82       bool IsStoreInst = false;
83       if (MBBI->getOpcode() == TargetOpcode::COPY && Info.isSpilledToReg()) {
84         Register DstReg = MBBI->getOperand(0).getReg();
85         Register Reg = MBBI->getOperand(1).getReg();
86         IsStoreInst = (Info.getDstReg() == DstReg) && (Info.getReg() == Reg);
87       } else {
88         Register Reg = TII.isStoreToStackSlot(*MBBI, StoreFI);
89         IsStoreInst = (Reg == Info.getReg()) && (StoreFI == FI);
90       }
91       assert(IsStoreInst &&
92              "Unexpected callee-saved register store instruction");
93 #endif
94       ++MBBI;
95     }
96 
97     // Iterate over list of callee-saved registers and emit .cfi_offset
98     // directives.
99     for (const auto &I : CSI) {
100       int64_t Offset = MFI.getObjectOffset(I.getFrameIdx());
101       Register Reg = I.getReg();
102 
103       unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset(
104           nullptr, MRI->getDwarfRegNum(Reg, 1), Offset));
105       BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
106           .addCFIIndex(CFIIndex);
107     }
108   }
109 
110   // if framepointer enabled, set it to point to the stack pointer.
111   if (hasFP(MF)) {
112     // Insert instruction "move $fp, $sp" at this location.
113     BuildMI(MBB, MBBI, DL, TII.get(Xtensa::OR), FP)
114         .addReg(SP)
115         .addReg(SP)
116         .setMIFlag(MachineInstr::FrameSetup);
117 
118     // emit ".cfi_def_cfa_register $fp"
119     unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createDefCfaRegister(
120         nullptr, MRI->getDwarfRegNum(FP, true)));
121     BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
122         .addCFIIndex(CFIIndex);
123   }
124 
125   if (StackSize != PrevStackSize) {
126     MFI.setStackSize(StackSize);
127 
128     for (int i = MFI.getObjectIndexBegin(); i < MFI.getObjectIndexEnd(); i++) {
129       if (!MFI.isDeadObjectIndex(i)) {
130         int64_t SPOffset = MFI.getObjectOffset(i);
131 
132         if (SPOffset < 0)
133           MFI.setObjectOffset(i, SPOffset - StackSize + PrevStackSize);
134       }
135     }
136   }
137 }
138 
139 void XtensaFrameLowering::emitEpilogue(MachineFunction &MF,
140                                        MachineBasicBlock &MBB) const {
141   MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
142   MachineFrameInfo &MFI = MF.getFrameInfo();
143   DebugLoc DL = MBBI->getDebugLoc();
144   MCRegister SP = Xtensa::SP;
145   MCRegister FP = TRI->getFrameRegister(MF);
146 
147   // if framepointer enabled, restore the stack pointer.
148   if (hasFP(MF)) {
149     // We should place restore stack pointer instruction just before
150     // sequence of instructions which restores callee-saved registers.
151     // This sequence is placed at the end of the basic block,
152     // so we should find first instruction of the sequence.
153     MachineBasicBlock::iterator I = MBBI;
154 
155     const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
156 
157     // Find the first instruction at the end that restores a callee-saved
158     // register.
159     for (unsigned i = 0, e = CSI.size(); i < e; ++i) {
160       --I;
161 #ifndef NDEBUG
162       const CalleeSavedInfo &Info = CSI[i];
163       int FI = Info.getFrameIdx();
164       int LoadFI = 0;
165 
166       // Checking that the instruction is exactly as expected
167       bool IsRestoreInst = false;
168       if (I->getOpcode() == TargetOpcode::COPY && Info.isSpilledToReg()) {
169         Register Reg = I->getOperand(0).getReg();
170         Register DstReg = I->getOperand(1).getReg();
171         IsRestoreInst = (Info.getDstReg() == DstReg) && (Info.getReg() == Reg);
172       } else {
173         Register Reg = TII.isLoadFromStackSlot(*I, LoadFI);
174         IsRestoreInst = (Info.getReg() == Reg) && (LoadFI == FI);
175       }
176       assert(IsRestoreInst &&
177              "Unexpected callee-saved register restore instruction");
178 #endif
179     }
180 
181     BuildMI(MBB, I, DL, TII.get(Xtensa::OR), SP).addReg(FP).addReg(FP);
182   }
183 
184   // Get the number of bytes from FrameInfo
185   uint64_t StackSize = MFI.getStackSize();
186 
187   if (!StackSize)
188     return;
189 
190   // Adjust stack.
191   TII.adjustStackPtr(SP, StackSize, MBB, MBBI);
192 }
193 
194 bool XtensaFrameLowering::spillCalleeSavedRegisters(
195     MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
196     ArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {
197   MachineFunction *MF = MBB.getParent();
198   MachineBasicBlock &EntryBlock = *(MF->begin());
199 
200   for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
201     // Add the callee-saved register as live-in. Do not add if the register is
202     // A0 and return address is taken, because it will be implemented in
203     // method XtensaTargetLowering::LowerRETURNADDR.
204     // It's killed at the spill, unless the register is RA and return address
205     // is taken.
206     Register Reg = CSI[i].getReg();
207     bool IsA0AndRetAddrIsTaken =
208         (Reg == Xtensa::A0) && MF->getFrameInfo().isReturnAddressTaken();
209     if (!IsA0AndRetAddrIsTaken)
210       EntryBlock.addLiveIn(Reg);
211 
212     // Insert the spill to the stack frame.
213     bool IsKill = !IsA0AndRetAddrIsTaken;
214     const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
215     TII.storeRegToStackSlot(EntryBlock, MI, Reg, IsKill, CSI[i].getFrameIdx(),
216                             RC, TRI, Register());
217   }
218 
219   return true;
220 }
221 
222 bool XtensaFrameLowering::restoreCalleeSavedRegisters(
223     MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
224     MutableArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {
225   return TargetFrameLowering::restoreCalleeSavedRegisters(MBB, MI, CSI, TRI);
226 }
227 
228 // Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions
229 MachineBasicBlock::iterator XtensaFrameLowering::eliminateCallFramePseudoInstr(
230     MachineFunction &MF, MachineBasicBlock &MBB,
231     MachineBasicBlock::iterator I) const {
232   const XtensaInstrInfo &TII =
233       *static_cast<const XtensaInstrInfo *>(MF.getSubtarget().getInstrInfo());
234 
235   if (!hasReservedCallFrame(MF)) {
236     int64_t Amount = I->getOperand(0).getImm();
237 
238     if (I->getOpcode() == Xtensa::ADJCALLSTACKDOWN)
239       Amount = -Amount;
240 
241     TII.adjustStackPtr(Xtensa::SP, Amount, MBB, I);
242   }
243 
244   return MBB.erase(I);
245 }
246 
247 void XtensaFrameLowering::determineCalleeSaves(MachineFunction &MF,
248                                                BitVector &SavedRegs,
249                                                RegScavenger *RS) const {
250   unsigned FP = TRI->getFrameRegister(MF);
251 
252   TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
253 
254   // Mark $fp as used if function has dedicated frame pointer.
255   if (hasFP(MF))
256     SavedRegs.set(FP);
257 }
258 
259 void XtensaFrameLowering::processFunctionBeforeFrameFinalized(
260     MachineFunction &MF, RegScavenger *RS) const {
261   // Set scavenging frame index if necessary.
262   MachineFrameInfo &MFI = MF.getFrameInfo();
263   uint64_t MaxSPOffset = MFI.estimateStackSize(MF);
264   auto *XtensaFI = MF.getInfo<XtensaMachineFunctionInfo>();
265   unsigned ScavSlotsNum = 0;
266 
267   if (!isInt<12>(MaxSPOffset))
268     ScavSlotsNum = 1;
269 
270   // Far branches over 18-bit offset require a spill slot for scratch register.
271   bool IsLargeFunction = !isInt<18>(MF.estimateFunctionSizeInBytes());
272   if (IsLargeFunction)
273     ScavSlotsNum = std::max(ScavSlotsNum, 1u);
274 
275   const TargetRegisterClass &RC = Xtensa::ARRegClass;
276   unsigned Size = TRI->getSpillSize(RC);
277   Align Alignment = TRI->getSpillAlign(RC);
278   for (unsigned I = 0; I < ScavSlotsNum; I++) {
279     int FI = MFI.CreateSpillStackObject(Size, Alignment);
280     RS->addScavengingFrameIndex(FI);
281 
282     if (IsLargeFunction &&
283         XtensaFI->getBranchRelaxationScratchFrameIndex() == -1)
284       XtensaFI->setBranchRelaxationScratchFrameIndex(FI);
285   }
286 }
287