LLVM 19.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"
15#include "X86InstrBuilder.h"
17#include "X86RegisterInfo.h"
18#include "X86Subtarget.h"
29#include "llvm/IR/Attributes.h"
30#include "llvm/IR/Function.h"
32#include "llvm/Pass.h"
33
34using namespace llvm;
35
36#define DEBUG_TYPE "x86argumentstackrebase"
37
38namespace {
39
40class X86ArgumentStackSlotPass : public MachineFunctionPass {
41
42public:
43 static char ID; // Pass identification, replacement for typeid
44
45 explicit X86ArgumentStackSlotPass() : MachineFunctionPass(ID) {
47 }
48
49 bool runOnMachineFunction(MachineFunction &MF) override;
50
51 void getAnalysisUsage(AnalysisUsage &AU) const override {
52 AU.setPreservesCFG();
54 }
55};
56
57} // end anonymous namespace
58
59char X86ArgumentStackSlotPass::ID = 0;
60
61INITIALIZE_PASS(X86ArgumentStackSlotPass, DEBUG_TYPE, "Argument Stack Rebase",
62 false, false)
63
65 return new X86ArgumentStackSlotPass();
66}
67
70 const X86Subtarget &STI = MF.getSubtarget<X86Subtarget>();
71 const Function &F = MF.getFunction();
72 CallingConv::ID CC = F.getCallingConv();
73 Register NoReg;
74 const TargetRegisterClass *RC = nullptr;
75 switch (CC) {
76 // We need a virtual register in case there is inline assembly
77 // clobber argument base register.
78 case CallingConv::C:
79 RC = STI.is64Bit() ? &X86::GR64_ArgRefRegClass : &X86::GR32_ArgRefRegClass;
80 break;
82 // FIXME: For regcall there is no scratch register on 32-bit target.
83 // We may use a callee saved register as argument base register and
84 // save it before being changed as base pointer. We need DW_CFA to
85 // indicate where the callee saved register is saved, so that it can
86 // be correctly unwind.
87 // push ebx
88 // mov ebx, esp
89 // and esp, -128
90 // ...
91 // pop ebx
92 // ret
93 RC = STI.is64Bit() ? &X86::GR64_ArgRefRegClass : nullptr;
94 break;
95 // TODO: Refine register class for each calling convention.
96 default:
97 break;
98 }
99 if (RC)
100 return MRI.createVirtualRegister(RC);
101 else
102 return NoReg;
103}
104
105bool X86ArgumentStackSlotPass::runOnMachineFunction(MachineFunction &MF) {
106 const Function &F = MF.getFunction();
107 MachineFrameInfo &MFI = MF.getFrameInfo();
108 const X86Subtarget &STI = MF.getSubtarget<X86Subtarget>();
109 const X86RegisterInfo *TRI = STI.getRegisterInfo();
110 const X86InstrInfo *TII = STI.getInstrInfo();
112 bool Changed = false;
113
114 if (F.hasFnAttribute(Attribute::Naked))
115 return false;
116 // Only support Linux and ELF.
117 if (!STI.isTargetLinux() && !STI.isTargetELF())
118 return false;
119 if (!TRI->hasBasePointer(MF))
120 return false;
121 // Don't support X32
122 if (STI.isTarget64BitILP32())
123 return false;
124
125 Register BasePtr = TRI->getBaseRegister();
126 auto IsBaseRegisterClobbered = [&]() {
127 for (MachineBasicBlock &MBB : MF) {
128 for (MachineInstr &MI : MBB) {
129 if (!MI.isInlineAsm())
130 continue;
131 for (MachineOperand &MO : MI.operands()) {
132 if (!MO.isReg())
133 continue;
134 Register Reg = MO.getReg();
136 continue;
137 if (TRI->isSuperOrSubRegisterEq(BasePtr, Reg))
138 return true;
139 }
140 }
141 }
142 return false;
143 };
144 if (!IsBaseRegisterClobbered())
145 return false;
146
147 Register ArgBaseReg = getArgBaseReg(MF);
148 if (!ArgBaseReg.isValid())
149 return false;
150 // leal 4(%esp), %reg
153 DebugLoc DL;
154 // Emit instruction to copy get stack pointer to a virtual register
155 // and save the instruction to x86 machine functon info. We can get
156 // physical register of ArgBaseReg after register allocation. The
157 // stack slot is used to save/restore argument base pointer. We can
158 // get the index from the instruction.
159 unsigned SlotSize = TRI->getSlotSize();
160 int FI = MFI.CreateSpillStackObject(SlotSize, Align(SlotSize));
161 // Use pseudo LEA to prevent the instruction from being eliminated.
162 // TODO: if it is duplicated we can expand it to lea.
163 MachineInstr *LEA =
164 BuildMI(MBB, MBBI, DL,
165 TII->get(STI.is64Bit() ? X86::PLEA64r : X86::PLEA32r), ArgBaseReg)
166 .addFrameIndex(FI)
167 .addImm(1)
168 .addUse(X86::NoRegister)
169 .addImm(SlotSize)
170 .addUse(X86::NoRegister)
172 X86FI->setStackPtrSaveMI(LEA);
173
174 for (MachineBasicBlock &MBB : MF) {
175 for (MachineInstr &MI : MBB) {
176 int I = 0;
177 for (MachineOperand &MO : MI.operands()) {
178 if (MO.isFI()) {
179 int Idx = MO.getIndex();
180 if (!MFI.isFixedObjectIndex(Idx))
181 continue;
182 int64_t Offset = MFI.getObjectOffset(Idx);
183 if (Offset < 0)
184 continue;
185 // TODO replace register for debug instruction
186 if (MI.isDebugInstr())
187 continue;
188 // Replace frame register with argument base pointer and its offset.
189 TRI->eliminateFrameIndex(MI.getIterator(), I, ArgBaseReg, Offset);
190 Changed = true;
191 }
192 ++I;
193 }
194 }
195 }
196
197 return Changed;
198}
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:269
A debug info location.
Definition: DebugLoc.h:33
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:311
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:180
const X86InstrInfo * getInstrInfo() const override
Definition: X86Subtarget.h:129
bool isTargetELF() const
Definition: X86Subtarget.h:299
const X86RegisterInfo * getRegisterInfo() const override
Definition: X86Subtarget.h:139
bool isTargetLinux() const
Definition: X86Subtarget.h:303
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
@ 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
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:456
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