brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.6 KiB · 3c3924b Raw
211 lines · cpp
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-exception6//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 22using namespace llvm;23 24// Determines the size of the frame and maximum call frame size.25void 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 so40  // 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 replaces59// ADJDYNALLOC pseudo instructions with a Lanai:ADDI with the60// maximum call frame size as the immediate.61void 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 FP83//   add %sp,8,%fp          !generate new FP84//   sub %sp,0x4,%sp        !allocate stack space (as needed)85void 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 used94  // to determine the end of the prologue.95  DebugLoc DL;96 97  // Determine the correct frame layout98  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 FP105  // 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 FP114  // add %sp,8,%fp115  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 needed121  // sub %sp,StackSize,%sp122  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 ADJDYNANALLOC130  if (MFI.hasVarSizedObjects())131    replaceAdjDynAllocPseudo(MF);132}133 134MachineBasicBlock::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 because143// of alloca; we also take advantage of it to omit stack adjustments144// before returning.145//146// Note that when we go to restore the preserved register values we must147// 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 function149// execution due to a call to alloca().  Rather, we must restore all150// preserved registers via offsets from the frame pointer value.151//152// Note also that when the current frame is being "popped" (by adjusting153// the value of the stack pointer) on function exit, we must (for the154// sake of alloca) set the new value of the stack pointer based upon155// the current value of the frame pointer.  We can't just add what we156// believe to be the (static) frame size to the stack pointer because157// if we did that, and alloca() had been called during this function,158// we would end up returning *without* having fully deallocated all of159// the space grabbed by alloca.  If that happened, and a function160// 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 to164//      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 emits167//      mov %fp,%sp     # restore the stack pointer168//      ld -8[%fp],%fp  # restore the caller's frame pointer169// before RET and the delay slot filler will move RET such that these170// instructions execute in the delay slots of the load to PC.171void 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 189void 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 RCA199  MFI.CreateFixedObject(4, Offset, true);200  Offset -= 4;201 202  // Reserve 4 bytes for the saved FP203  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