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