LLVM 20.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"
14#include "MipsInstrInfo.h"
15#include "MipsTargetMachine.h"
20
21using namespace llvm;
22
23
24//===----------------------------------------------------------------------===//
25//
26// Stack Frame Processing methods
27// +----------------------------+
28//
29// The stack is allocated decrementing the stack pointer on
30// the first instruction of a function prologue. Once decremented,
31// all stack references are done thought a positive offset
32// from the stack/frame pointer, so the stack is considering
33// to grow up! Otherwise terrible hacks would have to be made
34// to get this stack ABI compliant :)
35//
36// The stack frame required by the ABI (after call):
37// Offset
38//
39// 0 ----------
40// 4 Args to pass
41// . saved $GP (used in PIC)
42// . Alloca allocations
43// . Local Area
44// . CPU "Callee Saved" Registers
45// . saved FP
46// . saved RA
47// . FPU "Callee Saved" Registers
48// StackSize -----------
49//
50// Offset - offset from sp after stack allocation on function prologue
51//
52// The sp is the stack pointer subtracted/added from the stack size
53// at the Prologue/Epilogue
54//
55// References to the previous stack (to obtain arguments) are done
56// with offsets that exceeds the stack size: (stacksize+(4*(num_arg-1))
57//
58// Examples:
59// - reference to the actual stack frame
60// for any local area var there is smt like : FI >= 0, StackOffset: 4
61// sw REGX, 4(SP)
62//
63// - reference to previous stack frame
64// suppose there's a load to the 5th arguments : FI < 0, StackOffset: 16.
65// The emitted instruction will be something like:
66// lw REGX, 16+StackSize(SP)
67//
68// Since the total stack size is unknown on LowerFormalArguments, all
69// stack references (ObjectOffset) created to reference the function
70// arguments, are negative numbers. This way, on eliminateFrameIndex it's
71// possible to detect those references and the offsets are adjusted to
72// their real location.
73//
74//===----------------------------------------------------------------------===//
75
77 if (ST.inMips16Mode())
79
81}
82
83// hasFPImpl - Return true if the specified function should have a dedicated
84// frame pointer register. This is true if the function has variable sized
85// allocas, if it needs dynamic stack realignment, if frame pointer elimination
86// is disabled, or if the frame address is taken.
88 const MachineFrameInfo &MFI = MF.getFrameInfo();
90
93 TRI->hasStackRealignment(MF);
94}
95
97 const MachineFrameInfo &MFI = MF.getFrameInfo();
99
100 return MFI.hasVarSizedObjects() && TRI->hasStackRealignment(MF);
101}
102
103// Estimate the size of the stack, including the incoming arguments. We need to
104// account for register spills, local objects, reserved call frame and incoming
105// arguments. This is required to determine the largest possible positive offset
106// from $sp so that it can be determined if an emergency spill slot for stack
107// addresses is required.
109 const MachineFrameInfo &MFI = MF.getFrameInfo();
111
112 int64_t Size = 0;
113
114 // Iterate over fixed sized objects which are incoming arguments.
115 for (int I = MFI.getObjectIndexBegin(); I != 0; ++I)
116 if (MFI.getObjectOffset(I) > 0)
117 Size += MFI.getObjectSize(I);
118
119 // Conservatively assume all callee-saved registers will be saved.
120 for (const MCPhysReg *R = TRI.getCalleeSavedRegs(&MF); *R; ++R) {
121 unsigned RegSize = TRI.getSpillSize(*TRI.getMinimalPhysRegClass(*R));
123 }
124
125 // Get the size of the rest of the frame objects and any possible reserved
126 // call frame, accounting for alignment.
127 return Size + MFI.estimateStackSize(MF);
128}
129
130// Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions
134 unsigned SP = STI.getABI().IsN64() ? Mips::SP_64 : Mips::SP;
135
136 if (!hasReservedCallFrame(MF)) {
137 int64_t Amount = I->getOperand(0).getImm();
138 if (I->getOpcode() == Mips::ADJCALLSTACKDOWN)
139 Amount = -Amount;
140
141 STI.getInstrInfo()->adjustStackPtr(SP, Amount, MBB, I);
142 }
143
144 return MBB.erase(I);
145}
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 TargetMachine & 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 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...
bool hasFPImpl(const MachineFunction &MF) const override
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.