Path: blob/main/contrib/llvm-project/llvm/lib/Target/Lanai/LanaiFrameLowering.cpp
35271 views
//===-- LanaiFrameLowering.cpp - Lanai Frame Information ------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file contains the Lanai implementation of TargetFrameLowering class.9//10//===----------------------------------------------------------------------===//1112#include "LanaiFrameLowering.h"1314#include "LanaiAluCode.h"15#include "LanaiInstrInfo.h"16#include "LanaiSubtarget.h"17#include "llvm/CodeGen/MachineFrameInfo.h"18#include "llvm/CodeGen/MachineFunction.h"19#include "llvm/CodeGen/MachineInstrBuilder.h"20#include "llvm/CodeGen/MachineRegisterInfo.h"21#include "llvm/IR/Function.h"2223using namespace llvm;2425// Determines the size of the frame and maximum call frame size.26void LanaiFrameLowering::determineFrameLayout(MachineFunction &MF) const {27MachineFrameInfo &MFI = MF.getFrameInfo();28const LanaiRegisterInfo *LRI = STI.getRegisterInfo();2930// Get the number of bytes to allocate from the FrameInfo.31unsigned FrameSize = MFI.getStackSize();3233// Get the alignment.34Align StackAlign =35LRI->hasStackRealignment(MF) ? MFI.getMaxAlign() : getStackAlign();3637// Get the maximum call frame size of all the calls.38unsigned MaxCallFrameSize = MFI.getMaxCallFrameSize();3940// If we have dynamic alloca then MaxCallFrameSize needs to be aligned so41// that allocations will be aligned.42if (MFI.hasVarSizedObjects())43MaxCallFrameSize = alignTo(MaxCallFrameSize, StackAlign);4445// Update maximum call frame size.46MFI.setMaxCallFrameSize(MaxCallFrameSize);4748// Include call frame size in total.49if (!(hasReservedCallFrame(MF) && MFI.adjustsStack()))50FrameSize += MaxCallFrameSize;5152// Make sure the frame is aligned.53FrameSize = alignTo(FrameSize, StackAlign);5455// Update frame info.56MFI.setStackSize(FrameSize);57}5859// Iterates through each basic block in a machine function and replaces60// ADJDYNALLOC pseudo instructions with a Lanai:ADDI with the61// maximum call frame size as the immediate.62void LanaiFrameLowering::replaceAdjDynAllocPseudo(MachineFunction &MF) const {63const LanaiInstrInfo &LII =64*static_cast<const LanaiInstrInfo *>(STI.getInstrInfo());65unsigned MaxCallFrameSize = MF.getFrameInfo().getMaxCallFrameSize();6667for (MachineBasicBlock &MBB : MF) {68for (MachineInstr &MI : llvm::make_early_inc_range(MBB)) {69if (MI.getOpcode() == Lanai::ADJDYNALLOC) {70DebugLoc DL = MI.getDebugLoc();71Register Dst = MI.getOperand(0).getReg();72Register Src = MI.getOperand(1).getReg();7374BuildMI(MBB, MI, DL, LII.get(Lanai::ADD_I_LO), Dst)75.addReg(Src)76.addImm(MaxCallFrameSize);77MI.eraseFromParent();78}79}80}81}8283// Generates the following sequence for function entry:84// st %fp,-4[*%sp] !push old FP85// add %sp,8,%fp !generate new FP86// sub %sp,0x4,%sp !allocate stack space (as needed)87void LanaiFrameLowering::emitPrologue(MachineFunction &MF,88MachineBasicBlock &MBB) const {89assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported");9091MachineFrameInfo &MFI = MF.getFrameInfo();92const LanaiInstrInfo &LII =93*static_cast<const LanaiInstrInfo *>(STI.getInstrInfo());94MachineBasicBlock::iterator MBBI = MBB.begin();9596// Debug location must be unknown since the first debug location is used97// to determine the end of the prologue.98DebugLoc DL;99100// Determine the correct frame layout101determineFrameLayout(MF);102103// FIXME: This appears to be overallocating. Needs investigation.104// Get the number of bytes to allocate from the FrameInfo.105unsigned StackSize = MFI.getStackSize();106107// Push old FP108// st %fp,-4[*%sp]109BuildMI(MBB, MBBI, DL, LII.get(Lanai::SW_RI))110.addReg(Lanai::FP)111.addReg(Lanai::SP)112.addImm(-4)113.addImm(LPAC::makePreOp(LPAC::ADD))114.setMIFlag(MachineInstr::FrameSetup);115116// Generate new FP117// add %sp,8,%fp118BuildMI(MBB, MBBI, DL, LII.get(Lanai::ADD_I_LO), Lanai::FP)119.addReg(Lanai::SP)120.addImm(8)121.setMIFlag(MachineInstr::FrameSetup);122123// Allocate space on the stack if needed124// sub %sp,StackSize,%sp125if (StackSize != 0) {126BuildMI(MBB, MBBI, DL, LII.get(Lanai::SUB_I_LO), Lanai::SP)127.addReg(Lanai::SP)128.addImm(StackSize)129.setMIFlag(MachineInstr::FrameSetup);130}131132// Replace ADJDYNANALLOC133if (MFI.hasVarSizedObjects())134replaceAdjDynAllocPseudo(MF);135}136137MachineBasicBlock::iterator LanaiFrameLowering::eliminateCallFramePseudoInstr(138MachineFunction & /*MF*/, MachineBasicBlock &MBB,139MachineBasicBlock::iterator I) const {140// Discard ADJCALLSTACKDOWN, ADJCALLSTACKUP instructions.141return MBB.erase(I);142}143144// The function epilogue should not depend on the current stack pointer!145// It should use the frame pointer only. This is mandatory because146// of alloca; we also take advantage of it to omit stack adjustments147// before returning.148//149// Note that when we go to restore the preserved register values we must150// not try to address their slots by using offsets from the stack pointer.151// That's because the stack pointer may have been moved during the function152// execution due to a call to alloca(). Rather, we must restore all153// preserved registers via offsets from the frame pointer value.154//155// Note also that when the current frame is being "popped" (by adjusting156// the value of the stack pointer) on function exit, we must (for the157// sake of alloca) set the new value of the stack pointer based upon158// the current value of the frame pointer. We can't just add what we159// believe to be the (static) frame size to the stack pointer because160// if we did that, and alloca() had been called during this function,161// we would end up returning *without* having fully deallocated all of162// the space grabbed by alloca. If that happened, and a function163// containing one or more alloca() calls was called over and over again,164// then the stack would grow without limit!165//166// RET is lowered to167// ld -4[%fp],%pc # modify %pc (two delay slots)168// as the return address is in the stack frame and mov to pc is allowed.169// emitEpilogue emits170// mov %fp,%sp # restore the stack pointer171// ld -8[%fp],%fp # restore the caller's frame pointer172// before RET and the delay slot filler will move RET such that these173// instructions execute in the delay slots of the load to PC.174void LanaiFrameLowering::emitEpilogue(MachineFunction & /*MF*/,175MachineBasicBlock &MBB) const {176MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();177const LanaiInstrInfo &LII =178*static_cast<const LanaiInstrInfo *>(STI.getInstrInfo());179DebugLoc DL = MBBI->getDebugLoc();180181// Restore the stack pointer using the callee's frame pointer value.182BuildMI(MBB, MBBI, DL, LII.get(Lanai::ADD_I_LO), Lanai::SP)183.addReg(Lanai::FP)184.addImm(0);185186// Restore the frame pointer from the stack.187BuildMI(MBB, MBBI, DL, LII.get(Lanai::LDW_RI), Lanai::FP)188.addReg(Lanai::FP)189.addImm(-8)190.addImm(LPAC::ADD);191}192193void LanaiFrameLowering::determineCalleeSaves(MachineFunction &MF,194BitVector &SavedRegs,195RegScavenger *RS) const {196TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);197198MachineFrameInfo &MFI = MF.getFrameInfo();199const LanaiRegisterInfo *LRI =200static_cast<const LanaiRegisterInfo *>(STI.getRegisterInfo());201int Offset = -4;202203// Reserve 4 bytes for the saved RCA204MFI.CreateFixedObject(4, Offset, true);205Offset -= 4;206207// Reserve 4 bytes for the saved FP208MFI.CreateFixedObject(4, Offset, true);209Offset -= 4;210211if (LRI->hasBasePointer(MF)) {212MFI.CreateFixedObject(4, Offset, true);213SavedRegs.reset(LRI->getBaseRegister());214}215}216217218