blob: bb549dc048840738a361d7e5ae5578a3f191e91e [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
Igor Breger9d5571a2017-07-05 06:24:13 +000022#include "llvm/CodeGen/Analysis.h"
Zvi Rackover76dbf262016-11-15 06:34:33 +000023#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
Igor Breger9ea154d2017-01-29 08:35:42 +000024#include "llvm/CodeGen/MachineRegisterInfo.h"
Igor Breger8a924be2017-03-23 12:13:29 +000025#include "llvm/CodeGen/MachineValueType.h"
Igor Breger9ea154d2017-01-29 08:35:42 +000026#include "llvm/Target/TargetSubtargetInfo.h"
Zvi Rackover76dbf262016-11-15 06:34:33 +000027
28using namespace llvm;
29
Igor Breger9ea154d2017-01-29 08:35:42 +000030#include "X86GenCallingConv.inc"
31
Zvi Rackover76dbf262016-11-15 06:34:33 +000032#ifndef LLVM_BUILD_GLOBAL_ISEL
33#error "This shouldn't be built without GISel"
34#endif
35
36X86CallLowering::X86CallLowering(const X86TargetLowering &TLI)
37 : CallLowering(&TLI) {}
38
Igor Breger9d5571a2017-07-05 06:24:13 +000039bool X86CallLowering::splitToValueTypes(const ArgInfo &OrigArg,
Igor Breger5c31a4c2017-02-06 08:37:41 +000040 SmallVectorImpl<ArgInfo> &SplitArgs,
41 const DataLayout &DL,
42 MachineRegisterInfo &MRI,
43 SplitArgTy PerformArgSplit) const {
44
45 const X86TargetLowering &TLI = *getTLI<X86TargetLowering>();
46 LLVMContext &Context = OrigArg.Ty->getContext();
Igor Breger9d5571a2017-07-05 06:24:13 +000047
48 SmallVector<EVT, 4> SplitVTs;
49 SmallVector<uint64_t, 4> Offsets;
50 ComputeValueVTs(TLI, DL, OrigArg.Ty, SplitVTs, &Offsets, 0);
51
52 if (SplitVTs.size() != 1) {
53 // TODO: support struct/array split
54 return false;
55 }
56
57 EVT VT = SplitVTs[0];
Igor Breger5c31a4c2017-02-06 08:37:41 +000058 unsigned NumParts = TLI.getNumRegisters(Context, VT);
59
60 if (NumParts == 1) {
Igor Bregera8ba5722017-03-23 15:25:57 +000061 // replace the original type ( pointer -> GPR ).
62 SplitArgs.emplace_back(OrigArg.Reg, VT.getTypeForEVT(Context),
63 OrigArg.Flags, OrigArg.IsFixed);
Igor Breger9d5571a2017-07-05 06:24:13 +000064 return true;
Igor Breger5c31a4c2017-02-06 08:37:41 +000065 }
66
Igor Breger5c31a4c2017-02-06 08:37:41 +000067 SmallVector<unsigned, 8> SplitRegs;
68
69 EVT PartVT = TLI.getRegisterType(Context, VT);
70 Type *PartTy = PartVT.getTypeForEVT(Context);
71
72 for (unsigned i = 0; i < NumParts; ++i) {
Daniel Sanders52b4ce72017-03-07 23:20:35 +000073 ArgInfo Info =
74 ArgInfo{MRI.createGenericVirtualRegister(getLLTForType(*PartTy, DL)),
75 PartTy, OrigArg.Flags};
Igor Breger5c31a4c2017-02-06 08:37:41 +000076 SplitArgs.push_back(Info);
Igor Breger87aafa02017-04-24 17:05:52 +000077 SplitRegs.push_back(Info.Reg);
Igor Breger5c31a4c2017-02-06 08:37:41 +000078 }
Igor Breger87aafa02017-04-24 17:05:52 +000079
80 PerformArgSplit(SplitRegs);
Igor Breger9d5571a2017-07-05 06:24:13 +000081 return true;
Igor Breger5c31a4c2017-02-06 08:37:41 +000082}
83
84namespace {
85struct FuncReturnHandler : public CallLowering::ValueHandler {
86 FuncReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
87 MachineInstrBuilder &MIB, CCAssignFn *AssignFn)
88 : ValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB) {}
89
90 unsigned getStackAddress(uint64_t Size, int64_t Offset,
91 MachinePointerInfo &MPO) override {
92 llvm_unreachable("Don't know how to get a stack address yet");
93 }
94
95 void assignValueToReg(unsigned ValVReg, unsigned PhysReg,
96 CCValAssign &VA) override {
97 MIB.addUse(PhysReg, RegState::Implicit);
98 unsigned ExtReg = extendRegister(ValVReg, VA);
99 MIRBuilder.buildCopy(PhysReg, ExtReg);
100 }
101
102 void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size,
103 MachinePointerInfo &MPO, CCValAssign &VA) override {
104 llvm_unreachable("Don't know how to assign a value to an address yet");
105 }
106
107 MachineInstrBuilder &MIB;
108};
109} // End anonymous namespace.
110
Zvi Rackover76dbf262016-11-15 06:34:33 +0000111bool X86CallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
112 const Value *Val, unsigned VReg) const {
Zvi Rackover76dbf262016-11-15 06:34:33 +0000113
Igor Breger5c31a4c2017-02-06 08:37:41 +0000114 assert(((Val && VReg) || (!Val && !VReg)) && "Return value without a vreg");
Igor Breger9ea154d2017-01-29 08:35:42 +0000115
Igor Breger5c31a4c2017-02-06 08:37:41 +0000116 auto MIB = MIRBuilder.buildInstrNoInsert(X86::RET).addImm(0);
Zvi Rackover76dbf262016-11-15 06:34:33 +0000117
Igor Breger5c31a4c2017-02-06 08:37:41 +0000118 if (VReg) {
119 MachineFunction &MF = MIRBuilder.getMF();
120 MachineRegisterInfo &MRI = MF.getRegInfo();
121 auto &DL = MF.getDataLayout();
122 const Function &F = *MF.getFunction();
123
124 ArgInfo OrigArg{VReg, Val->getType()};
Reid Klecknerb5180542017-03-21 16:57:19 +0000125 setArgFlags(OrigArg, AttributeList::ReturnIndex, DL, F);
Igor Breger5c31a4c2017-02-06 08:37:41 +0000126
127 SmallVector<ArgInfo, 8> SplitArgs;
Igor Breger9d5571a2017-07-05 06:24:13 +0000128 if (!splitToValueTypes(OrigArg, SplitArgs, DL, MRI,
129 [&](ArrayRef<unsigned> Regs) {
130 MIRBuilder.buildUnmerge(Regs, VReg);
131 }))
132 return false;
Igor Breger5c31a4c2017-02-06 08:37:41 +0000133
134 FuncReturnHandler Handler(MIRBuilder, MRI, MIB, RetCC_X86);
Igor Breger8a924be2017-03-23 12:13:29 +0000135 if (!handleAssignments(MIRBuilder, SplitArgs, Handler))
Igor Breger5c31a4c2017-02-06 08:37:41 +0000136 return false;
137 }
138
139 MIRBuilder.insertInstr(MIB);
Zvi Rackover76dbf262016-11-15 06:34:33 +0000140 return true;
141}
142
Igor Breger9ea154d2017-01-29 08:35:42 +0000143namespace {
144struct FormalArgHandler : public CallLowering::ValueHandler {
145 FormalArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
146 CCAssignFn *AssignFn, const DataLayout &DL)
147 : ValueHandler(MIRBuilder, MRI, AssignFn), DL(DL) {}
148
149 unsigned getStackAddress(uint64_t Size, int64_t Offset,
150 MachinePointerInfo &MPO) override {
151
152 auto &MFI = MIRBuilder.getMF().getFrameInfo();
153 int FI = MFI.CreateFixedObject(Size, Offset, true);
154 MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI);
155
Igor Breger8a924be2017-03-23 12:13:29 +0000156 unsigned AddrReg = MRI.createGenericVirtualRegister(
157 LLT::pointer(0, DL.getPointerSizeInBits(0)));
Igor Breger9ea154d2017-01-29 08:35:42 +0000158 MIRBuilder.buildFrameIndex(AddrReg, FI);
159 return AddrReg;
160 }
161
162 void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size,
163 MachinePointerInfo &MPO, CCValAssign &VA) override {
164
165 auto MMO = MIRBuilder.getMF().getMachineMemOperand(
166 MPO, MachineMemOperand::MOLoad | MachineMemOperand::MOInvariant, Size,
167 0);
168 MIRBuilder.buildLoad(ValVReg, Addr, *MMO);
169 }
170
171 void assignValueToReg(unsigned ValVReg, unsigned PhysReg,
172 CCValAssign &VA) override {
173 MIRBuilder.getMBB().addLiveIn(PhysReg);
174 MIRBuilder.buildCopy(ValVReg, PhysReg);
175 }
176
177 const DataLayout &DL;
178};
Igor Breger8a924be2017-03-23 12:13:29 +0000179} // namespace
Igor Breger9ea154d2017-01-29 08:35:42 +0000180
Zvi Rackover76dbf262016-11-15 06:34:33 +0000181bool X86CallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
182 const Function &F,
183 ArrayRef<unsigned> VRegs) const {
Igor Breger9ea154d2017-01-29 08:35:42 +0000184 if (F.arg_empty())
185 return true;
186
Igor Breger8a924be2017-03-23 12:13:29 +0000187 // TODO: handle variadic function
Igor Breger9ea154d2017-01-29 08:35:42 +0000188 if (F.isVarArg())
189 return false;
190
Igor Breger5c31a4c2017-02-06 08:37:41 +0000191 MachineFunction &MF = MIRBuilder.getMF();
192 MachineRegisterInfo &MRI = MF.getRegInfo();
193 auto DL = MF.getDataLayout();
Igor Breger9ea154d2017-01-29 08:35:42 +0000194
Igor Breger5c31a4c2017-02-06 08:37:41 +0000195 SmallVector<ArgInfo, 8> SplitArgs;
Igor Breger9ea154d2017-01-29 08:35:42 +0000196 unsigned Idx = 0;
Reid Kleckner45707d42017-03-16 22:59:15 +0000197 for (auto &Arg : F.args()) {
Igor Breger5c31a4c2017-02-06 08:37:41 +0000198 ArgInfo OrigArg(VRegs[Idx], Arg.getType());
199 setArgFlags(OrigArg, Idx + 1, DL, F);
Igor Breger9d5571a2017-07-05 06:24:13 +0000200 if (!splitToValueTypes(OrigArg, SplitArgs, DL, MRI,
201 [&](ArrayRef<unsigned> Regs) {
202 MIRBuilder.buildMerge(VRegs[Idx], Regs);
203 }))
204 return false;
Igor Breger9ea154d2017-01-29 08:35:42 +0000205 Idx++;
206 }
207
Igor Breger5c31a4c2017-02-06 08:37:41 +0000208 MachineBasicBlock &MBB = MIRBuilder.getMBB();
209 if (!MBB.empty())
Igor Breger8a924be2017-03-23 12:13:29 +0000210 MIRBuilder.setInstr(*MBB.begin());
Igor Breger5c31a4c2017-02-06 08:37:41 +0000211
212 FormalArgHandler Handler(MIRBuilder, MRI, CC_X86, DL);
213 if (!handleAssignments(MIRBuilder, SplitArgs, Handler))
214 return false;
215
216 // Move back to the end of the basic block.
217 MIRBuilder.setMBB(MBB);
218
219 return true;
Zvi Rackover76dbf262016-11-15 06:34:33 +0000220}