]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/ARC/ARCFrameLowering.cpp
Merge llvm, clang, lld, lldb, compiler-rt and libc++ trunk r321545,
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / ARC / ARCFrameLowering.cpp
1 //===- ARCFrameLowering.cpp - ARC Frame Information -------------*- C++ -*-===//
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 ARC implementation of the TargetFrameLowering class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "ARCFrameLowering.h"
15 #include "ARCMachineFunctionInfo.h"
16 #include "ARCSubtarget.h"
17 #include "llvm/CodeGen/MachineInstrBuilder.h"
18 #include "llvm/CodeGen/MachineModuleInfo.h"
19 #include "llvm/CodeGen/RegisterScavenging.h"
20 #include "llvm/CodeGen/TargetRegisterInfo.h"
21 #include "llvm/IR/Function.h"
22 #include "llvm/Support/Debug.h"
23
24 #define DEBUG_TYPE "arc-frame-lowering"
25
26 using namespace llvm;
27
28 static cl::opt<bool>
29     UseSaveRestoreFunclet("arc-save-restore-funclet", cl::Hidden,
30                           cl::desc("Use arc callee save/restore functions"),
31                           cl::init(true));
32
33 static const char *store_funclet_name[] = {
34     "__st_r13_to_r15", "__st_r13_to_r16", "__st_r13_to_r17", "__st_r13_to_r18",
35     "__st_r13_to_r19", "__st_r13_to_r20", "__st_r13_to_r21", "__st_r13_to_r22",
36     "__st_r13_to_r23", "__st_r13_to_r24", "__st_r13_to_r25",
37 };
38
39 static const char *load_funclet_name[] = {
40     "__ld_r13_to_r15", "__ld_r13_to_r16", "__ld_r13_to_r17", "__ld_r13_to_r18",
41     "__ld_r13_to_r19", "__ld_r13_to_r20", "__ld_r13_to_r21", "__ld_r13_to_r22",
42     "__ld_r13_to_r23", "__ld_r13_to_r24", "__ld_r13_to_r25",
43 };
44
45 static void generateStackAdjustment(MachineBasicBlock &MBB,
46                                     MachineBasicBlock::iterator MBBI,
47                                     const ARCInstrInfo &TII, DebugLoc dl,
48                                     int Amount, int StackPtr) {
49   unsigned AdjOp;
50   if (!Amount)
51     return;
52   bool Positive;
53   unsigned AbsAmount;
54   if (Amount < 0) {
55     AbsAmount = -Amount;
56     Positive = false;
57   } else {
58     AbsAmount = Amount;
59     Positive = true;
60   }
61
62   DEBUG(dbgs() << "Internal: adjust stack by: " << Amount << "," << AbsAmount
63                << "\n");
64
65   assert((AbsAmount % 4 == 0) && "Stack adjustments must be 4-byte aligned.");
66   if (isUInt<6>(AbsAmount))
67     AdjOp = Positive ? ARC::ADD_rru6 : ARC::SUB_rru6;
68   else
69     AdjOp = Positive ? ARC::ADD_rrlimm : ARC::SUB_rrlimm;
70
71   BuildMI(MBB, MBBI, dl, TII.get(AdjOp), StackPtr)
72       .addReg(StackPtr)
73       .addImm(AbsAmount);
74 }
75
76 static unsigned
77 determineLastCalleeSave(const std::vector<CalleeSavedInfo> &CSI) {
78   unsigned Last = 0;
79   for (auto Reg : CSI) {
80     assert(Reg.getReg() >= ARC::R13 && Reg.getReg() <= ARC::R25 &&
81            "Unexpected callee saved reg.");
82     if (Reg.getReg() > Last)
83       Last = Reg.getReg();
84   }
85   return Last;
86 }
87
88 void ARCFrameLowering::determineCalleeSaves(MachineFunction &MF,
89                                             BitVector &SavedRegs,
90                                             RegScavenger *RS) const {
91   DEBUG(dbgs() << "Determine Callee Saves: " << MF.getName()
92                << "\n");
93   TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
94   SavedRegs.set(ARC::BLINK);
95 }
96
97 void ARCFrameLowering::adjustStackToMatchRecords(
98     MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
99     bool Allocate) const {
100   MachineFunction &MF = *MBB.getParent();
101   int ScalarAlloc = MF.getFrameInfo().getStackSize();
102
103   if (Allocate) {
104     // Allocate by adjusting by the negative of what the record holder tracked
105     // it tracked a positive offset in a downward growing stack.
106     ScalarAlloc = -ScalarAlloc;
107   }
108
109   generateStackAdjustment(MBB, MBBI, *ST.getInstrInfo(), DebugLoc(),
110                           ScalarAlloc, ARC::SP);
111 }
112
113 /// Insert prolog code into the function.
114 /// For ARC, this inserts a call to a function that puts required callee saved
115 /// registers onto the stack, when enough callee saved registers are required.
116 void ARCFrameLowering::emitPrologue(MachineFunction &MF,
117                                     MachineBasicBlock &MBB) const {
118   DEBUG(dbgs() << "Emit Prologue: " << MF.getName() << "\n");
119   auto *AFI = MF.getInfo<ARCFunctionInfo>();
120   MachineModuleInfo &MMI = MF.getMMI();
121   MCContext &Context = MMI.getContext();
122   const MCRegisterInfo *MRI = Context.getRegisterInfo();
123   const ARCInstrInfo *TII = MF.getSubtarget<ARCSubtarget>().getInstrInfo();
124   MachineBasicBlock::iterator MBBI = MBB.begin();
125   // Debug location must be unknown since the first debug location is used
126   // to determine the end of the prologue.
127   DebugLoc dl;
128   MachineFrameInfo &MFI = MF.getFrameInfo();
129   const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
130   unsigned Last = determineLastCalleeSave(CSI);
131   unsigned StackSlotsUsedByFunclet = 0;
132   bool SavedBlink = false;
133   unsigned AlreadyAdjusted = 0;
134   if (MF.getFunction().isVarArg()) {
135     // Add in the varargs area here first.
136     DEBUG(dbgs() << "Varargs\n");
137     unsigned VarArgsBytes = MFI.getObjectSize(AFI->getVarArgsFrameIndex());
138     BuildMI(MBB, MBBI, dl, TII->get(ARC::SUB_rru6))
139         .addReg(ARC::SP)
140         .addReg(ARC::SP)
141         .addImm(VarArgsBytes);
142   }
143   if (hasFP(MF)) {
144     DEBUG(dbgs() << "Saving FP\n");
145     BuildMI(MBB, MBBI, dl, TII->get(ARC::ST_AW_rs9))
146         .addReg(ARC::SP, RegState::Define)
147         .addReg(ARC::FP)
148         .addReg(ARC::SP)
149         .addImm(-4);
150     AlreadyAdjusted += 4;
151   }
152   if (UseSaveRestoreFunclet && Last > ARC::R14) {
153     DEBUG(dbgs() << "Creating store funclet.\n");
154     // BL to __save_r13_to_<TRI->getRegAsmName()>
155     StackSlotsUsedByFunclet = Last - ARC::R12;
156     BuildMI(MBB, MBBI, dl, TII->get(ARC::PUSH_S_BLINK));
157     BuildMI(MBB, MBBI, dl, TII->get(ARC::SUB_rru6))
158         .addReg(ARC::SP)
159         .addReg(ARC::SP)
160         .addImm(4 * StackSlotsUsedByFunclet);
161     BuildMI(MBB, MBBI, dl, TII->get(ARC::BL))
162         .addExternalSymbol(store_funclet_name[Last - ARC::R15])
163         .addReg(ARC::BLINK, RegState::Implicit | RegState::Kill);
164     AlreadyAdjusted += 4 * (StackSlotsUsedByFunclet + 1);
165     SavedBlink = true;
166   }
167   // If we haven't saved BLINK, but we need to...do that now.
168   if (MFI.hasCalls() && !SavedBlink) {
169     DEBUG(dbgs() << "Creating save blink.\n");
170     BuildMI(MBB, MBBI, dl, TII->get(ARC::PUSH_S_BLINK));
171     AlreadyAdjusted += 4;
172   }
173   if (AFI->MaxCallStackReq > 0)
174     MFI.setStackSize(MFI.getStackSize() + AFI->MaxCallStackReq);
175   // We have already saved some of the stack...
176   DEBUG(dbgs() << "Adjusting stack by: "
177                << (MFI.getStackSize() - AlreadyAdjusted) << "\n");
178   generateStackAdjustment(MBB, MBBI, *ST.getInstrInfo(), dl,
179                           -(MFI.getStackSize() - AlreadyAdjusted), ARC::SP);
180
181   if (hasFP(MF)) {
182     DEBUG(dbgs() << "Setting FP from SP.\n");
183     BuildMI(MBB, MBBI, dl,
184             TII->get(isUInt<6>(MFI.getStackSize()) ? ARC::ADD_rru6
185                                                    : ARC::ADD_rrlimm),
186             ARC::FP)
187         .addReg(ARC::SP)
188         .addImm(MFI.getStackSize());
189   }
190
191   // Emit CFI records:
192   // .cfi_def_cfa_offset StackSize
193   // .cfi_offset fp, -StackSize
194   // .cfi_offset blink, -StackSize+4
195   unsigned CFIIndex = MF.addFrameInst(
196       MCCFIInstruction::createDefCfaOffset(nullptr, -MFI.getStackSize()));
197   BuildMI(MBB, MBBI, dl, TII->get(TargetOpcode::CFI_INSTRUCTION))
198       .addCFIIndex(CFIIndex)
199       .setMIFlags(MachineInstr::FrameSetup);
200
201   int CurOffset = -4;
202   if (hasFP(MF)) {
203     CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset(
204         nullptr, MRI->getDwarfRegNum(ARC::FP, true), CurOffset));
205     BuildMI(MBB, MBBI, dl, TII->get(TargetOpcode::CFI_INSTRUCTION))
206         .addCFIIndex(CFIIndex)
207         .setMIFlags(MachineInstr::FrameSetup);
208     CurOffset -= 4;
209   }
210
211   if (MFI.hasCalls()) {
212     CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset(
213         nullptr, MRI->getDwarfRegNum(ARC::BLINK, true), CurOffset));
214     BuildMI(MBB, MBBI, dl, TII->get(TargetOpcode::CFI_INSTRUCTION))
215         .addCFIIndex(CFIIndex)
216         .setMIFlags(MachineInstr::FrameSetup);
217   }
218   // CFI for the rest of the registers.
219   for (const auto &Entry : CSI) {
220     unsigned Reg = Entry.getReg();
221     int FI = Entry.getFrameIdx();
222     // Skip BLINK and FP.
223     if ((hasFP(MF) && Reg == ARC::FP) || (MFI.hasCalls() && Reg == ARC::BLINK))
224       continue;
225     CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset(
226         nullptr, MRI->getDwarfRegNum(Reg, true), MFI.getObjectOffset(FI)));
227     BuildMI(MBB, MBBI, dl, TII->get(TargetOpcode::CFI_INSTRUCTION))
228         .addCFIIndex(CFIIndex)
229         .setMIFlags(MachineInstr::FrameSetup);
230   }
231 }
232
233 /// Insert epilog code into the function.
234 /// For ARC, this inserts a call to a function that restores callee saved
235 /// registers onto the stack, when enough callee saved registers are required.
236 void ARCFrameLowering::emitEpilogue(MachineFunction &MF,
237                                     MachineBasicBlock &MBB) const {
238   DEBUG(dbgs() << "Emit Epilogue: " << MF.getName() << "\n");
239   auto *AFI = MF.getInfo<ARCFunctionInfo>();
240   const ARCInstrInfo *TII = MF.getSubtarget<ARCSubtarget>().getInstrInfo();
241   MachineBasicBlock::iterator MBBI = MBB.getFirstTerminator();
242   MachineFrameInfo &MFI = MF.getFrameInfo();
243   uint64_t StackSize = MF.getFrameInfo().getStackSize();
244   bool SavedBlink = false;
245   unsigned AmountAboveFunclet = 0;
246   // If we have variable sized frame objects, then we have to move
247   // the stack pointer to a known spot (fp - StackSize).
248   // Then, replace the frame pointer by (new) [sp,StackSize-4].
249   // Then, move the stack pointer the rest of the way (sp = sp + StackSize).
250   if (hasFP(MF)) {
251     BuildMI(MBB, MBBI, DebugLoc(), TII->get(ARC::SUB_rru6), ARC::SP)
252         .addReg(ARC::FP)
253         .addImm(StackSize);
254     AmountAboveFunclet += 4;
255   }
256
257   // Now, move the stack pointer to the bottom of the save area for the funclet.
258   const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
259   unsigned Last = determineLastCalleeSave(CSI);
260   unsigned StackSlotsUsedByFunclet = 0;
261   // Now, restore the callee save registers.
262   if (UseSaveRestoreFunclet && Last > ARC::R14) {
263     // BL to __ld_r13_to_<TRI->getRegAsmName()>
264     StackSlotsUsedByFunclet = Last - ARC::R12;
265     AmountAboveFunclet += 4 * (StackSlotsUsedByFunclet + 1);
266     SavedBlink = true;
267   }
268
269   if (MFI.hasCalls() && !SavedBlink) {
270     AmountAboveFunclet += 4;
271     SavedBlink = true;
272   }
273
274   // Move the stack pointer up to the point of the funclet.
275   if (StackSize - AmountAboveFunclet) {
276     BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::ADD_rru6))
277         .addReg(ARC::SP)
278         .addReg(ARC::SP)
279         .addImm(StackSize - AmountAboveFunclet);
280   }
281
282   if (StackSlotsUsedByFunclet) {
283     BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::BL))
284         .addExternalSymbol(load_funclet_name[Last - ARC::R15])
285         .addReg(ARC::BLINK, RegState::Implicit | RegState::Kill);
286     BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::ADD_rru6))
287         .addReg(ARC::SP)
288         .addReg(ARC::SP)
289         .addImm(4 * (StackSlotsUsedByFunclet));
290   }
291   // Now, pop blink if necessary.
292   if (SavedBlink) {
293     BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::POP_S_BLINK));
294   }
295   // Now, pop fp if necessary.
296   if (hasFP(MF)) {
297     BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::LD_AB_rs9))
298         .addReg(ARC::SP, RegState::Define)
299         .addReg(ARC::FP, RegState::Define)
300         .addReg(ARC::SP)
301         .addImm(4);
302   }
303
304   // Relieve the varargs area if necessary.
305   if (MF.getFunction().isVarArg()) {
306     // Add in the varargs area here first.
307     DEBUG(dbgs() << "Varargs\n");
308     unsigned VarArgsBytes = MFI.getObjectSize(AFI->getVarArgsFrameIndex());
309     BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::ADD_rru6))
310         .addReg(ARC::SP)
311         .addReg(ARC::SP)
312         .addImm(VarArgsBytes);
313   }
314 }
315
316 static std::vector<CalleeSavedInfo>::iterator
317 getSavedReg(std::vector<CalleeSavedInfo> &V, unsigned reg) {
318   for (auto I = V.begin(), E = V.end(); I != E; ++I) {
319     if (reg == I->getReg())
320       return I;
321   }
322   return V.end();
323 }
324
325 bool ARCFrameLowering::assignCalleeSavedSpillSlots(
326     MachineFunction &MF, const TargetRegisterInfo *TRI,
327     std::vector<CalleeSavedInfo> &CSI) const {
328   // Use this opportunity to assign the spill slots for all of the potential
329   // callee save registers (blink, fp, r13->r25) that we care about the
330   // placement for.  We can calculate all of that data here.
331   int CurOffset = -4;
332   unsigned Last = determineLastCalleeSave(CSI);
333   MachineFrameInfo &MFI = MF.getFrameInfo();
334   if (hasFP(MF)) {
335     // Create a fixed slot at for FP
336     int StackObj = MFI.CreateFixedSpillStackObject(4, CurOffset, true);
337     DEBUG(dbgs() << "Creating fixed object (" << StackObj << ") for FP at "
338                  << CurOffset << "\n");
339     (void)StackObj;
340     CurOffset -= 4;
341   }
342   if (MFI.hasCalls() || (UseSaveRestoreFunclet && Last > ARC::R14)) {
343     // Create a fixed slot for BLINK.
344     int StackObj  = MFI.CreateFixedSpillStackObject(4, CurOffset, true);
345     DEBUG(dbgs() << "Creating fixed object (" << StackObj << ") for BLINK at "
346                  << CurOffset << "\n");
347     (void)StackObj;
348     CurOffset -= 4;
349   }
350
351   // Create slots for last down to r13.
352   for (unsigned Which = Last; Which > ARC::R12; Which--) {
353     auto RegI = getSavedReg(CSI, Which);
354     if (RegI == CSI.end() || RegI->getFrameIdx() == 0) {
355       // Always create the stack slot.  If for some reason the register isn't in
356       // the save list, then don't worry about it.
357       int FI = MFI.CreateFixedSpillStackObject(4, CurOffset, true);
358       if (RegI != CSI.end())
359         RegI->setFrameIdx(FI);
360     } else
361       MFI.setObjectOffset(RegI->getFrameIdx(), CurOffset);
362     CurOffset -= 4;
363   }
364   for (auto &I : CSI) {
365     if (I.getReg() > ARC::R12)
366       continue;
367     if (I.getFrameIdx() == 0) {
368       I.setFrameIdx(MFI.CreateFixedSpillStackObject(4, CurOffset, true));
369       DEBUG(dbgs() << "Creating fixed object (" << I.getFrameIdx()
370                    << ") for other register at " << CurOffset << "\n");
371     } else {
372       MFI.setObjectOffset(I.getFrameIdx(), CurOffset);
373       DEBUG(dbgs() << "Updating fixed object (" << I.getFrameIdx()
374                    << ") for other register at " << CurOffset << "\n");
375     }
376     CurOffset -= 4;
377   }
378   return true;
379 }
380
381 bool ARCFrameLowering::spillCalleeSavedRegisters(
382     MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
383     const std::vector<CalleeSavedInfo> &CSI,
384     const TargetRegisterInfo *TRI) const {
385   DEBUG(dbgs() << "Spill callee saved registers: "
386                << MBB.getParent()->getName() << "\n");
387   // There are routines for saving at least 3 registers (r13 to r15, etc.)
388   unsigned Last = determineLastCalleeSave(CSI);
389   if (UseSaveRestoreFunclet && Last > ARC::R14) {
390     // Use setObjectOffset for these registers.
391     // Needs to be in or before processFunctionBeforeFrameFinalized.
392     // Or, do assignCalleeSaveSpillSlots?
393     // Will be handled in prolog.
394     return true;
395   }
396   return false;
397 }
398
399 bool ARCFrameLowering::restoreCalleeSavedRegisters(
400     MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
401     std::vector<CalleeSavedInfo> &CSI, const TargetRegisterInfo *TRI) const {
402   DEBUG(dbgs() << "Restore callee saved registers: "
403                << MBB.getParent()->getName() << "\n");
404   // There are routines for saving at least 3 registers (r13 to r15, etc.)
405   unsigned Last = determineLastCalleeSave(CSI);
406   if (UseSaveRestoreFunclet && Last > ARC::R14) {
407     // Will be handled in epilog.
408     return true;
409   }
410   return false;
411 }
412
413 // Adjust local variables that are 4-bytes or larger to 4-byte boundary
414 void ARCFrameLowering::processFunctionBeforeFrameFinalized(
415     MachineFunction &MF, RegScavenger *RS) const {
416   const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
417   DEBUG(dbgs() << "Process function before frame finalized: "
418                << MF.getName() << "\n");
419   MachineFrameInfo &MFI = MF.getFrameInfo();
420   DEBUG(dbgs() << "Current stack size: " << MFI.getStackSize() << "\n");
421   const TargetRegisterClass *RC = &ARC::GPR32RegClass;
422   if (MFI.hasStackObjects()) {
423     int RegScavFI = MFI.CreateStackObject(
424         RegInfo->getSpillSize(*RC), RegInfo->getSpillAlignment(*RC), false);
425     RS->addScavengingFrameIndex(RegScavFI);
426     DEBUG(dbgs() << "Created scavenging index RegScavFI=" << RegScavFI << "\n");
427   }
428 }
429
430 static void emitRegUpdate(MachineBasicBlock &MBB,
431                           MachineBasicBlock::iterator &MBBI, DebugLoc dl,
432                           unsigned Reg, int NumBytes, bool IsAdd,
433                           const ARCInstrInfo *TII) {
434   unsigned Opc = IsAdd ? ARC::ADD_rru6 : ARC::SUB_rru6;
435   BuildMI(MBB, MBBI, dl, TII->get(Opc), Reg)
436       .addReg(Reg, RegState::Kill)
437       .addImm(NumBytes);
438 }
439
440 MachineBasicBlock::iterator ARCFrameLowering::eliminateCallFramePseudoInstr(
441     MachineFunction &MF, MachineBasicBlock &MBB,
442     MachineBasicBlock::iterator I) const {
443   DEBUG(dbgs() << "EmitCallFramePseudo: " << MF.getName() << "\n");
444   const ARCInstrInfo *TII = MF.getSubtarget<ARCSubtarget>().getInstrInfo();
445   MachineInstr &Old = *I;
446   DebugLoc dl = Old.getDebugLoc();
447   unsigned Amt = Old.getOperand(0).getImm();
448   auto *AFI = MF.getInfo<ARCFunctionInfo>();
449   if (!hasFP(MF)) {
450     if (Amt > AFI->MaxCallStackReq && Old.getOpcode() == ARC::ADJCALLSTACKDOWN)
451       AFI->MaxCallStackReq = Amt;
452   } else {
453     if (Amt != 0) {
454       assert((Old.getOpcode() == ARC::ADJCALLSTACKDOWN ||
455               Old.getOpcode() == ARC::ADJCALLSTACKUP) &&
456              "Unknown Frame Pseudo.");
457       bool IsAdd = (Old.getOpcode() == ARC::ADJCALLSTACKUP);
458       emitRegUpdate(MBB, I, dl, ARC::SP, Amt, IsAdd, TII);
459     }
460   }
461   return MBB.erase(I);
462 }
463
464 bool ARCFrameLowering::hasFP(const MachineFunction &MF) const {
465   const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
466   bool HasFP = MF.getTarget().Options.DisableFramePointerElim(MF) ||
467                MF.getFrameInfo().hasVarSizedObjects() ||
468                MF.getFrameInfo().isFrameAddressTaken() ||
469                RegInfo->needsStackRealignment(MF);
470   return HasFP;
471 }