blob: c8a3b2b51c88698358fe609fcb98ec5312d7e3c8 [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 +000032X86CallLowering::X86CallLowering(const X86TargetLowering &TLI)
33 : CallLowering(&TLI) {}
34
Igor Breger9d5571a2017-07-05 06:24:13 +000035bool X86CallLowering::splitToValueTypes(const ArgInfo &OrigArg,
Igor Breger5c31a4c2017-02-06 08:37:41 +000036 SmallVectorImpl<ArgInfo> &SplitArgs,
37 const DataLayout &DL,
38 MachineRegisterInfo &MRI,
39 SplitArgTy PerformArgSplit) const {
40
41 const X86TargetLowering &TLI = *getTLI<X86TargetLowering>();
42 LLVMContext &Context = OrigArg.Ty->getContext();
Igor Breger9d5571a2017-07-05 06:24:13 +000043
44 SmallVector<EVT, 4> SplitVTs;
45 SmallVector<uint64_t, 4> Offsets;
46 ComputeValueVTs(TLI, DL, OrigArg.Ty, SplitVTs, &Offsets, 0);
47
48 if (SplitVTs.size() != 1) {
49 // TODO: support struct/array split
50 return false;
51 }
52
53 EVT VT = SplitVTs[0];
Igor Breger5c31a4c2017-02-06 08:37:41 +000054 unsigned NumParts = TLI.getNumRegisters(Context, VT);
55
56 if (NumParts == 1) {
Igor Bregera8ba5722017-03-23 15:25:57 +000057 // replace the original type ( pointer -> GPR ).
58 SplitArgs.emplace_back(OrigArg.Reg, VT.getTypeForEVT(Context),
59 OrigArg.Flags, OrigArg.IsFixed);
Igor Breger9d5571a2017-07-05 06:24:13 +000060 return true;
Igor Breger5c31a4c2017-02-06 08:37:41 +000061 }
62
Igor Breger5c31a4c2017-02-06 08:37:41 +000063 SmallVector<unsigned, 8> SplitRegs;
64
65 EVT PartVT = TLI.getRegisterType(Context, VT);
66 Type *PartTy = PartVT.getTypeForEVT(Context);
67
68 for (unsigned i = 0; i < NumParts; ++i) {
Daniel Sanders52b4ce72017-03-07 23:20:35 +000069 ArgInfo Info =
70 ArgInfo{MRI.createGenericVirtualRegister(getLLTForType(*PartTy, DL)),
71 PartTy, OrigArg.Flags};
Igor Breger5c31a4c2017-02-06 08:37:41 +000072 SplitArgs.push_back(Info);
Igor Breger87aafa02017-04-24 17:05:52 +000073 SplitRegs.push_back(Info.Reg);
Igor Breger5c31a4c2017-02-06 08:37:41 +000074 }
Igor Breger87aafa02017-04-24 17:05:52 +000075
76 PerformArgSplit(SplitRegs);
Igor Breger9d5571a2017-07-05 06:24:13 +000077 return true;
Igor Breger5c31a4c2017-02-06 08:37:41 +000078}
79
80namespace {
81struct FuncReturnHandler : public CallLowering::ValueHandler {
82 FuncReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
83 MachineInstrBuilder &MIB, CCAssignFn *AssignFn)
84 : ValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB) {}
85
86 unsigned getStackAddress(uint64_t Size, int64_t Offset,
87 MachinePointerInfo &MPO) override {
88 llvm_unreachable("Don't know how to get a stack address yet");
89 }
90
91 void assignValueToReg(unsigned ValVReg, unsigned PhysReg,
92 CCValAssign &VA) override {
93 MIB.addUse(PhysReg, RegState::Implicit);
94 unsigned ExtReg = extendRegister(ValVReg, VA);
95 MIRBuilder.buildCopy(PhysReg, ExtReg);
96 }
97
98 void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size,
99 MachinePointerInfo &MPO, CCValAssign &VA) override {
100 llvm_unreachable("Don't know how to assign a value to an address yet");
101 }
102
103 MachineInstrBuilder &MIB;
104};
105} // End anonymous namespace.
106
Zvi Rackover76dbf262016-11-15 06:34:33 +0000107bool X86CallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
108 const Value *Val, unsigned VReg) const {
Zvi Rackover76dbf262016-11-15 06:34:33 +0000109
Igor Breger5c31a4c2017-02-06 08:37:41 +0000110 assert(((Val && VReg) || (!Val && !VReg)) && "Return value without a vreg");
Igor Breger9ea154d2017-01-29 08:35:42 +0000111
Igor Breger5c31a4c2017-02-06 08:37:41 +0000112 auto MIB = MIRBuilder.buildInstrNoInsert(X86::RET).addImm(0);
Zvi Rackover76dbf262016-11-15 06:34:33 +0000113
Igor Breger5c31a4c2017-02-06 08:37:41 +0000114 if (VReg) {
115 MachineFunction &MF = MIRBuilder.getMF();
116 MachineRegisterInfo &MRI = MF.getRegInfo();
117 auto &DL = MF.getDataLayout();
118 const Function &F = *MF.getFunction();
119
120 ArgInfo OrigArg{VReg, Val->getType()};
Reid Klecknerb5180542017-03-21 16:57:19 +0000121 setArgFlags(OrigArg, AttributeList::ReturnIndex, DL, F);
Igor Breger5c31a4c2017-02-06 08:37:41 +0000122
123 SmallVector<ArgInfo, 8> SplitArgs;
Igor Breger9d5571a2017-07-05 06:24:13 +0000124 if (!splitToValueTypes(OrigArg, SplitArgs, DL, MRI,
125 [&](ArrayRef<unsigned> Regs) {
126 MIRBuilder.buildUnmerge(Regs, VReg);
127 }))
128 return false;
Igor Breger5c31a4c2017-02-06 08:37:41 +0000129
130 FuncReturnHandler Handler(MIRBuilder, MRI, MIB, RetCC_X86);
Igor Breger8a924be2017-03-23 12:13:29 +0000131 if (!handleAssignments(MIRBuilder, SplitArgs, Handler))
Igor Breger5c31a4c2017-02-06 08:37:41 +0000132 return false;
133 }
134
135 MIRBuilder.insertInstr(MIB);
Zvi Rackover76dbf262016-11-15 06:34:33 +0000136 return true;
137}
138
Igor Breger9ea154d2017-01-29 08:35:42 +0000139namespace {
140struct FormalArgHandler : public CallLowering::ValueHandler {
141 FormalArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
142 CCAssignFn *AssignFn, const DataLayout &DL)
143 : ValueHandler(MIRBuilder, MRI, AssignFn), DL(DL) {}
144
145 unsigned getStackAddress(uint64_t Size, int64_t Offset,
146 MachinePointerInfo &MPO) override {
147
148 auto &MFI = MIRBuilder.getMF().getFrameInfo();
149 int FI = MFI.CreateFixedObject(Size, Offset, true);
150 MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI);
151
Igor Breger8a924be2017-03-23 12:13:29 +0000152 unsigned AddrReg = MRI.createGenericVirtualRegister(
153 LLT::pointer(0, DL.getPointerSizeInBits(0)));
Igor Breger9ea154d2017-01-29 08:35:42 +0000154 MIRBuilder.buildFrameIndex(AddrReg, FI);
155 return AddrReg;
156 }
157
158 void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size,
159 MachinePointerInfo &MPO, CCValAssign &VA) override {
160
161 auto MMO = MIRBuilder.getMF().getMachineMemOperand(
162 MPO, MachineMemOperand::MOLoad | MachineMemOperand::MOInvariant, Size,
163 0);
164 MIRBuilder.buildLoad(ValVReg, Addr, *MMO);
165 }
166
167 void assignValueToReg(unsigned ValVReg, unsigned PhysReg,
168 CCValAssign &VA) override {
169 MIRBuilder.getMBB().addLiveIn(PhysReg);
170 MIRBuilder.buildCopy(ValVReg, PhysReg);
171 }
172
173 const DataLayout &DL;
174};
Igor Breger8a924be2017-03-23 12:13:29 +0000175} // namespace
Igor Breger9ea154d2017-01-29 08:35:42 +0000176
Zvi Rackover76dbf262016-11-15 06:34:33 +0000177bool X86CallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
178 const Function &F,
179 ArrayRef<unsigned> VRegs) const {
Igor Breger9ea154d2017-01-29 08:35:42 +0000180 if (F.arg_empty())
181 return true;
182
Igor Breger8a924be2017-03-23 12:13:29 +0000183 // TODO: handle variadic function
Igor Breger9ea154d2017-01-29 08:35:42 +0000184 if (F.isVarArg())
185 return false;
186
Igor Breger5c31a4c2017-02-06 08:37:41 +0000187 MachineFunction &MF = MIRBuilder.getMF();
188 MachineRegisterInfo &MRI = MF.getRegInfo();
189 auto DL = MF.getDataLayout();
Igor Breger9ea154d2017-01-29 08:35:42 +0000190
Igor Breger5c31a4c2017-02-06 08:37:41 +0000191 SmallVector<ArgInfo, 8> SplitArgs;
Igor Breger9ea154d2017-01-29 08:35:42 +0000192 unsigned Idx = 0;
Reid Kleckner45707d42017-03-16 22:59:15 +0000193 for (auto &Arg : F.args()) {
Igor Breger0c979d42017-07-05 11:40:35 +0000194
195 // TODO: handle not simple cases.
196 if (Arg.hasAttribute(Attribute::ByVal) ||
197 Arg.hasAttribute(Attribute::InReg) ||
198 Arg.hasAttribute(Attribute::StructRet) ||
199 Arg.hasAttribute(Attribute::SwiftSelf) ||
200 Arg.hasAttribute(Attribute::SwiftError) ||
201 Arg.hasAttribute(Attribute::Nest))
202 return false;
203
Igor Breger5c31a4c2017-02-06 08:37:41 +0000204 ArgInfo OrigArg(VRegs[Idx], Arg.getType());
Igor Breger0c979d42017-07-05 11:40:35 +0000205 setArgFlags(OrigArg, Idx + AttributeList::FirstArgIndex, DL, F);
Igor Breger9d5571a2017-07-05 06:24:13 +0000206 if (!splitToValueTypes(OrigArg, SplitArgs, DL, MRI,
207 [&](ArrayRef<unsigned> Regs) {
208 MIRBuilder.buildMerge(VRegs[Idx], Regs);
209 }))
210 return false;
Igor Breger9ea154d2017-01-29 08:35:42 +0000211 Idx++;
212 }
213
Igor Breger5c31a4c2017-02-06 08:37:41 +0000214 MachineBasicBlock &MBB = MIRBuilder.getMBB();
215 if (!MBB.empty())
Igor Breger8a924be2017-03-23 12:13:29 +0000216 MIRBuilder.setInstr(*MBB.begin());
Igor Breger5c31a4c2017-02-06 08:37:41 +0000217
218 FormalArgHandler Handler(MIRBuilder, MRI, CC_X86, DL);
219 if (!handleAssignments(MIRBuilder, SplitArgs, Handler))
220 return false;
221
222 // Move back to the end of the basic block.
223 MIRBuilder.setMBB(MBB);
224
225 return true;
Zvi Rackover76dbf262016-11-15 06:34:33 +0000226}