1 //===---- X86ArgumentStackSlotRebase.cpp - rebase argument stack slot -----===//
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
7 //===----------------------------------------------------------------------===//
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.
12 //===----------------------------------------------------------------------===//
15 #include "X86InstrBuilder.h"
16 #include "X86MachineFunctionInfo.h"
17 #include "X86RegisterInfo.h"
18 #include "X86Subtarget.h"
19 #include "llvm/CodeGen/MachineBasicBlock.h"
20 #include "llvm/CodeGen/MachineFrameInfo.h"
21 #include "llvm/CodeGen/MachineFunction.h"
22 #include "llvm/CodeGen/MachineFunctionPass.h"
23 #include "llvm/CodeGen/MachineInstr.h"
24 #include "llvm/CodeGen/MachineOperand.h"
25 #include "llvm/CodeGen/MachineRegisterInfo.h"
26 #include "llvm/CodeGen/TargetOpcodes.h"
27 #include "llvm/CodeGen/TargetRegisterInfo.h"
28 #include "llvm/CodeGen/TargetSubtargetInfo.h"
29 #include "llvm/IR/Attributes.h"
30 #include "llvm/IR/Function.h"
31 #include "llvm/InitializePasses.h"
32 #include "llvm/Pass.h"
36 #define DEBUG_TYPE "x86argumentstackrebase"
40 class X86ArgumentStackSlotPass
: public MachineFunctionPass
{
43 static char ID
; // Pass identification, replacement for typeid
45 explicit X86ArgumentStackSlotPass() : MachineFunctionPass(ID
) {
46 initializeX86ArgumentStackSlotPassPass(*PassRegistry::getPassRegistry());
49 bool runOnMachineFunction(MachineFunction
&MF
) override
;
51 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
53 MachineFunctionPass::getAnalysisUsage(AU
);
57 } // end anonymous namespace
59 char X86ArgumentStackSlotPass::ID
= 0;
61 INITIALIZE_PASS(X86ArgumentStackSlotPass
, DEBUG_TYPE
, "Argument Stack Rebase",
64 FunctionPass
*llvm::createX86ArgumentStackSlotPass() {
65 return new X86ArgumentStackSlotPass();
68 static Register
getArgBaseReg(MachineFunction
&MF
) {
69 MachineRegisterInfo
&MRI
= MF
.getRegInfo();
70 const X86Subtarget
&STI
= MF
.getSubtarget
<X86Subtarget
>();
71 const Function
&F
= MF
.getFunction();
72 CallingConv::ID CC
= F
.getCallingConv();
74 const TargetRegisterClass
*RC
= nullptr;
76 // We need a virtual register in case there is inline assembly
77 // clobber argument base register.
79 RC
= STI
.is64Bit() ? &X86::GR64_ArgRefRegClass
: &X86::GR32_ArgRefRegClass
;
81 case CallingConv::X86_RegCall
:
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.
93 RC
= STI
.is64Bit() ? &X86::GR64_ArgRefRegClass
: nullptr;
95 // TODO: Refine register class for each calling convention.
100 return MRI
.createVirtualRegister(RC
);
105 bool 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();
111 X86MachineFunctionInfo
*X86FI
= MF
.getInfo
<X86MachineFunctionInfo
>();
112 bool Changed
= false;
114 if (F
.hasFnAttribute(Attribute::Naked
))
116 // Only support Linux and ELF.
117 if (!STI
.isTargetLinux() && !STI
.isTargetELF())
119 if (!TRI
->hasBasePointer(MF
))
122 if (STI
.isTarget64BitILP32())
125 Register BasePtr
= TRI
->getBaseRegister();
126 auto IsBaseRegisterClobbered
= [&]() {
127 for (MachineBasicBlock
&MBB
: MF
) {
128 for (MachineInstr
&MI
: MBB
) {
129 if (!MI
.isInlineAsm())
131 for (MachineOperand
&MO
: MI
.operands()) {
134 Register Reg
= MO
.getReg();
135 if (!Register::isPhysicalRegister(Reg
))
137 if (TRI
->isSuperOrSubRegisterEq(BasePtr
, Reg
))
144 if (!IsBaseRegisterClobbered())
147 Register ArgBaseReg
= getArgBaseReg(MF
);
148 if (!ArgBaseReg
.isValid())
150 // leal 4(%esp), %reg
151 MachineBasicBlock
&MBB
= MF
.front();
152 MachineBasicBlock::iterator MBBI
= MBB
.begin();
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.
164 BuildMI(MBB
, MBBI
, DL
,
165 TII
->get(STI
.is64Bit() ? X86::PLEA64r
: X86::PLEA32r
), ArgBaseReg
)
168 .addUse(X86::NoRegister
)
170 .addUse(X86::NoRegister
)
171 .setMIFlag(MachineInstr::FrameSetup
);
172 X86FI
->setStackPtrSaveMI(LEA
);
174 for (MachineBasicBlock
&MBB
: MF
) {
175 for (MachineInstr
&MI
: MBB
) {
177 for (MachineOperand
&MO
: MI
.operands()) {
179 int Idx
= MO
.getIndex();
180 if (!MFI
.isFixedObjectIndex(Idx
))
182 int64_t Offset
= MFI
.getObjectOffset(Idx
);
185 // TODO replace register for debug instruction
186 if (MI
.isDebugInstr())
188 // Replace frame register with argument base pointer and its offset.
189 TRI
->eliminateFrameIndex(MI
.getIterator(), I
, ArgBaseReg
, Offset
);