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