blob: 161bfa7b54748893d5a7fff3cad60b06131a10a8 [file] [log] [blame]
Zvi Rackover76dbf262016-11-15 06:34:33 +00001//===-- llvm/lib/Target/X86/X86CallLowering.cpp - Call lowering -----------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9///
10/// \file
11/// This file implements the lowering of LLVM calls to machine code calls for
12/// GlobalISel.
13///
14//===----------------------------------------------------------------------===//
15
16#include "X86CallLowering.h"
Igor Breger8a924be2017-03-23 12:13:29 +000017#include "X86CallingConv.h"
Zvi Rackover76dbf262016-11-15 06:34:33 +000018#include "X86ISelLowering.h"
19#include "X86InstrInfo.h"
Igor Breger9ea154d2017-01-29 08:35:42 +000020#include "X86TargetMachine.h"
Igor Breger9ea154d2017-01-29 08:35:42 +000021
Zvi Rackover76dbf262016-11-15 06:34:33 +000022#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
Igor Breger9ea154d2017-01-29 08:35:42 +000023#include "llvm/CodeGen/MachineRegisterInfo.h"
Igor Breger8a924be2017-03-23 12:13:29 +000024#include "llvm/CodeGen/MachineValueType.h"
Igor Breger9ea154d2017-01-29 08:35:42 +000025#include "llvm/Target/TargetSubtargetInfo.h"
Zvi Rackover76dbf262016-11-15 06:34:33 +000026
27using namespace llvm;
28
Igor Breger9ea154d2017-01-29 08:35:42 +000029#include "X86GenCallingConv.inc"
30
Zvi Rackover76dbf262016-11-15 06:34:33 +000031#ifndef LLVM_BUILD_GLOBAL_ISEL
32#error "This shouldn't be built without GISel"
33#endif
34
35X86CallLowering::X86CallLowering(const X86TargetLowering &TLI)
36 : CallLowering(&TLI) {}
37
Igor Breger5c31a4c2017-02-06 08:37:41 +000038void X86CallLowering::splitToValueTypes(const ArgInfo &OrigArg,
39 SmallVectorImpl<ArgInfo> &SplitArgs,
40 const DataLayout &DL,
41 MachineRegisterInfo &MRI,
42 SplitArgTy PerformArgSplit) const {
43
44 const X86TargetLowering &TLI = *getTLI<X86TargetLowering>();
45 LLVMContext &Context = OrigArg.Ty->getContext();
46 EVT VT = TLI.getValueType(DL, OrigArg.Ty);
47 unsigned NumParts = TLI.getNumRegisters(Context, VT);
48
49 if (NumParts == 1) {
Igor Bregera8ba5722017-03-23 15:25:57 +000050 // replace the original type ( pointer -> GPR ).
51 SplitArgs.emplace_back(OrigArg.Reg, VT.getTypeForEVT(Context),
52 OrigArg.Flags, OrigArg.IsFixed);
Igor Breger5c31a4c2017-02-06 08:37:41 +000053 return;
54 }
55
Igor Breger5c31a4c2017-02-06 08:37:41 +000056 SmallVector<unsigned, 8> SplitRegs;
57
58 EVT PartVT = TLI.getRegisterType(Context, VT);
59 Type *PartTy = PartVT.getTypeForEVT(Context);
60
61 for (unsigned i = 0; i < NumParts; ++i) {
Daniel Sanders52b4ce72017-03-07 23:20:35 +000062 ArgInfo Info =
63 ArgInfo{MRI.createGenericVirtualRegister(getLLTForType(*PartTy, DL)),
64 PartTy, OrigArg.Flags};
Igor Breger5c31a4c2017-02-06 08:37:41 +000065 SplitArgs.push_back(Info);
Igor Breger87aafa02017-04-24 17:05:52 +000066 SplitRegs.push_back(Info.Reg);
Igor Breger5c31a4c2017-02-06 08:37:41 +000067 }
Igor Breger87aafa02017-04-24 17:05:52 +000068
69 PerformArgSplit(SplitRegs);
Igor Breger5c31a4c2017-02-06 08:37:41 +000070}
71
72namespace {
73struct FuncReturnHandler : public CallLowering::ValueHandler {
74 FuncReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
75 MachineInstrBuilder &MIB, CCAssignFn *AssignFn)
76 : ValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB) {}
77
78 unsigned getStackAddress(uint64_t Size, int64_t Offset,
79 MachinePointerInfo &MPO) override {
80 llvm_unreachable("Don't know how to get a stack address yet");
81 }
82
83 void assignValueToReg(unsigned ValVReg, unsigned PhysReg,
84 CCValAssign &VA) override {
85 MIB.addUse(PhysReg, RegState::Implicit);
86 unsigned ExtReg = extendRegister(ValVReg, VA);
87 MIRBuilder.buildCopy(PhysReg, ExtReg);
88 }
89
90 void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size,
91 MachinePointerInfo &MPO, CCValAssign &VA) override {
92 llvm_unreachable("Don't know how to assign a value to an address yet");
93 }
94
95 MachineInstrBuilder &MIB;
96};
97} // End anonymous namespace.
98
Zvi Rackover76dbf262016-11-15 06:34:33 +000099bool X86CallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
100 const Value *Val, unsigned VReg) const {
Zvi Rackover76dbf262016-11-15 06:34:33 +0000101
Igor Breger5c31a4c2017-02-06 08:37:41 +0000102 assert(((Val && VReg) || (!Val && !VReg)) && "Return value without a vreg");
Igor Breger9ea154d2017-01-29 08:35:42 +0000103
Igor Breger5c31a4c2017-02-06 08:37:41 +0000104 auto MIB = MIRBuilder.buildInstrNoInsert(X86::RET).addImm(0);
Zvi Rackover76dbf262016-11-15 06:34:33 +0000105
Igor Breger5c31a4c2017-02-06 08:37:41 +0000106 if (VReg) {
107 MachineFunction &MF = MIRBuilder.getMF();
108 MachineRegisterInfo &MRI = MF.getRegInfo();
109 auto &DL = MF.getDataLayout();
110 const Function &F = *MF.getFunction();
111
112 ArgInfo OrigArg{VReg, Val->getType()};
Reid Klecknerb5180542017-03-21 16:57:19 +0000113 setArgFlags(OrigArg, AttributeList::ReturnIndex, DL, F);
Igor Breger5c31a4c2017-02-06 08:37:41 +0000114
115 SmallVector<ArgInfo, 8> SplitArgs;
Igor Breger87aafa02017-04-24 17:05:52 +0000116 splitToValueTypes(
117 OrigArg, SplitArgs, DL, MRI,
118 [&](ArrayRef<unsigned> Regs) { MIRBuilder.buildUnmerge(Regs, VReg); });
Igor Breger5c31a4c2017-02-06 08:37:41 +0000119
120 FuncReturnHandler Handler(MIRBuilder, MRI, MIB, RetCC_X86);
Igor Breger8a924be2017-03-23 12:13:29 +0000121 if (!handleAssignments(MIRBuilder, SplitArgs, Handler))
Igor Breger5c31a4c2017-02-06 08:37:41 +0000122 return false;
123 }
124
125 MIRBuilder.insertInstr(MIB);
Zvi Rackover76dbf262016-11-15 06:34:33 +0000126 return true;
127}
128
Igor Breger9ea154d2017-01-29 08:35:42 +0000129namespace {
130struct FormalArgHandler : public CallLowering::ValueHandler {
131 FormalArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
132 CCAssignFn *AssignFn, const DataLayout &DL)
133 : ValueHandler(MIRBuilder, MRI, AssignFn), DL(DL) {}
134
135 unsigned getStackAddress(uint64_t Size, int64_t Offset,
136 MachinePointerInfo &MPO) override {
137
138 auto &MFI = MIRBuilder.getMF().getFrameInfo();
139 int FI = MFI.CreateFixedObject(Size, Offset, true);
140 MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI);
141
Igor Breger8a924be2017-03-23 12:13:29 +0000142 unsigned AddrReg = MRI.createGenericVirtualRegister(
143 LLT::pointer(0, DL.getPointerSizeInBits(0)));
Igor Breger9ea154d2017-01-29 08:35:42 +0000144 MIRBuilder.buildFrameIndex(AddrReg, FI);
145 return AddrReg;
146 }
147
148 void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size,
149 MachinePointerInfo &MPO, CCValAssign &VA) override {
150
151 auto MMO = MIRBuilder.getMF().getMachineMemOperand(
152 MPO, MachineMemOperand::MOLoad | MachineMemOperand::MOInvariant, Size,
153 0);
154 MIRBuilder.buildLoad(ValVReg, Addr, *MMO);
155 }
156
157 void assignValueToReg(unsigned ValVReg, unsigned PhysReg,
158 CCValAssign &VA) override {
159 MIRBuilder.getMBB().addLiveIn(PhysReg);
160 MIRBuilder.buildCopy(ValVReg, PhysReg);
161 }
162
163 const DataLayout &DL;
164};
Igor Breger8a924be2017-03-23 12:13:29 +0000165} // namespace
Igor Breger9ea154d2017-01-29 08:35:42 +0000166
Zvi Rackover76dbf262016-11-15 06:34:33 +0000167bool X86CallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
168 const Function &F,
169 ArrayRef<unsigned> VRegs) const {
Igor Breger9ea154d2017-01-29 08:35:42 +0000170 if (F.arg_empty())
171 return true;
172
Igor Breger8a924be2017-03-23 12:13:29 +0000173 // TODO: handle variadic function
Igor Breger9ea154d2017-01-29 08:35:42 +0000174 if (F.isVarArg())
175 return false;
176
Igor Breger5c31a4c2017-02-06 08:37:41 +0000177 MachineFunction &MF = MIRBuilder.getMF();
178 MachineRegisterInfo &MRI = MF.getRegInfo();
179 auto DL = MF.getDataLayout();
Igor Breger9ea154d2017-01-29 08:35:42 +0000180
Igor Breger5c31a4c2017-02-06 08:37:41 +0000181 SmallVector<ArgInfo, 8> SplitArgs;
Igor Breger9ea154d2017-01-29 08:35:42 +0000182 unsigned Idx = 0;
Reid Kleckner45707d42017-03-16 22:59:15 +0000183 for (auto &Arg : F.args()) {
Igor Breger5c31a4c2017-02-06 08:37:41 +0000184 ArgInfo OrigArg(VRegs[Idx], Arg.getType());
185 setArgFlags(OrigArg, Idx + 1, DL, F);
186 splitToValueTypes(OrigArg, SplitArgs, DL, MRI,
Igor Breger87aafa02017-04-24 17:05:52 +0000187 [&](ArrayRef<unsigned> Regs) {
188 MIRBuilder.buildMerge(VRegs[Idx], Regs);
Igor Breger5c31a4c2017-02-06 08:37:41 +0000189 });
Igor Breger9ea154d2017-01-29 08:35:42 +0000190 Idx++;
191 }
192
Igor Breger5c31a4c2017-02-06 08:37:41 +0000193 MachineBasicBlock &MBB = MIRBuilder.getMBB();
194 if (!MBB.empty())
Igor Breger8a924be2017-03-23 12:13:29 +0000195 MIRBuilder.setInstr(*MBB.begin());
Igor Breger5c31a4c2017-02-06 08:37:41 +0000196
197 FormalArgHandler Handler(MIRBuilder, MRI, CC_X86, DL);
198 if (!handleAssignments(MIRBuilder, SplitArgs, Handler))
199 return false;
200
201 // Move back to the end of the basic block.
202 MIRBuilder.setMBB(MBB);
203
204 return true;
Zvi Rackover76dbf262016-11-15 06:34:33 +0000205}