blob: 4da5d0d61d801d09c6f6371332275f70ac18eb1e [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"
17#include "X86ISelLowering.h"
18#include "X86InstrInfo.h"
Igor Breger9ea154d2017-01-29 08:35:42 +000019#include "X86TargetMachine.h"
20#include "X86CallingConv.h"
21
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/MachineValueType.h"
24#include "llvm/CodeGen/MachineRegisterInfo.h"
25#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) {
50 SplitArgs.push_back(OrigArg);
51 return;
52 }
53
54 SmallVector<uint64_t, 4> BitOffsets;
55 SmallVector<unsigned, 8> SplitRegs;
56
57 EVT PartVT = TLI.getRegisterType(Context, VT);
58 Type *PartTy = PartVT.getTypeForEVT(Context);
59
60 for (unsigned i = 0; i < NumParts; ++i) {
Daniel Sanders52b4ce72017-03-07 23:20:35 +000061 ArgInfo Info =
62 ArgInfo{MRI.createGenericVirtualRegister(getLLTForType(*PartTy, DL)),
63 PartTy, OrigArg.Flags};
Igor Breger5c31a4c2017-02-06 08:37:41 +000064 SplitArgs.push_back(Info);
Tim Northoverc2c545b2017-03-06 23:50:28 +000065 PerformArgSplit(Info.Reg, PartVT.getSizeInBits() * i);
Igor Breger5c31a4c2017-02-06 08:37:41 +000066 }
Igor Breger5c31a4c2017-02-06 08:37:41 +000067}
68
69namespace {
70struct FuncReturnHandler : public CallLowering::ValueHandler {
71 FuncReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
72 MachineInstrBuilder &MIB, CCAssignFn *AssignFn)
73 : ValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB) {}
74
75 unsigned getStackAddress(uint64_t Size, int64_t Offset,
76 MachinePointerInfo &MPO) override {
77 llvm_unreachable("Don't know how to get a stack address yet");
78 }
79
80 void assignValueToReg(unsigned ValVReg, unsigned PhysReg,
81 CCValAssign &VA) override {
82 MIB.addUse(PhysReg, RegState::Implicit);
83 unsigned ExtReg = extendRegister(ValVReg, VA);
84 MIRBuilder.buildCopy(PhysReg, ExtReg);
85 }
86
87 void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size,
88 MachinePointerInfo &MPO, CCValAssign &VA) override {
89 llvm_unreachable("Don't know how to assign a value to an address yet");
90 }
91
92 MachineInstrBuilder &MIB;
93};
94} // End anonymous namespace.
95
Zvi Rackover76dbf262016-11-15 06:34:33 +000096bool X86CallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
97 const Value *Val, unsigned VReg) const {
Zvi Rackover76dbf262016-11-15 06:34:33 +000098
Igor Breger5c31a4c2017-02-06 08:37:41 +000099 assert(((Val && VReg) || (!Val && !VReg)) && "Return value without a vreg");
Igor Breger9ea154d2017-01-29 08:35:42 +0000100
Igor Breger5c31a4c2017-02-06 08:37:41 +0000101 auto MIB = MIRBuilder.buildInstrNoInsert(X86::RET).addImm(0);
Zvi Rackover76dbf262016-11-15 06:34:33 +0000102
Igor Breger5c31a4c2017-02-06 08:37:41 +0000103 if (VReg) {
104 MachineFunction &MF = MIRBuilder.getMF();
105 MachineRegisterInfo &MRI = MF.getRegInfo();
106 auto &DL = MF.getDataLayout();
107 const Function &F = *MF.getFunction();
108
109 ArgInfo OrigArg{VReg, Val->getType()};
110 setArgFlags(OrigArg, AttributeSet::ReturnIndex, DL, F);
111
112 SmallVector<ArgInfo, 8> SplitArgs;
113 splitToValueTypes(OrigArg, SplitArgs, DL, MRI,
Tim Northoverc2c545b2017-03-06 23:50:28 +0000114 [&](unsigned Reg, uint64_t Offset) {
115 MIRBuilder.buildExtract(Reg, VReg, Offset);
Igor Breger5c31a4c2017-02-06 08:37:41 +0000116 });
117
118 FuncReturnHandler Handler(MIRBuilder, MRI, MIB, RetCC_X86);
119 if(!handleAssignments(MIRBuilder, SplitArgs, Handler))
120 return false;
121 }
122
123 MIRBuilder.insertInstr(MIB);
Zvi Rackover76dbf262016-11-15 06:34:33 +0000124 return true;
125}
126
Igor Breger9ea154d2017-01-29 08:35:42 +0000127namespace {
128struct FormalArgHandler : public CallLowering::ValueHandler {
129 FormalArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
130 CCAssignFn *AssignFn, const DataLayout &DL)
131 : ValueHandler(MIRBuilder, MRI, AssignFn), DL(DL) {}
132
133 unsigned getStackAddress(uint64_t Size, int64_t Offset,
134 MachinePointerInfo &MPO) override {
135
136 auto &MFI = MIRBuilder.getMF().getFrameInfo();
137 int FI = MFI.CreateFixedObject(Size, Offset, true);
138 MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI);
139
140 unsigned AddrReg =
141 MRI.createGenericVirtualRegister(LLT::pointer(0,
142 DL.getPointerSizeInBits(0)));
143 MIRBuilder.buildFrameIndex(AddrReg, FI);
144 return AddrReg;
145 }
146
147 void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size,
148 MachinePointerInfo &MPO, CCValAssign &VA) override {
149
150 auto MMO = MIRBuilder.getMF().getMachineMemOperand(
151 MPO, MachineMemOperand::MOLoad | MachineMemOperand::MOInvariant, Size,
152 0);
153 MIRBuilder.buildLoad(ValVReg, Addr, *MMO);
154 }
155
156 void assignValueToReg(unsigned ValVReg, unsigned PhysReg,
157 CCValAssign &VA) override {
158 MIRBuilder.getMBB().addLiveIn(PhysReg);
159 MIRBuilder.buildCopy(ValVReg, PhysReg);
160 }
161
162 const DataLayout &DL;
163};
164}
165
Zvi Rackover76dbf262016-11-15 06:34:33 +0000166bool X86CallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
167 const Function &F,
168 ArrayRef<unsigned> VRegs) const {
Igor Breger9ea154d2017-01-29 08:35:42 +0000169 if (F.arg_empty())
170 return true;
171
172 //TODO: handle variadic function
173 if (F.isVarArg())
174 return false;
175
Igor Breger5c31a4c2017-02-06 08:37:41 +0000176 MachineFunction &MF = MIRBuilder.getMF();
177 MachineRegisterInfo &MRI = MF.getRegInfo();
178 auto DL = MF.getDataLayout();
Igor Breger9ea154d2017-01-29 08:35:42 +0000179
Igor Breger5c31a4c2017-02-06 08:37:41 +0000180 SmallVector<ArgInfo, 8> SplitArgs;
Igor Breger9ea154d2017-01-29 08:35:42 +0000181 unsigned Idx = 0;
182 for (auto &Arg : F.getArgumentList()) {
Igor Breger5c31a4c2017-02-06 08:37:41 +0000183 ArgInfo OrigArg(VRegs[Idx], Arg.getType());
184 setArgFlags(OrigArg, Idx + 1, DL, F);
Tim Northoverc2c545b2017-03-06 23:50:28 +0000185 LLT Ty = MRI.getType(VRegs[Idx]);
186 unsigned Dst = VRegs[Idx];
187 bool Split = false;
Igor Breger5c31a4c2017-02-06 08:37:41 +0000188 splitToValueTypes(OrigArg, SplitArgs, DL, MRI,
Tim Northoverc2c545b2017-03-06 23:50:28 +0000189 [&](unsigned Reg, uint64_t Offset) {
190 if (!Split) {
191 Split = true;
192 Dst = MRI.createGenericVirtualRegister(Ty);
193 MIRBuilder.buildUndef(Dst);
194 }
195 unsigned Tmp = MRI.createGenericVirtualRegister(Ty);
196 MIRBuilder.buildInsert(Tmp, Dst, Reg, Offset);
197 Dst = Tmp;
Igor Breger5c31a4c2017-02-06 08:37:41 +0000198 });
Tim Northoverc2c545b2017-03-06 23:50:28 +0000199 if (Dst != VRegs[Idx])
200 MIRBuilder.buildCopy(VRegs[Idx], Dst);
Igor Breger9ea154d2017-01-29 08:35:42 +0000201 Idx++;
202 }
203
Igor Breger5c31a4c2017-02-06 08:37:41 +0000204 MachineBasicBlock &MBB = MIRBuilder.getMBB();
205 if (!MBB.empty())
206 MIRBuilder.setInstr(*MBB.begin());
207
208 FormalArgHandler Handler(MIRBuilder, MRI, CC_X86, DL);
209 if (!handleAssignments(MIRBuilder, SplitArgs, Handler))
210 return false;
211
212 // Move back to the end of the basic block.
213 MIRBuilder.setMBB(MBB);
214
215 return true;
Zvi Rackover76dbf262016-11-15 06:34:33 +0000216}