LLVM 19.0.0git
MipsFrameLowering.cpp
Go to the documentation of this file.
1//===-- MipsFrameLowering.cpp - Mips 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-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file contains the Mips implementation of TargetFrameLowering class.
10//
11//===----------------------------------------------------------------------===//
12
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"
26
27using namespace llvm;
28
29
30//===----------------------------------------------------------------------===//
31//
32// Stack Frame Processing methods
33// +----------------------------+
34//
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 :)
41//
42// The stack frame required by the ABI (after call):
43// Offset
44//
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 -----------
55//
56// Offset - offset from sp after stack allocation on function prologue
57//
58// The sp is the stack pointer subtracted/added from the stack size
59// at the Prologue/Epilogue
60//
61// References to the previous stack (to obtain arguments) are done
62// with offsets that exceeds the stack size: (stacksize+(4*(num_arg-1))
63//
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)
68//
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)
73//
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.
79//
80//===----------------------------------------------------------------------===//
81
83 if (ST.inMips16Mode())
85
87}
88
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();
96
99 TRI->hasStackRealignment(MF);
100}
101
103 const MachineFrameInfo &MFI = MF.getFrameInfo();
105
106 return MFI.hasVarSizedObjects() && TRI->hasStackRealignment(MF);
107}
108
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();
117
118 int64_t Size = 0;
119
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);
124
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 }
130
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);
134}
135
136// Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions
140 unsigned SP = STI.getABI().IsN64() ? Mips::SP_64 : Mips::SP;
141
142 if (!hasReservedCallFrame(MF)) {
143 int64_t Amount = I->getOperand(0).getImm();
144 if (I->getOpcode() == Mips::ADJCALLSTACKDOWN)
145 Amount = -Amount;
146
147 STI.getInstrInfo()->adjustStackPtr(SP, Amount, MBB, I);
148 }
149
150 return MBB.erase(I);
151}
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.