1 //===-- LanaiFrameLowering.cpp - Lanai 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 Lanai implementation of TargetFrameLowering class. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "LanaiFrameLowering.h" 14 15 #include "LanaiAluCode.h" 16 #include "LanaiInstrInfo.h" 17 #include "LanaiSubtarget.h" 18 #include "llvm/CodeGen/MachineFrameInfo.h" 19 #include "llvm/CodeGen/MachineFunction.h" 20 #include "llvm/CodeGen/MachineInstrBuilder.h" 21 22 using namespace llvm; 23 24 // Determines the size of the frame and maximum call frame size. 25 void LanaiFrameLowering::determineFrameLayout(MachineFunction &MF) const { 26 MachineFrameInfo &MFI = MF.getFrameInfo(); 27 const LanaiRegisterInfo *LRI = STI.getRegisterInfo(); 28 29 // Get the number of bytes to allocate from the FrameInfo. 30 unsigned FrameSize = MFI.getStackSize(); 31 32 // Get the alignment. 33 Align StackAlign = 34 LRI->hasStackRealignment(MF) ? MFI.getMaxAlign() : getStackAlign(); 35 36 // Get the maximum call frame size of all the calls. 37 unsigned MaxCallFrameSize = MFI.getMaxCallFrameSize(); 38 39 // If we have dynamic alloca then MaxCallFrameSize needs to be aligned so 40 // that allocations will be aligned. 41 if (MFI.hasVarSizedObjects()) 42 MaxCallFrameSize = alignTo(MaxCallFrameSize, StackAlign); 43 44 // Update maximum call frame size. 45 MFI.setMaxCallFrameSize(MaxCallFrameSize); 46 47 // Include call frame size in total. 48 if (!(hasReservedCallFrame(MF) && MFI.adjustsStack())) 49 FrameSize += MaxCallFrameSize; 50 51 // Make sure the frame is aligned. 52 FrameSize = alignTo(FrameSize, StackAlign); 53 54 // Update frame info. 55 MFI.setStackSize(FrameSize); 56 } 57 58 // Iterates through each basic block in a machine function and replaces 59 // ADJDYNALLOC pseudo instructions with a Lanai:ADDI with the 60 // maximum call frame size as the immediate. 61 void LanaiFrameLowering::replaceAdjDynAllocPseudo(MachineFunction &MF) const { 62 const LanaiInstrInfo &LII = *STI.getInstrInfo(); 63 unsigned MaxCallFrameSize = MF.getFrameInfo().getMaxCallFrameSize(); 64 65 for (MachineBasicBlock &MBB : MF) { 66 for (MachineInstr &MI : llvm::make_early_inc_range(MBB)) { 67 if (MI.getOpcode() == Lanai::ADJDYNALLOC) { 68 DebugLoc DL = MI.getDebugLoc(); 69 Register Dst = MI.getOperand(0).getReg(); 70 Register Src = MI.getOperand(1).getReg(); 71 72 BuildMI(MBB, MI, DL, LII.get(Lanai::ADD_I_LO), Dst) 73 .addReg(Src) 74 .addImm(MaxCallFrameSize); 75 MI.eraseFromParent(); 76 } 77 } 78 } 79 } 80 81 // Generates the following sequence for function entry: 82 // st %fp,-4[*%sp] !push old FP 83 // add %sp,8,%fp !generate new FP 84 // sub %sp,0x4,%sp !allocate stack space (as needed) 85 void LanaiFrameLowering::emitPrologue(MachineFunction &MF, 86 MachineBasicBlock &MBB) const { 87 assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported"); 88 89 MachineFrameInfo &MFI = MF.getFrameInfo(); 90 const LanaiInstrInfo &LII = *STI.getInstrInfo(); 91 MachineBasicBlock::iterator MBBI = MBB.begin(); 92 93 // Debug location must be unknown since the first debug location is used 94 // to determine the end of the prologue. 95 DebugLoc DL; 96 97 // Determine the correct frame layout 98 determineFrameLayout(MF); 99 100 // FIXME: This appears to be overallocating. Needs investigation. 101 // Get the number of bytes to allocate from the FrameInfo. 102 unsigned StackSize = MFI.getStackSize(); 103 104 // Push old FP 105 // st %fp,-4[*%sp] 106 BuildMI(MBB, MBBI, DL, LII.get(Lanai::SW_RI)) 107 .addReg(Lanai::FP) 108 .addReg(Lanai::SP) 109 .addImm(-4) 110 .addImm(LPAC::makePreOp(LPAC::ADD)) 111 .setMIFlag(MachineInstr::FrameSetup); 112 113 // Generate new FP 114 // add %sp,8,%fp 115 BuildMI(MBB, MBBI, DL, LII.get(Lanai::ADD_I_LO), Lanai::FP) 116 .addReg(Lanai::SP) 117 .addImm(8) 118 .setMIFlag(MachineInstr::FrameSetup); 119 120 // Allocate space on the stack if needed 121 // sub %sp,StackSize,%sp 122 if (StackSize != 0) { 123 BuildMI(MBB, MBBI, DL, LII.get(Lanai::SUB_I_LO), Lanai::SP) 124 .addReg(Lanai::SP) 125 .addImm(StackSize) 126 .setMIFlag(MachineInstr::FrameSetup); 127 } 128 129 // Replace ADJDYNANALLOC 130 if (MFI.hasVarSizedObjects()) 131 replaceAdjDynAllocPseudo(MF); 132 } 133 134 MachineBasicBlock::iterator LanaiFrameLowering::eliminateCallFramePseudoInstr( 135 MachineFunction & /*MF*/, MachineBasicBlock &MBB, 136 MachineBasicBlock::iterator I) const { 137 // Discard ADJCALLSTACKDOWN, ADJCALLSTACKUP instructions. 138 return MBB.erase(I); 139 } 140 141 // The function epilogue should not depend on the current stack pointer! 142 // It should use the frame pointer only. This is mandatory because 143 // of alloca; we also take advantage of it to omit stack adjustments 144 // before returning. 145 // 146 // Note that when we go to restore the preserved register values we must 147 // not try to address their slots by using offsets from the stack pointer. 148 // That's because the stack pointer may have been moved during the function 149 // execution due to a call to alloca(). Rather, we must restore all 150 // preserved registers via offsets from the frame pointer value. 151 // 152 // Note also that when the current frame is being "popped" (by adjusting 153 // the value of the stack pointer) on function exit, we must (for the 154 // sake of alloca) set the new value of the stack pointer based upon 155 // the current value of the frame pointer. We can't just add what we 156 // believe to be the (static) frame size to the stack pointer because 157 // if we did that, and alloca() had been called during this function, 158 // we would end up returning *without* having fully deallocated all of 159 // the space grabbed by alloca. If that happened, and a function 160 // containing one or more alloca() calls was called over and over again, 161 // then the stack would grow without limit! 162 // 163 // RET is lowered to 164 // ld -4[%fp],%pc # modify %pc (two delay slots) 165 // as the return address is in the stack frame and mov to pc is allowed. 166 // emitEpilogue emits 167 // mov %fp,%sp # restore the stack pointer 168 // ld -8[%fp],%fp # restore the caller's frame pointer 169 // before RET and the delay slot filler will move RET such that these 170 // instructions execute in the delay slots of the load to PC. 171 void LanaiFrameLowering::emitEpilogue(MachineFunction & /*MF*/, 172 MachineBasicBlock &MBB) const { 173 MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 174 const LanaiInstrInfo &LII = *STI.getInstrInfo(); 175 DebugLoc DL = MBBI->getDebugLoc(); 176 177 // Restore the stack pointer using the callee's frame pointer value. 178 BuildMI(MBB, MBBI, DL, LII.get(Lanai::ADD_I_LO), Lanai::SP) 179 .addReg(Lanai::FP) 180 .addImm(0); 181 182 // Restore the frame pointer from the stack. 183 BuildMI(MBB, MBBI, DL, LII.get(Lanai::LDW_RI), Lanai::FP) 184 .addReg(Lanai::FP) 185 .addImm(-8) 186 .addImm(LPAC::ADD); 187 } 188 189 void LanaiFrameLowering::determineCalleeSaves(MachineFunction &MF, 190 BitVector &SavedRegs, 191 RegScavenger *RS) const { 192 TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); 193 194 MachineFrameInfo &MFI = MF.getFrameInfo(); 195 const LanaiRegisterInfo *LRI = STI.getRegisterInfo(); 196 int Offset = -4; 197 198 // Reserve 4 bytes for the saved RCA 199 MFI.CreateFixedObject(4, Offset, true); 200 Offset -= 4; 201 202 // Reserve 4 bytes for the saved FP 203 MFI.CreateFixedObject(4, Offset, true); 204 Offset -= 4; 205 206 if (LRI->hasBasePointer(MF)) { 207 MFI.CreateFixedObject(4, Offset, true); 208 SavedRegs.reset(LRI->getBaseRegister()); 209 } 210 } 211