LLVM 18.0.0git
Mips16FrameLowering.cpp
Go to the documentation of this file.
1//===- Mips16FrameLowering.cpp - Mips16 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 Mips16 implementation of TargetFrameLowering class.
10//
11//===----------------------------------------------------------------------===//
12
13#include "Mips16FrameLowering.h"
15#include "Mips16InstrInfo.h"
16#include "MipsInstrInfo.h"
17#include "MipsRegisterInfo.h"
18#include "MipsSubtarget.h"
19#include "llvm/ADT/BitVector.h"
26#include "llvm/IR/DebugLoc.h"
27#include "llvm/MC/MCContext.h"
28#include "llvm/MC/MCDwarf.h"
33#include <cassert>
34#include <cstdint>
35#include <vector>
36
37using namespace llvm;
38
40 : MipsFrameLowering(STI, STI.getStackAlignment()) {}
41
43 MachineBasicBlock &MBB) const {
45 const Mips16InstrInfo &TII =
46 *static_cast<const Mips16InstrInfo *>(STI.getInstrInfo());
48
49 // Debug location must be unknown since the first debug location is used
50 // to determine the end of the prologue.
51 DebugLoc dl;
52
53 uint64_t StackSize = MFI.getStackSize();
54
55 // No need to allocate space on the stack.
56 if (StackSize == 0 && !MFI.adjustsStack()) return;
57
58 MachineModuleInfo &MMI = MF.getMMI();
60
61 // Adjust stack.
62 TII.makeFrame(Mips::SP, StackSize, MBB, MBBI);
63
64 // emit ".cfi_def_cfa_offset StackSize"
65 unsigned CFIIndex =
66 MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, StackSize));
67 BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
68 .addCFIIndex(CFIIndex);
69
70 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
71
72 if (!CSI.empty()) {
73 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
74
75 for (const CalleeSavedInfo &I : CSI) {
76 int64_t Offset = MFI.getObjectOffset(I.getFrameIdx());
77 Register Reg = I.getReg();
78 unsigned DReg = MRI->getDwarfRegNum(Reg, true);
79 unsigned CFIIndex = MF.addFrameInst(
81 BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
82 .addCFIIndex(CFIIndex);
83 }
84 }
85 if (hasFP(MF))
86 BuildMI(MBB, MBBI, dl, TII.get(Mips::MoveR3216), Mips::S0)
88}
89
91 MachineBasicBlock &MBB) const {
94 const Mips16InstrInfo &TII =
95 *static_cast<const Mips16InstrInfo *>(STI.getInstrInfo());
96 DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
97 uint64_t StackSize = MFI.getStackSize();
98
99 if (!StackSize)
100 return;
101
102 if (hasFP(MF))
103 BuildMI(MBB, MBBI, dl, TII.get(Mips::Move32R16), Mips::SP)
104 .addReg(Mips::S0);
105
106 // Adjust stack.
107 // assumes stacksize multiple of 8
108 TII.restoreFrame(Mips::SP, StackSize, MBB, MBBI);
109}
110
115
116 //
117 // Registers RA, S0,S1 are the callee saved registers and they
118 // will be saved with the "save" instruction
119 // during emitPrologue
120 //
121 for (const CalleeSavedInfo &I : CSI) {
122 // Add the callee-saved register as live-in. Do not add if the register is
123 // RA and return address is taken, because it has already been added in
124 // method MipsTargetLowering::lowerRETURNADDR.
125 // It's killed at the spill, unless the register is RA and return address
126 // is taken.
127 Register Reg = I.getReg();
128 bool IsRAAndRetAddrIsTaken = (Reg == Mips::RA)
130 if (!IsRAAndRetAddrIsTaken)
131 MBB.addLiveIn(Reg);
132 }
133
134 return true;
135}
136
140 //
141 // Registers RA,S0,S1 are the callee saved registers and they will be restored
142 // with the restore instruction during emitEpilogue.
143 // We need to override this virtual function, otherwise llvm will try and
144 // restore the registers on it's on from the stack.
145 //
146
147 return true;
148}
149
150bool
152 const MachineFrameInfo &MFI = MF.getFrameInfo();
153 // Reserve call frame if the size of the maximum call frame fits into 15-bit
154 // immediate field and there are no variable sized objects on the stack.
155 return isInt<15>(MFI.getMaxCallFrameSize()) && !MFI.hasVarSizedObjects();
156}
157
159 BitVector &SavedRegs,
160 RegScavenger *RS) const {
162 const Mips16InstrInfo &TII =
163 *static_cast<const Mips16InstrInfo *>(STI.getInstrInfo());
164 const MipsRegisterInfo &RI = TII.getRegisterInfo();
165 const BitVector Reserved = RI.getReservedRegs(MF);
166 bool SaveS2 = Reserved[Mips::S2];
167 if (SaveS2)
168 SavedRegs.set(Mips::S2);
169 if (hasFP(MF))
170 SavedRegs.set(Mips::S0);
171}
172
173const MipsFrameLowering *
175 return new Mips16FrameLowering(ST);
176}
unsigned const MachineRegisterInfo * MRI
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator MBBI
This file implements the BitVector class.
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition: MD5.cpp:58
unsigned const TargetRegisterInfo * TRI
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
BitVector & set()
Definition: BitVector.h:351
The CalleeSavedInfo class tracks the information need to locate where a callee saved register is in t...
A debug info location.
Definition: DebugLoc.h:33
static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register, int Offset, SMLoc Loc={})
.cfi_offset Previous value of Register is saved at offset Offset from CFA.
Definition: MCDwarf.h:582
static MCCFIInstruction cfiDefCfaOffset(MCSymbol *L, int Offset, SMLoc Loc={})
.cfi_def_cfa_offset modifies a rule for computing CFA.
Definition: MCDwarf.h:555
const MCRegisterInfo * getRegisterInfo() const
Definition: MCContext.h:448
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
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 ...
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
bool adjustsStack() const
Return true if this function adjusts the stack – e.g., when calling another function.
bool isReturnAddressTaken() const
This method may be called any time after instruction selection is complete to determine if there is a...
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
unsigned getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
unsigned addFrameInst(const MCCFIInstruction &Inst)
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineModuleInfo & getMMI() const
const MachineInstrBuilder & addCFIIndex(unsigned CFIIndex) const
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
This class contains meta information specific to a module.
const MCContext & getContext() const
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS) const override
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, ArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI) const override
spillCalleeSavedRegisters - Issues instruction(s) to spill all callee saved registers and returns tru...
bool hasReservedCallFrame(const MachineFunction &MF) const override
hasReservedCallFrame - Under normal circumstances, when a frame pointer is not required,...
Mips16FrameLowering(const MipsSubtarget &STI)
bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, MutableArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI) const override
restoreCalleeSavedRegisters - Issues instruction(s) to restore all callee saved registers and returns...
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override
emitProlog/emitEpilog - These methods insert prolog and epilog code into the function.
bool hasFP(const MachineFunction &MF) const override
hasFP - Return true if the specified function should have a dedicated frame pointer register.
const MipsSubtarget & STI
BitVector getReservedRegs(const MachineFunction &MF) const override
const MipsInstrInfo * getInstrInfo() const override
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Definition: ArrayRef.h:307
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
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
@ Offset
Definition: DWP.cpp:440
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
const MipsFrameLowering * createMips16FrameLowering(const MipsSubtarget &ST)
Create MipsFrameLowering objects.