LLVM 20.0.0git
X86ArgumentStackSlotRebase.cpp
Go to the documentation of this file.
1//===---- X86ArgumentStackSlotRebase.cpp - rebase argument stack slot -----===//
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 pass replace the frame register with a GPR virtual register and set
10// the stack offset for each instruction which reference argument from stack.
11//
12//===----------------------------------------------------------------------===//
13
14#include "X86.h"
16#include "X86RegisterInfo.h"
17#include "X86Subtarget.h"
27#include "llvm/IR/Attributes.h"
28#include "llvm/IR/Function.h"
30#include "llvm/Pass.h"
31
32using namespace llvm;
33
34#define DEBUG_TYPE "x86argumentstackrebase"
35
36namespace {
37
38class X86ArgumentStackSlotPass : public MachineFunctionPass {
39
40public:
41 static char ID; // Pass identification, replacement for typeid
42
43 explicit X86ArgumentStackSlotPass() : MachineFunctionPass(ID) {
45 }
46
47 bool runOnMachineFunction(MachineFunction &MF) override;
48
49 void getAnalysisUsage(AnalysisUsage &AU) const override {
50 AU.setPreservesCFG();
52 }
53};
54
55} // end anonymous namespace
56
57char X86ArgumentStackSlotPass::ID = 0;
58
59INITIALIZE_PASS(X86ArgumentStackSlotPass, DEBUG_TYPE, "Argument Stack Rebase",
60 false, false)
61
63 return new X86ArgumentStackSlotPass();
64}
65
68 const X86Subtarget &STI = MF.getSubtarget<X86Subtarget>();
69 const Function &F = MF.getFunction();
70 CallingConv::ID CC = F.getCallingConv();
71 Register NoReg;
72 const TargetRegisterClass *RC = nullptr;
73 switch (CC) {
74 // We need a virtual register in case there is inline assembly
75 // clobber argument base register.
76 case CallingConv::C:
77 RC = STI.is64Bit() ? &X86::GR64_ArgRefRegClass : &X86::GR32_ArgRefRegClass;
78 break;
80 // FIXME: For regcall there is no scratch register on 32-bit target.
81 // We may use a callee saved register as argument base register and
82 // save it before being changed as base pointer. We need DW_CFA to
83 // indicate where the callee saved register is saved, so that it can
84 // be correctly unwind.
85 // push ebx
86 // mov ebx, esp
87 // and esp, -128
88 // ...
89 // pop ebx
90 // ret
91 RC = STI.is64Bit() ? &X86::GR64_ArgRefRegClass : nullptr;
92 break;
93 // TODO: Refine register class for each calling convention.
94 default:
95 break;
96 }
97 if (RC)
98 return MRI.createVirtualRegister(RC);
99 else
100 return NoReg;
101}
102
103bool X86ArgumentStackSlotPass::runOnMachineFunction(MachineFunction &MF) {
104 const Function &F = MF.getFunction();
105 MachineFrameInfo &MFI = MF.getFrameInfo();
106 const X86Subtarget &STI = MF.getSubtarget<X86Subtarget>();
107 const X86RegisterInfo *TRI = STI.getRegisterInfo();
108 const X86InstrInfo *TII = STI.getInstrInfo();
110 bool Changed = false;
111
112 if (F.hasFnAttribute(Attribute::Naked))
113 return false;
114 // Only support Linux and ELF.
115 if (!STI.isTargetLinux() && !STI.isTargetELF())
116 return false;
117 if (!TRI->hasBasePointer(MF))
118 return false;
119 // Don't support X32
120 if (STI.isTarget64BitILP32())
121 return false;
122
123 Register BasePtr = TRI->getBaseRegister();
124 auto IsBaseRegisterClobbered = [&]() {
125 for (MachineBasicBlock &MBB : MF) {
126 for (MachineInstr &MI : MBB) {
127 if (!MI.isInlineAsm())
128 continue;
129 for (MachineOperand &MO : MI.operands()) {
130 if (!MO.isReg())
131 continue;
132 Register Reg = MO.getReg();
134 continue;
135 if (TRI->isSuperOrSubRegisterEq(BasePtr, Reg))
136 return true;
137 }
138 }
139 }
140 return false;
141 };
142 if (!IsBaseRegisterClobbered())
143 return false;
144
145 Register ArgBaseReg = getArgBaseReg(MF);
146 if (!ArgBaseReg.isValid())
147 return false;
148 // leal 4(%esp), %reg
151 DebugLoc DL;
152 // Emit instruction to copy get stack pointer to a virtual register
153 // and save the instruction to x86 machine functon info. We can get
154 // physical register of ArgBaseReg after register allocation. The
155 // stack slot is used to save/restore argument base pointer. We can
156 // get the index from the instruction.
157 unsigned SlotSize = TRI->getSlotSize();
158 int FI = MFI.CreateSpillStackObject(SlotSize, Align(SlotSize));
159 // Use pseudo LEA to prevent the instruction from being eliminated.
160 // TODO: if it is duplicated we can expand it to lea.
161 MachineInstr *LEA =
162 BuildMI(MBB, MBBI, DL,
163 TII->get(STI.is64Bit() ? X86::PLEA64r : X86::PLEA32r), ArgBaseReg)
164 .addFrameIndex(FI)
165 .addImm(1)
166 .addUse(X86::NoRegister)
167 .addImm(SlotSize)
168 .addUse(X86::NoRegister)
170 X86FI->setStackPtrSaveMI(LEA);
171
172 for (MachineBasicBlock &MBB : MF) {
173 for (MachineInstr &MI : MBB) {
174 int I = 0;
175 for (MachineOperand &MO : MI.operands()) {
176 if (MO.isFI()) {
177 int Idx = MO.getIndex();
178 if (!MFI.isFixedObjectIndex(Idx))
179 continue;
180 int64_t Offset = MFI.getObjectOffset(Idx);
181 if (Offset < 0)
182 continue;
183 // TODO replace register for debug instruction
184 if (MI.isDebugInstr())
185 continue;
186 // Replace frame register with argument base pointer and its offset.
187 TRI->eliminateFrameIndex(MI.getIterator(), I, ArgBaseReg, Offset);
188 Changed = true;
189 }
190 ++I;
191 }
192 }
193 }
194
195 return Changed;
196}
unsigned const MachineRegisterInfo * MRI
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
This file contains the simple types necessary to represent the attributes associated with functions a...
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
unsigned const TargetRegisterInfo * TRI
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:38
static Register getArgBaseReg(MachineFunction &MF)
#define DEBUG_TYPE
Represent the analysis usage information of a pass.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition: Pass.cpp:256
A debug info location.
Definition: DebugLoc.h:33
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:310
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
int CreateSpillStackObject(uint64_t Size, Align Alignment)
Create a new statically sized stack object that represents a spill slot, returning a nonnegative iden...
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
bool isFixedObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a fixed stack object.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
Representation of each machine instruction.
Definition: MachineInstr.h:69
MachineOperand class - Representation of each machine instruction operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
constexpr bool isValid() const
Definition: Register.h:116
static constexpr bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
Definition: Register.h:65
X86MachineFunctionInfo - This class is derived from MachineFunction and contains private X86 target-s...
void setStackPtrSaveMI(MachineInstr *MI)
bool isTarget64BitILP32() const
Is this x86_64 with the ILP32 programming model (x32 ABI)?
Definition: X86Subtarget.h:173
const X86InstrInfo * getInstrInfo() const override
Definition: X86Subtarget.h:122
bool isTargetELF() const
Definition: X86Subtarget.h:286
const X86RegisterInfo * getRegisterInfo() const override
Definition: X86Subtarget.h:132
bool isTargetLinux() const
Definition: X86Subtarget.h:290
@ X86_RegCall
Register calling convention used for parameters transfer optimization.
Definition: CallingConv.h:203
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
Reg
All possible values of the reg field in the ModR/M byte.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:480
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
void initializeX86ArgumentStackSlotPassPass(PassRegistry &)
FunctionPass * createX86ArgumentStackSlotPass()
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39