LLVM 24.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"
19
20using namespace llvm;
21
22
23//===----------------------------------------------------------------------===//
24//
25// Stack Frame Processing methods
26// +----------------------------+
27//
28// The stack is allocated decrementing the stack pointer on
29// the first instruction of a function prologue. Once decremented,
30// all stack references are done thought a positive offset
31// from the stack/frame pointer, so the stack is considering
32// to grow up! Otherwise terrible hacks would have to be made
33// to get this stack ABI compliant :)
34//
35// The stack frame required by the ABI (after call):
36// Offset
37//
38// 0 ----------
39// 4 Args to pass
40// . saved $GP (used in PIC)
41// . Alloca allocations
42// . Local Area
43// . CPU "Callee Saved" Registers
44// . saved FP
45// . saved RA
46// . FPU "Callee Saved" Registers
47// StackSize -----------
48//
49// Offset - offset from sp after stack allocation on function prologue
50//
51// The sp is the stack pointer subtracted/added from the stack size
52// at the Prologue/Epilogue
53//
54// References to the previous stack (to obtain arguments) are done
55// with offsets that exceeds the stack size: (stacksize+(4*(num_arg-1))
56//
57// Examples:
58// - reference to the actual stack frame
59// for any local area var there is smt like : FI >= 0, StackOffset: 4
60// sw REGX, 4(SP)
61//
62// - reference to previous stack frame
63// suppose there's a load to the 5th arguments : FI < 0, StackOffset: 16.
64// The emitted instruction will be something like:
65// lw REGX, 16+StackSize(SP)
66//
67// Since the total stack size is unknown on LowerFormalArguments, all
68// stack references (ObjectOffset) created to reference the function
69// arguments, are negative numbers. This way, on eliminateFrameIndex it's
70// possible to detect those references and the offsets are adjusted to
71// their real location.
72//
73//===----------------------------------------------------------------------===//
74
76 if (ST.inMips16Mode())
78
80}
81
82// hasFPImpl - Return true if the specified function should have a dedicated
83// frame pointer register. This is true if the function has variable sized
84// allocas, if it needs dynamic stack realignment, if frame pointer elimination
85// is disabled, or if the frame address is taken.
87 const MachineFrameInfo &MFI = MF.getFrameInfo();
88 const TargetRegisterInfo *TRI = STI.getRegisterInfo();
89
90 return MF.disableFramePointerElim() || MFI.hasVarSizedObjects() ||
91 MFI.isFrameAddressTaken() || TRI->hasStackRealignment(MF);
92}
93
95 const MachineFrameInfo &MFI = MF.getFrameInfo();
96 const TargetRegisterInfo *TRI = STI.getRegisterInfo();
97
98 return MFI.hasVarSizedObjects() && TRI->hasStackRealignment(MF);
99}
100
101// Estimate the size of the stack, including the incoming arguments. We need to
102// account for register spills, local objects, reserved call frame and incoming
103// arguments. This is required to determine the largest possible positive offset
104// from $sp so that it can be determined if an emergency spill slot for stack
105// addresses is required.
107 const MachineFrameInfo &MFI = MF.getFrameInfo();
108 const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
109
110 int64_t Size = 0;
111
112 // Iterate over fixed sized objects which are incoming arguments.
113 for (int I = MFI.getObjectIndexBegin(); I != 0; ++I)
114 if (MFI.getObjectOffset(I) > 0)
115 Size += MFI.getObjectSize(I);
116
117 // Conservatively assume all callee-saved registers will be saved.
118 for (const MCPhysReg *R = TRI.getCalleeSavedRegs(&MF); *R; ++R) {
119 unsigned RegSize = TRI.getSpillSize(*TRI.getMinimalPhysRegClass(*R));
121 }
122
123 // Get the size of the rest of the frame objects and any possible reserved
124 // call frame, accounting for alignment.
125 return Size + MFI.estimateStackSize(MF);
126}
127
128// Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions
132 unsigned SP = STI.getABI().IsN64() ? Mips::SP_64 : Mips::SP;
133
134 if (!hasReservedCallFrame(MF)) {
135 int64_t Amount = I->getOperand(0).getImm();
136 if (I->getOpcode() == Mips::ADJCALLSTACKDOWN)
137 Amount = -Amount;
138
139 STI.getInstrInfo()->adjustStackPtr(SP, Amount, MBB, I);
140 }
141
142 return MBB.erase(I);
143}
unsigned RegSize
MachineBasicBlock & MBB
#define I(x, y, z)
Definition MD5.cpp:57
Register const TargetRegisterInfo * TRI
MachineInstrBundleIterator< MachineInstr > iterator
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...
LLVM_ABI 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.
LLVM_ABI bool disableFramePointerElim() const
Returns true if frame pointer elimination should be disabled for this function.
static const MipsFrameLowering * create(const MipsSubtarget &ST)
MipsFrameLowering(const MipsSubtarget &sti, Align Alignment)
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 bool hasReservedCallFrame(const MachineFunction &MF) const
hasReservedCallFrame - Under normal circumstances, when a frame pointer is not required,...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
This is an optimization pass for GlobalISel generic memory operations.
const MipsFrameLowering * createMipsSEFrameLowering(const MipsSubtarget &ST)
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:144
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition MCRegister.h:21
const MipsFrameLowering * createMips16FrameLowering(const MipsSubtarget &ST)
Create MipsFrameLowering objects.