LLVM 19.0.0git
Go to the documentation of this file.
1//===-- MipsFrameLowering.cpp - Mips Frame Information --------------------===//
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
9// This file contains the Mips implementation of TargetFrameLowering class.
13#include "MipsFrameLowering.h"
15#include "MipsInstrInfo.h"
16#include "MipsMachineFunction.h"
17#include "MipsTargetMachine.h"
23#include "llvm/IR/DataLayout.h"
24#include "llvm/IR/Function.h"
27using namespace llvm;
32// Stack Frame Processing methods
33// +----------------------------+
35// The stack is allocated decrementing the stack pointer on
36// the first instruction of a function prologue. Once decremented,
37// all stack references are done thought a positive offset
38// from the stack/frame pointer, so the stack is considering
39// to grow up! Otherwise terrible hacks would have to be made
40// to get this stack ABI compliant :)
42// The stack frame required by the ABI (after call):
43// Offset
45// 0 ----------
46// 4 Args to pass
47// . saved $GP (used in PIC)
48// . Alloca allocations
49// . Local Area
50// . CPU "Callee Saved" Registers
51// . saved FP
52// . saved RA
53// . FPU "Callee Saved" Registers
54// StackSize -----------
56// Offset - offset from sp after stack allocation on function prologue
58// The sp is the stack pointer subtracted/added from the stack size
59// at the Prologue/Epilogue
61// References to the previous stack (to obtain arguments) are done
62// with offsets that exceeds the stack size: (stacksize+(4*(num_arg-1))
64// Examples:
65// - reference to the actual stack frame
66// for any local area var there is smt like : FI >= 0, StackOffset: 4
67// sw REGX, 4(SP)
69// - reference to previous stack frame
70// suppose there's a load to the 5th arguments : FI < 0, StackOffset: 16.
71// The emitted instruction will be something like:
72// lw REGX, 16+StackSize(SP)
74// Since the total stack size is unknown on LowerFormalArguments, all
75// stack references (ObjectOffset) created to reference the function
76// arguments, are negative numbers. This way, on eliminateFrameIndex it's
77// possible to detect those references and the offsets are adjusted to
78// their real location.
83 if (ST.inMips16Mode())
89// hasFP - Return true if the specified function should have a dedicated frame
90// pointer register. This is true if the function has variable sized allocas,
91// if it needs dynamic stack realignment, if frame pointer elimination is
92// disabled, or if the frame address is taken.
94 const MachineFrameInfo &MFI = MF.getFrameInfo();
99 TRI->hasStackRealignment(MF);
103 const MachineFrameInfo &MFI = MF.getFrameInfo();
106 return MFI.hasVarSizedObjects() && TRI->hasStackRealignment(MF);
109// Estimate the size of the stack, including the incoming arguments. We need to
110// account for register spills, local objects, reserved call frame and incoming
111// arguments. This is required to determine the largest possible positive offset
112// from $sp so that it can be determined if an emergency spill slot for stack
113// addresses is required.
115 const MachineFrameInfo &MFI = MF.getFrameInfo();
118 int64_t Size = 0;
120 // Iterate over fixed sized objects which are incoming arguments.
121 for (int I = MFI.getObjectIndexBegin(); I != 0; ++I)
122 if (MFI.getObjectOffset(I) > 0)
123 Size += MFI.getObjectSize(I);
125 // Conservatively assume all callee-saved registers will be saved.
126 for (const MCPhysReg *R = TRI.getCalleeSavedRegs(&MF); *R; ++R) {
127 unsigned RegSize = TRI.getSpillSize(*TRI.getMinimalPhysRegClass(*R));
129 }
131 // Get the size of the rest of the frame objects and any possible reserved
132 // call frame, accounting for alignment.
133 return Size + MFI.estimateStackSize(MF);
136// Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions
140 unsigned SP = STI.getABI().IsN64() ? Mips::SP_64 : Mips::SP;
142 if (!hasReservedCallFrame(MF)) {
143 int64_t Amount = I->getOperand(0).getImm();
144 if (I->getOpcode() == Mips::ADJCALLSTACKDOWN)
145 Amount = -Amount;
147 STI.getInstrInfo()->adjustStackPtr(SP, Amount, MBB, I);
148 }
150 return MBB.erase(I);
unsigned RegSize
MachineBasicBlock & MBB
uint64_t Size
#define I(x, y, z)
Definition: MD5.cpp:58
unsigned const TargetRegisterInfo * TRI
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
bool isFrameAddressTaken() const
This method may be called any time after instruction selection is complete to determine if there is a...
uint64_t estimateStackSize(const MachineFunction &MF) const
Estimate and return the size of the stack frame.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
int getObjectIndexBegin() const
Return the minimum frame object index.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
bool IsN64() const
Definition: MipsABIInfo.h:42
static const MipsFrameLowering * create(const MipsSubtarget &ST)
bool hasFP(const MachineFunction &MF) const override
hasFP - Return true if the specified function should have a dedicated frame pointer register.
bool hasBP(const MachineFunction &MF) const
uint64_t estimateStackSize(const MachineFunction &MF) const
MachineBasicBlock::iterator eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const override
This method is called during prolog/epilog code insertion to eliminate call frame setup and destroy p...
const MipsSubtarget & STI
virtual void adjustStackPtr(unsigned SP, int64_t Amount, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const =0
const MipsInstrInfo * getInstrInfo() const override
const MipsRegisterInfo * getRegisterInfo() const override
const MipsABIInfo & getABI() const
virtual bool hasReservedCallFrame(const MachineFunction &MF) const
hasReservedCallFrame - Under normal circumstances, when a frame pointer is not required,...
TargetOptions Options
bool DisableFramePointerElim(const MachineFunction &MF) const
DisableFramePointerElim - This returns true if frame pointer elimination optimization should be disab...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
const MipsFrameLowering * createMipsSEFrameLowering(const MipsSubtarget &ST)
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:155
const MipsFrameLowering * createMips16FrameLowering(const MipsSubtarget &ST)
Create MipsFrameLowering objects.