[Clang/AMDGPU] Zero sized arrays not allowed in HIP device code. (#113470)
[llvm-project.git] / llvm / lib / Target / MSP430 / MSP430FrameLowering.cpp
blob76d6e8a324ae545ae53edd242df5c3bf796e852f
1 //===-- MSP430FrameLowering.cpp - MSP430 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 MSP430 implementation of TargetFrameLowering class.
11 //===----------------------------------------------------------------------===//
13 #include "MSP430FrameLowering.h"
14 #include "MSP430InstrInfo.h"
15 #include "MSP430MachineFunctionInfo.h"
16 #include "MSP430Subtarget.h"
17 #include "llvm/CodeGen/MachineFrameInfo.h"
18 #include "llvm/CodeGen/MachineFunction.h"
19 #include "llvm/CodeGen/MachineInstrBuilder.h"
20 #include "llvm/CodeGen/MachineModuleInfo.h"
21 #include "llvm/Target/TargetOptions.h"
23 using namespace llvm;
25 MSP430FrameLowering::MSP430FrameLowering(const MSP430Subtarget &STI)
26 : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, Align(2), -2,
27 Align(2)),
28 STI(STI), TII(*STI.getInstrInfo()), TRI(STI.getRegisterInfo()) {}
30 bool MSP430FrameLowering::hasFPImpl(const MachineFunction &MF) const {
31 const MachineFrameInfo &MFI = MF.getFrameInfo();
33 return (MF.getTarget().Options.DisableFramePointerElim(MF) ||
34 MF.getFrameInfo().hasVarSizedObjects() ||
35 MFI.isFrameAddressTaken());
38 bool MSP430FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
39 return !MF.getFrameInfo().hasVarSizedObjects();
42 void MSP430FrameLowering::BuildCFI(MachineBasicBlock &MBB,
43 MachineBasicBlock::iterator MBBI,
44 const DebugLoc &DL,
45 const MCCFIInstruction &CFIInst,
46 MachineInstr::MIFlag Flag) const {
47 MachineFunction &MF = *MBB.getParent();
48 unsigned CFIIndex = MF.addFrameInst(CFIInst);
49 BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
50 .addCFIIndex(CFIIndex)
51 .setMIFlag(Flag);
54 void MSP430FrameLowering::emitCalleeSavedFrameMoves(
55 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
56 const DebugLoc &DL, bool IsPrologue) const {
57 MachineFunction &MF = *MBB.getParent();
58 MachineFrameInfo &MFI = MF.getFrameInfo();
59 const MCRegisterInfo *MRI = MF.getContext().getRegisterInfo();
61 // Add callee saved registers to move list.
62 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
64 // Calculate offsets.
65 for (const CalleeSavedInfo &I : CSI) {
66 int64_t Offset = MFI.getObjectOffset(I.getFrameIdx());
67 Register Reg = I.getReg();
68 unsigned DwarfReg = MRI->getDwarfRegNum(Reg, true);
70 if (IsPrologue) {
71 BuildCFI(MBB, MBBI, DL,
72 MCCFIInstruction::createOffset(nullptr, DwarfReg, Offset));
73 } else {
74 BuildCFI(MBB, MBBI, DL,
75 MCCFIInstruction::createRestore(nullptr, DwarfReg));
80 void MSP430FrameLowering::emitPrologue(MachineFunction &MF,
81 MachineBasicBlock &MBB) const {
82 assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported");
83 MachineFrameInfo &MFI = MF.getFrameInfo();
84 MSP430MachineFunctionInfo *MSP430FI = MF.getInfo<MSP430MachineFunctionInfo>();
85 const MSP430InstrInfo &TII =
86 *static_cast<const MSP430InstrInfo *>(MF.getSubtarget().getInstrInfo());
88 MachineBasicBlock::iterator MBBI = MBB.begin();
89 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
91 // Get the number of bytes to allocate from the FrameInfo.
92 uint64_t StackSize = MFI.getStackSize();
93 int stackGrowth = -2;
95 uint64_t NumBytes = 0;
96 if (hasFP(MF)) {
97 // Calculate required stack adjustment
98 uint64_t FrameSize = StackSize - 2;
99 NumBytes = FrameSize - MSP430FI->getCalleeSavedFrameSize();
101 // Get the offset of the stack slot for the EBP register... which is
102 // guaranteed to be the last slot by processFunctionBeforeFrameFinalized.
103 // Update the frame offset adjustment.
104 MFI.setOffsetAdjustment(-NumBytes);
106 // Save FP into the appropriate stack slot...
107 BuildMI(MBB, MBBI, DL, TII.get(MSP430::PUSH16r))
108 .addReg(MSP430::R4, RegState::Kill)
109 .setMIFlag(MachineInstr::FrameSetup);
111 // Mark the place where FP was saved.
112 // Define the current CFA rule to use the provided offset.
113 BuildCFI(MBB, MBBI, DL,
114 MCCFIInstruction::cfiDefCfaOffset(nullptr, -2 * stackGrowth),
115 MachineInstr::FrameSetup);
117 // Change the rule for the FramePtr to be an "offset" rule.
118 unsigned DwarfFramePtr = TRI->getDwarfRegNum(MSP430::R4, true);
119 BuildCFI(
120 MBB, MBBI, DL,
121 MCCFIInstruction::createOffset(nullptr, DwarfFramePtr, 2 * stackGrowth),
122 MachineInstr::FrameSetup);
124 // Update FP with the new base value...
125 BuildMI(MBB, MBBI, DL, TII.get(MSP430::MOV16rr), MSP430::R4)
126 .addReg(MSP430::SP)
127 .setMIFlag(MachineInstr::FrameSetup);
129 // Mark effective beginning of when frame pointer becomes valid.
130 // Define the current CFA to use the FP register.
131 BuildCFI(MBB, MBBI, DL,
132 MCCFIInstruction::createDefCfaRegister(nullptr, DwarfFramePtr),
133 MachineInstr::FrameSetup);
135 // Mark the FramePtr as live-in in every block except the entry.
136 for (MachineBasicBlock &MBBJ : llvm::drop_begin(MF))
137 MBBJ.addLiveIn(MSP430::R4);
138 } else
139 NumBytes = StackSize - MSP430FI->getCalleeSavedFrameSize();
141 // Skip the callee-saved push instructions.
142 int StackOffset = 2 * stackGrowth;
143 while (MBBI != MBB.end() && MBBI->getFlag(MachineInstr::FrameSetup) &&
144 (MBBI->getOpcode() == MSP430::PUSH16r)) {
145 ++MBBI;
147 if (!hasFP(MF)) {
148 // Mark callee-saved push instruction.
149 // Define the current CFA rule to use the provided offset.
150 assert(StackSize && "Expected stack frame");
151 BuildCFI(MBB, MBBI, DL,
152 MCCFIInstruction::cfiDefCfaOffset(nullptr, -StackOffset),
153 MachineInstr::FrameSetup);
154 StackOffset += stackGrowth;
158 if (MBBI != MBB.end())
159 DL = MBBI->getDebugLoc();
161 if (NumBytes) { // adjust stack pointer: SP -= numbytes
162 // If there is an SUB16ri of SP immediately before this instruction, merge
163 // the two.
164 //NumBytes -= mergeSPUpdates(MBB, MBBI, true);
165 // If there is an ADD16ri or SUB16ri of SP immediately after this
166 // instruction, merge the two instructions.
167 // mergeSPUpdatesDown(MBB, MBBI, &NumBytes);
169 if (NumBytes) {
170 MachineInstr *MI =
171 BuildMI(MBB, MBBI, DL, TII.get(MSP430::SUB16ri), MSP430::SP)
172 .addReg(MSP430::SP)
173 .addImm(NumBytes)
174 .setMIFlag(MachineInstr::FrameSetup);
175 // The SRW implicit def is dead.
176 MI->getOperand(3).setIsDead();
178 if (!hasFP(MF)) {
179 // Adjust the previous CFA value if CFA was not redefined by FP
180 BuildCFI(
181 MBB, MBBI, DL,
182 MCCFIInstruction::cfiDefCfaOffset(nullptr, StackSize - stackGrowth),
183 MachineInstr::FrameSetup);
187 emitCalleeSavedFrameMoves(MBB, MBBI, DL, true);
190 void MSP430FrameLowering::emitEpilogue(MachineFunction &MF,
191 MachineBasicBlock &MBB) const {
192 const MachineFrameInfo &MFI = MF.getFrameInfo();
193 MSP430MachineFunctionInfo *MSP430FI = MF.getInfo<MSP430MachineFunctionInfo>();
194 const MSP430InstrInfo &TII =
195 *static_cast<const MSP430InstrInfo *>(MF.getSubtarget().getInstrInfo());
197 MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
198 unsigned RetOpcode = MBBI->getOpcode();
199 DebugLoc DL = MBBI->getDebugLoc();
201 switch (RetOpcode) {
202 case MSP430::RET:
203 case MSP430::RETI: break; // These are ok
204 default:
205 llvm_unreachable("Can only insert epilog into returning blocks");
208 // Get the number of bytes to allocate from the FrameInfo
209 uint64_t StackSize = MFI.getStackSize();
210 unsigned CSSize = MSP430FI->getCalleeSavedFrameSize();
211 uint64_t NumBytes = 0;
213 MachineBasicBlock::iterator AfterPop = MBBI;
214 if (hasFP(MF)) {
215 // Calculate required stack adjustment
216 uint64_t FrameSize = StackSize - 2;
217 NumBytes = FrameSize - CSSize;
219 // pop FP.
220 BuildMI(MBB, MBBI, DL, TII.get(MSP430::POP16r), MSP430::R4)
221 .setMIFlag(MachineInstr::FrameDestroy);
222 unsigned DwarfStackPtr = TRI->getDwarfRegNum(MSP430::SP, true);
223 BuildCFI(MBB, MBBI, DL,
224 MCCFIInstruction::cfiDefCfa(nullptr, DwarfStackPtr, 2),
225 MachineInstr::FrameDestroy);
226 --MBBI;
227 if (!MBB.succ_empty() && !MBB.isReturnBlock()) {
228 unsigned DwarfFramePtr = TRI->getDwarfRegNum(MSP430::R4, true);
229 BuildCFI(MBB, AfterPop, DL,
230 MCCFIInstruction::createRestore(nullptr, DwarfFramePtr),
231 MachineInstr::FrameDestroy);
232 --MBBI;
233 --AfterPop;
235 } else
236 NumBytes = StackSize - CSSize;
238 // Skip the callee-saved pop instructions.
239 MachineBasicBlock::iterator FirstCSPop = MBBI;
240 while (MBBI != MBB.begin()) {
241 MachineBasicBlock::iterator PI = std::prev(MBBI);
242 unsigned Opc = PI->getOpcode();
243 if ((Opc != MSP430::POP16r || !PI->getFlag(MachineInstr::FrameDestroy)) &&
244 !PI->isTerminator())
245 break;
246 FirstCSPop = PI;
247 --MBBI;
249 MBBI = FirstCSPop;
251 DL = MBBI->getDebugLoc();
253 // If there is an ADD16ri or SUB16ri of SP immediately before this
254 // instruction, merge the two instructions.
255 //if (NumBytes || MFI.hasVarSizedObjects())
256 // mergeSPUpdatesUp(MBB, MBBI, StackPtr, &NumBytes);
258 if (MFI.hasVarSizedObjects()) {
259 BuildMI(MBB, MBBI, DL, TII.get(MSP430::MOV16rr), MSP430::SP)
260 .addReg(MSP430::R4)
261 .setMIFlag(MachineInstr::FrameDestroy);
262 if (CSSize) {
263 MachineInstr *MI =
264 BuildMI(MBB, MBBI, DL, TII.get(MSP430::SUB16ri), MSP430::SP)
265 .addReg(MSP430::SP)
266 .addImm(CSSize)
267 .setMIFlag(MachineInstr::FrameDestroy);
268 // The SRW implicit def is dead.
269 MI->getOperand(3).setIsDead();
271 } else {
272 // adjust stack pointer back: SP += numbytes
273 if (NumBytes) {
274 MachineInstr *MI =
275 BuildMI(MBB, MBBI, DL, TII.get(MSP430::ADD16ri), MSP430::SP)
276 .addReg(MSP430::SP)
277 .addImm(NumBytes)
278 .setMIFlag(MachineInstr::FrameDestroy);
279 // The SRW implicit def is dead.
280 MI->getOperand(3).setIsDead();
282 if (!hasFP(MF)) {
283 // Adjust CFA value if it was defined by SP
284 BuildCFI(MBB, MBBI, DL,
285 MCCFIInstruction::cfiDefCfaOffset(nullptr, CSSize + 2),
286 MachineInstr::FrameDestroy);
291 if (!hasFP(MF)) {
292 MBBI = FirstCSPop;
293 int64_t Offset = -(int64_t)CSSize - 2;
294 // Mark callee-saved pop instruction.
295 // Define the current CFA rule to use the provided offset.
296 while (MBBI != MBB.end()) {
297 MachineBasicBlock::iterator PI = MBBI;
298 unsigned Opc = PI->getOpcode();
299 ++MBBI;
300 if (Opc == MSP430::POP16r) {
301 Offset += 2;
302 BuildCFI(MBB, MBBI, DL,
303 MCCFIInstruction::cfiDefCfaOffset(nullptr, -Offset),
304 MachineInstr::FrameDestroy);
308 emitCalleeSavedFrameMoves(MBB, AfterPop, DL, false);
311 // FIXME: Can we eleminate these in favour of generic code?
312 bool MSP430FrameLowering::spillCalleeSavedRegisters(
313 MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
314 ArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {
315 if (CSI.empty())
316 return false;
318 DebugLoc DL;
319 if (MI != MBB.end()) DL = MI->getDebugLoc();
321 MachineFunction &MF = *MBB.getParent();
322 const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
323 MSP430MachineFunctionInfo *MFI = MF.getInfo<MSP430MachineFunctionInfo>();
324 MFI->setCalleeSavedFrameSize(CSI.size() * 2);
326 for (const CalleeSavedInfo &I : CSI) {
327 Register Reg = I.getReg();
328 // Add the callee-saved register as live-in. It's killed at the spill.
329 MBB.addLiveIn(Reg);
330 BuildMI(MBB, MI, DL, TII.get(MSP430::PUSH16r))
331 .addReg(Reg, RegState::Kill)
332 .setMIFlag(MachineInstr::FrameSetup);
334 return true;
337 bool MSP430FrameLowering::restoreCalleeSavedRegisters(
338 MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
339 MutableArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {
340 if (CSI.empty())
341 return false;
343 DebugLoc DL;
344 if (MI != MBB.end()) DL = MI->getDebugLoc();
346 MachineFunction &MF = *MBB.getParent();
347 const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
349 for (const CalleeSavedInfo &I : llvm::reverse(CSI))
350 BuildMI(MBB, MI, DL, TII.get(MSP430::POP16r), I.getReg())
351 .setMIFlag(MachineInstr::FrameDestroy);
353 return true;
356 MachineBasicBlock::iterator MSP430FrameLowering::eliminateCallFramePseudoInstr(
357 MachineFunction &MF, MachineBasicBlock &MBB,
358 MachineBasicBlock::iterator I) const {
359 const MSP430InstrInfo &TII =
360 *static_cast<const MSP430InstrInfo *>(MF.getSubtarget().getInstrInfo());
361 if (!hasReservedCallFrame(MF)) {
362 // If the stack pointer can be changed after prologue, turn the
363 // adjcallstackup instruction into a 'sub SP, <amt>' and the
364 // adjcallstackdown instruction into 'add SP, <amt>'
365 // TODO: consider using push / pop instead of sub + store / add
366 MachineInstr &Old = *I;
367 uint64_t Amount = TII.getFrameSize(Old);
368 if (Amount != 0) {
369 // We need to keep the stack aligned properly. To do this, we round the
370 // amount of space needed for the outgoing arguments up to the next
371 // alignment boundary.
372 Amount = alignTo(Amount, getStackAlign());
374 MachineInstr *New = nullptr;
375 if (Old.getOpcode() == TII.getCallFrameSetupOpcode()) {
376 New =
377 BuildMI(MF, Old.getDebugLoc(), TII.get(MSP430::SUB16ri), MSP430::SP)
378 .addReg(MSP430::SP)
379 .addImm(Amount);
380 } else {
381 assert(Old.getOpcode() == TII.getCallFrameDestroyOpcode());
382 // factor out the amount the callee already popped.
383 Amount -= TII.getFramePoppedByCallee(Old);
384 if (Amount)
385 New = BuildMI(MF, Old.getDebugLoc(), TII.get(MSP430::ADD16ri),
386 MSP430::SP)
387 .addReg(MSP430::SP)
388 .addImm(Amount);
391 if (New) {
392 // The SRW implicit def is dead.
393 New->getOperand(3).setIsDead();
395 // Replace the pseudo instruction with a new instruction...
396 MBB.insert(I, New);
399 } else if (I->getOpcode() == TII.getCallFrameDestroyOpcode()) {
400 // If we are performing frame pointer elimination and if the callee pops
401 // something off the stack pointer, add it back.
402 if (uint64_t CalleeAmt = TII.getFramePoppedByCallee(*I)) {
403 MachineInstr &Old = *I;
404 MachineInstr *New =
405 BuildMI(MF, Old.getDebugLoc(), TII.get(MSP430::SUB16ri), MSP430::SP)
406 .addReg(MSP430::SP)
407 .addImm(CalleeAmt);
408 if (!hasFP(MF)) {
409 DebugLoc DL = I->getDebugLoc();
410 BuildCFI(MBB, I, DL,
411 MCCFIInstruction::createAdjustCfaOffset(nullptr, CalleeAmt));
413 // The SRW implicit def is dead.
414 New->getOperand(3).setIsDead();
416 MBB.insert(I, New);
420 return MBB.erase(I);
423 void
424 MSP430FrameLowering::processFunctionBeforeFrameFinalized(MachineFunction &MF,
425 RegScavenger *) const {
426 // Create a frame entry for the FP register that must be saved.
427 if (hasFP(MF)) {
428 int FrameIdx = MF.getFrameInfo().CreateFixedObject(2, -4, true);
429 (void)FrameIdx;
430 assert(FrameIdx == MF.getFrameInfo().getObjectIndexBegin() &&
431 "Slot for FP register must be last in order to be found!");