//===-- LanaiFrameLowering.cpp - Lanai Frame Information ------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file contains the Lanai implementation of TargetFrameLowering class. // //===----------------------------------------------------------------------===// #include "LanaiFrameLowering.h" #include "LanaiAluCode.h" #include "LanaiInstrInfo.h" #include "LanaiSubtarget.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/IR/Function.h" usingnamespacellvm; // Determines the size of the frame and maximum call frame size. void LanaiFrameLowering::determineFrameLayout(MachineFunction &MF) const { … } // Iterates through each basic block in a machine function and replaces // ADJDYNALLOC pseudo instructions with a Lanai:ADDI with the // maximum call frame size as the immediate. void LanaiFrameLowering::replaceAdjDynAllocPseudo(MachineFunction &MF) const { … } // Generates the following sequence for function entry: // st %fp,-4[*%sp] !push old FP // add %sp,8,%fp !generate new FP // sub %sp,0x4,%sp !allocate stack space (as needed) void LanaiFrameLowering::emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const { … } MachineBasicBlock::iterator LanaiFrameLowering::eliminateCallFramePseudoInstr( MachineFunction & /*MF*/, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const { … } // The function epilogue should not depend on the current stack pointer! // It should use the frame pointer only. This is mandatory because // of alloca; we also take advantage of it to omit stack adjustments // before returning. // // Note that when we go to restore the preserved register values we must // not try to address their slots by using offsets from the stack pointer. // That's because the stack pointer may have been moved during the function // execution due to a call to alloca(). Rather, we must restore all // preserved registers via offsets from the frame pointer value. // // Note also that when the current frame is being "popped" (by adjusting // the value of the stack pointer) on function exit, we must (for the // sake of alloca) set the new value of the stack pointer based upon // the current value of the frame pointer. We can't just add what we // believe to be the (static) frame size to the stack pointer because // if we did that, and alloca() had been called during this function, // we would end up returning *without* having fully deallocated all of // the space grabbed by alloca. If that happened, and a function // containing one or more alloca() calls was called over and over again, // then the stack would grow without limit! // // RET is lowered to // ld -4[%fp],%pc # modify %pc (two delay slots) // as the return address is in the stack frame and mov to pc is allowed. // emitEpilogue emits // mov %fp,%sp # restore the stack pointer // ld -8[%fp],%fp # restore the caller's frame pointer // before RET and the delay slot filler will move RET such that these // instructions execute in the delay slots of the load to PC. void LanaiFrameLowering::emitEpilogue(MachineFunction & /*MF*/, MachineBasicBlock &MBB) const { … } void LanaiFrameLowering::determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS) const { … }