1 //===- TargetFrameLoweringImpl.cpp - Implement target frame interface ------==// 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 // Implements the layout of a stack frame on the target machine. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "llvm/ADT/BitVector.h" 14 #include "llvm/CodeGen/MachineFrameInfo.h" 15 #include "llvm/CodeGen/MachineFunction.h" 16 #include "llvm/CodeGen/MachineRegisterInfo.h" 17 #include "llvm/CodeGen/TargetFrameLowering.h" 18 #include "llvm/CodeGen/TargetRegisterInfo.h" 19 #include "llvm/CodeGen/TargetSubtargetInfo.h" 20 #include "llvm/IR/Attributes.h" 21 #include "llvm/IR/CallingConv.h" 22 #include "llvm/IR/Function.h" 23 #include "llvm/MC/MCRegisterInfo.h" 24 #include "llvm/Support/Compiler.h" 25 #include "llvm/Target/TargetMachine.h" 26 #include "llvm/Target/TargetOptions.h" 27 28 using namespace llvm; 29 30 TargetFrameLowering::~TargetFrameLowering() = default; 31 32 bool TargetFrameLowering::enableCalleeSaveSkip(const MachineFunction &MF) const { 33 assert(MF.getFunction().hasFnAttribute(Attribute::NoReturn) && 34 MF.getFunction().hasFnAttribute(Attribute::NoUnwind) && 35 !MF.getFunction().hasFnAttribute(Attribute::UWTable)); 36 return false; 37 } 38 39 /// Returns the displacement from the frame register to the stack 40 /// frame of the specified index, along with the frame register used 41 /// (in output arg FrameReg). This is the default implementation which 42 /// is overridden for some targets. 43 int TargetFrameLowering::getFrameIndexReference(const MachineFunction &MF, 44 int FI, unsigned &FrameReg) const { 45 const MachineFrameInfo &MFI = MF.getFrameInfo(); 46 const TargetRegisterInfo *RI = MF.getSubtarget().getRegisterInfo(); 47 48 // By default, assume all frame indices are referenced via whatever 49 // getFrameRegister() says. The target can override this if it's doing 50 // something different. 51 FrameReg = RI->getFrameRegister(MF); 52 53 return MFI.getObjectOffset(FI) + MFI.getStackSize() - 54 getOffsetOfLocalArea() + MFI.getOffsetAdjustment(); 55 } 56 57 bool TargetFrameLowering::needsFrameIndexResolution( 58 const MachineFunction &MF) const { 59 return MF.getFrameInfo().hasStackObjects(); 60 } 61 62 void TargetFrameLowering::getCalleeSaves(const MachineFunction &MF, 63 BitVector &CalleeSaves) const { 64 const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo(); 65 CalleeSaves.resize(TRI.getNumRegs()); 66 67 const MachineFrameInfo &MFI = MF.getFrameInfo(); 68 if (!MFI.isCalleeSavedInfoValid()) 69 return; 70 71 for (const CalleeSavedInfo &Info : MFI.getCalleeSavedInfo()) 72 CalleeSaves.set(Info.getReg()); 73 } 74 75 void TargetFrameLowering::determineCalleeSaves(MachineFunction &MF, 76 BitVector &SavedRegs, 77 RegScavenger *RS) const { 78 const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo(); 79 80 // Resize before the early returns. Some backends expect that 81 // SavedRegs.size() == TRI.getNumRegs() after this call even if there are no 82 // saved registers. 83 SavedRegs.resize(TRI.getNumRegs()); 84 85 // When interprocedural register allocation is enabled caller saved registers 86 // are preferred over callee saved registers. 87 if (MF.getTarget().Options.EnableIPRA && 88 isSafeForNoCSROpt(MF.getFunction()) && 89 isProfitableForNoCSROpt(MF.getFunction())) 90 return; 91 92 // Get the callee saved register list... 93 const MCPhysReg *CSRegs = MF.getRegInfo().getCalleeSavedRegs(); 94 95 // Early exit if there are no callee saved registers. 96 if (!CSRegs || CSRegs[0] == 0) 97 return; 98 99 // In Naked functions we aren't going to save any registers. 100 if (MF.getFunction().hasFnAttribute(Attribute::Naked)) 101 return; 102 103 // Noreturn+nounwind functions never restore CSR, so no saves are needed. 104 // Purely noreturn functions may still return through throws, so those must 105 // save CSR for caller exception handlers. 106 // 107 // If the function uses longjmp to break out of its current path of 108 // execution we do not need the CSR spills either: setjmp stores all CSRs 109 // it was called with into the jmp_buf, which longjmp then restores. 110 if (MF.getFunction().hasFnAttribute(Attribute::NoReturn) && 111 MF.getFunction().hasFnAttribute(Attribute::NoUnwind) && 112 !MF.getFunction().hasFnAttribute(Attribute::UWTable) && 113 enableCalleeSaveSkip(MF)) 114 return; 115 116 // Functions which call __builtin_unwind_init get all their registers saved. 117 bool CallsUnwindInit = MF.callsUnwindInit(); 118 const MachineRegisterInfo &MRI = MF.getRegInfo(); 119 for (unsigned i = 0; CSRegs[i]; ++i) { 120 unsigned Reg = CSRegs[i]; 121 if (CallsUnwindInit || MRI.isPhysRegModified(Reg)) 122 SavedRegs.set(Reg); 123 } 124 } 125 126 unsigned TargetFrameLowering::getStackAlignmentSkew( 127 const MachineFunction &MF) const { 128 // When HHVM function is called, the stack is skewed as the return address 129 // is removed from the stack before we enter the function. 130 if (LLVM_UNLIKELY(MF.getFunction().getCallingConv() == CallingConv::HHVM)) 131 return MF.getTarget().getAllocaPointerSize(); 132 133 return 0; 134 } 135 136 int TargetFrameLowering::getInitialCFAOffset(const MachineFunction &MF) const { 137 llvm_unreachable("getInitialCFAOffset() not implemented!"); 138 } 139 140 unsigned TargetFrameLowering::getInitialCFARegister(const MachineFunction &MF) 141 const { 142 llvm_unreachable("getInitialCFARegister() not implemented!"); 143 } 144