blob: 5e08361fc05bdaaca6e0a5ac4508626a46b41e5c [file] [log] [blame]
Tim Northoverfe5f89b2016-08-29 19:07:08 +00001//===-- lib/CodeGen/GlobalISel/CallLowering.cpp - Call lowering -----------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Tim Northoverfe5f89b2016-08-29 19:07:08 +00006//
7//===----------------------------------------------------------------------===//
8///
9/// \file
10/// This file implements some simple delegations needed for call lowering.
11///
12//===----------------------------------------------------------------------===//
13
Tim Northoverfe5f89b2016-08-29 19:07:08 +000014#include "llvm/CodeGen/GlobalISel/CallLowering.h"
Diana Picusc3dbe232019-06-27 08:54:17 +000015#include "llvm/CodeGen/Analysis.h"
Diana Picusf11f0422016-12-05 10:40:33 +000016#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
Tim Northoverfe5f89b2016-08-29 19:07:08 +000017#include "llvm/CodeGen/MachineOperand.h"
Diana Picus2d9adbf2016-12-13 10:46:12 +000018#include "llvm/CodeGen/MachineRegisterInfo.h"
David Blaikieb3bde2e2017-11-17 01:07:10 +000019#include "llvm/CodeGen/TargetLowering.h"
Tim Northover9a467182016-09-21 12:57:45 +000020#include "llvm/IR/DataLayout.h"
Diana Picusf11f0422016-12-05 10:40:33 +000021#include "llvm/IR/Instructions.h"
Mark Lacey7b8d3eb2019-07-31 20:34:02 +000022#include "llvm/IR/LLVMContext.h"
Tim Northover9a467182016-09-21 12:57:45 +000023#include "llvm/IR/Module.h"
Tim Northoverfe5f89b2016-08-29 19:07:08 +000024
Amara Emerson2b523f82019-04-09 21:22:33 +000025#define DEBUG_TYPE "call-lowering"
26
Tim Northoverfe5f89b2016-08-29 19:07:08 +000027using namespace llvm;
28
Richard Trieua87b70d2018-12-29 02:02:13 +000029void CallLowering::anchor() {}
30
Tim Northover3b2157a2019-05-24 08:40:13 +000031bool CallLowering::lowerCall(MachineIRBuilder &MIRBuilder, ImmutableCallSite CS,
Diana Picus81389962019-06-27 09:15:53 +000032 ArrayRef<Register> ResRegs,
Diana Picus43fb5ae2019-06-27 09:18:03 +000033 ArrayRef<ArrayRef<Register>> ArgRegs,
Matt Arsenaulte3a676e2019-06-24 15:50:29 +000034 Register SwiftErrorVReg,
Tim Northover3b2157a2019-05-24 08:40:13 +000035 std::function<unsigned()> GetCalleeReg) const {
Tim Northovere1a5f662019-08-09 08:26:38 +000036 CallLoweringInfo Info;
Ahmed Bougachad22b84b2017-03-10 00:25:44 +000037 auto &DL = CS.getParent()->getParent()->getParent()->getDataLayout();
Tim Northover9a467182016-09-21 12:57:45 +000038
Tim Northoverfe5f89b2016-08-29 19:07:08 +000039 // First step is to marshall all the function's parameters into the correct
40 // physregs and memory locations. Gather the sequence of argument types that
41 // we'll pass to the assigner function.
Tim Northover9a467182016-09-21 12:57:45 +000042 unsigned i = 0;
Ahmed Bougachad22b84b2017-03-10 00:25:44 +000043 unsigned NumFixedArgs = CS.getFunctionType()->getNumParams();
44 for (auto &Arg : CS.args()) {
Tim Northoverd9433542017-01-17 22:30:10 +000045 ArgInfo OrigArg{ArgRegs[i], Arg->getType(), ISD::ArgFlagsTy{},
46 i < NumFixedArgs};
Reid Klecknera0b45f42017-05-03 18:17:31 +000047 setArgFlags(OrigArg, i + AttributeList::FirstArgIndex, DL, CS);
Tim Northovere1a5f662019-08-09 08:26:38 +000048 Info.OrigArgs.push_back(OrigArg);
Tim Northover9a467182016-09-21 12:57:45 +000049 ++i;
50 }
Tim Northoverfe5f89b2016-08-29 19:07:08 +000051
Ahmed Bougachad22b84b2017-03-10 00:25:44 +000052 if (const Function *F = CS.getCalledFunction())
Tim Northovere1a5f662019-08-09 08:26:38 +000053 Info.Callee = MachineOperand::CreateGA(F, 0);
Tim Northoverfe5f89b2016-08-29 19:07:08 +000054 else
Tim Northovere1a5f662019-08-09 08:26:38 +000055 Info.Callee = MachineOperand::CreateReg(GetCalleeReg(), false);
Tim Northoverfe5f89b2016-08-29 19:07:08 +000056
Tim Northovere1a5f662019-08-09 08:26:38 +000057 Info.OrigRet = ArgInfo{ResRegs, CS.getType(), ISD::ArgFlagsTy{}};
58 if (!Info.OrigRet.Ty->isVoidTy())
59 setArgFlags(Info.OrigRet, AttributeList::ReturnIndex, DL, CS);
Tim Northover9a467182016-09-21 12:57:45 +000060
Tim Northovere1a5f662019-08-09 08:26:38 +000061 Info.KnownCallees =
Mark Lacey7b8d3eb2019-07-31 20:34:02 +000062 CS.getInstruction()->getMetadata(LLVMContext::MD_callees);
Tim Northovere1a5f662019-08-09 08:26:38 +000063 Info.CallConv = CS.getCallingConv();
64 Info.SwiftErrorVReg = SwiftErrorVReg;
Jessica Paquetteaf0bd412019-08-28 16:19:01 +000065 Info.IsMustTailCall = CS.isMustTailCall();
Mark Lacey7b8d3eb2019-07-31 20:34:02 +000066
Tim Northovere1a5f662019-08-09 08:26:38 +000067 return lowerCall(MIRBuilder, Info);
Tim Northoverfe5f89b2016-08-29 19:07:08 +000068}
Tim Northover9a467182016-09-21 12:57:45 +000069
70template <typename FuncInfoTy>
71void CallLowering::setArgFlags(CallLowering::ArgInfo &Arg, unsigned OpIdx,
72 const DataLayout &DL,
73 const FuncInfoTy &FuncInfo) const {
Reid Klecknerb5180542017-03-21 16:57:19 +000074 const AttributeList &Attrs = FuncInfo.getAttributes();
Tim Northover9a467182016-09-21 12:57:45 +000075 if (Attrs.hasAttribute(OpIdx, Attribute::ZExt))
76 Arg.Flags.setZExt();
77 if (Attrs.hasAttribute(OpIdx, Attribute::SExt))
78 Arg.Flags.setSExt();
79 if (Attrs.hasAttribute(OpIdx, Attribute::InReg))
80 Arg.Flags.setInReg();
81 if (Attrs.hasAttribute(OpIdx, Attribute::StructRet))
82 Arg.Flags.setSRet();
83 if (Attrs.hasAttribute(OpIdx, Attribute::SwiftSelf))
84 Arg.Flags.setSwiftSelf();
85 if (Attrs.hasAttribute(OpIdx, Attribute::SwiftError))
86 Arg.Flags.setSwiftError();
87 if (Attrs.hasAttribute(OpIdx, Attribute::ByVal))
88 Arg.Flags.setByVal();
89 if (Attrs.hasAttribute(OpIdx, Attribute::InAlloca))
90 Arg.Flags.setInAlloca();
91
92 if (Arg.Flags.isByVal() || Arg.Flags.isInAlloca()) {
93 Type *ElementTy = cast<PointerType>(Arg.Ty)->getElementType();
Tim Northoverb7141202019-05-30 18:48:23 +000094
95 auto Ty = Attrs.getAttribute(OpIdx, Attribute::ByVal).getValueAsType();
96 Arg.Flags.setByValSize(DL.getTypeAllocSize(Ty ? Ty : ElementTy));
97
Tim Northover9a467182016-09-21 12:57:45 +000098 // For ByVal, alignment should be passed from FE. BE will guess if
99 // this info is not there but there are cases it cannot get right.
100 unsigned FrameAlign;
Reid Kleckneree4930b2017-05-02 22:07:37 +0000101 if (FuncInfo.getParamAlignment(OpIdx - 2))
102 FrameAlign = FuncInfo.getParamAlignment(OpIdx - 2);
Tim Northover9a467182016-09-21 12:57:45 +0000103 else
104 FrameAlign = getTLI()->getByValTypeAlignment(ElementTy, DL);
105 Arg.Flags.setByValAlign(FrameAlign);
106 }
107 if (Attrs.hasAttribute(OpIdx, Attribute::Nest))
108 Arg.Flags.setNest();
109 Arg.Flags.setOrigAlign(DL.getABITypeAlignment(Arg.Ty));
110}
111
112template void
113CallLowering::setArgFlags<Function>(CallLowering::ArgInfo &Arg, unsigned OpIdx,
114 const DataLayout &DL,
115 const Function &FuncInfo) const;
116
117template void
118CallLowering::setArgFlags<CallInst>(CallLowering::ArgInfo &Arg, unsigned OpIdx,
119 const DataLayout &DL,
120 const CallInst &FuncInfo) const;
Diana Picusf11f0422016-12-05 10:40:33 +0000121
Diana Picusc3dbe232019-06-27 08:54:17 +0000122Register CallLowering::packRegs(ArrayRef<Register> SrcRegs, Type *PackedTy,
123 MachineIRBuilder &MIRBuilder) const {
124 assert(SrcRegs.size() > 1 && "Nothing to pack");
125
126 const DataLayout &DL = MIRBuilder.getMF().getDataLayout();
127 MachineRegisterInfo *MRI = MIRBuilder.getMRI();
128
129 LLT PackedLLT = getLLTForType(*PackedTy, DL);
130
131 SmallVector<LLT, 8> LLTs;
132 SmallVector<uint64_t, 8> Offsets;
133 computeValueLLTs(DL, *PackedTy, LLTs, &Offsets);
134 assert(LLTs.size() == SrcRegs.size() && "Regs / types mismatch");
135
136 Register Dst = MRI->createGenericVirtualRegister(PackedLLT);
137 MIRBuilder.buildUndef(Dst);
138 for (unsigned i = 0; i < SrcRegs.size(); ++i) {
139 Register NewDst = MRI->createGenericVirtualRegister(PackedLLT);
140 MIRBuilder.buildInsert(NewDst, Dst, SrcRegs[i], Offsets[i]);
141 Dst = NewDst;
142 }
143
144 return Dst;
145}
146
147void CallLowering::unpackRegs(ArrayRef<Register> DstRegs, Register SrcReg,
148 Type *PackedTy,
149 MachineIRBuilder &MIRBuilder) const {
150 assert(DstRegs.size() > 1 && "Nothing to unpack");
151
152 const DataLayout &DL = MIRBuilder.getMF().getDataLayout();
153
154 SmallVector<LLT, 8> LLTs;
155 SmallVector<uint64_t, 8> Offsets;
156 computeValueLLTs(DL, *PackedTy, LLTs, &Offsets);
157 assert(LLTs.size() == DstRegs.size() && "Regs / types mismatch");
158
159 for (unsigned i = 0; i < DstRegs.size(); ++i)
160 MIRBuilder.buildExtract(DstRegs[i], SrcReg, Offsets[i]);
161}
162
Diana Picusf11f0422016-12-05 10:40:33 +0000163bool CallLowering::handleAssignments(MachineIRBuilder &MIRBuilder,
Diana Picusf11f0422016-12-05 10:40:33 +0000164 ArrayRef<ArgInfo> Args,
165 ValueHandler &Handler) const {
166 MachineFunction &MF = MIRBuilder.getMF();
Matthias Braunf1caa282017-12-15 22:22:58 +0000167 const Function &F = MF.getFunction();
Diana Picusf11f0422016-12-05 10:40:33 +0000168 SmallVector<CCValAssign, 16> ArgLocs;
169 CCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs, F.getContext());
Matt Arsenault1c3f4ec2019-07-16 22:41:34 +0000170 return handleAssignments(CCInfo, ArgLocs, MIRBuilder, Args, Handler);
171}
172
173bool CallLowering::handleAssignments(CCState &CCInfo,
174 SmallVectorImpl<CCValAssign> &ArgLocs,
175 MachineIRBuilder &MIRBuilder,
176 ArrayRef<ArgInfo> Args,
177 ValueHandler &Handler) const {
178 MachineFunction &MF = MIRBuilder.getMF();
179 const Function &F = MF.getFunction();
180 const DataLayout &DL = F.getParent()->getDataLayout();
Diana Picusf11f0422016-12-05 10:40:33 +0000181
182 unsigned NumArgs = Args.size();
183 for (unsigned i = 0; i != NumArgs; ++i) {
184 MVT CurVT = MVT::getVT(Args[i].Ty);
Amara Emerson2b523f82019-04-09 21:22:33 +0000185 if (Handler.assignArg(i, CurVT, CurVT, CCValAssign::Full, Args[i], CCInfo)) {
186 // Try to use the register type if we couldn't assign the VT.
Amara Emersonbc1172d2019-08-05 23:05:28 +0000187 if (!Handler.isIncomingArgumentHandler() || !CurVT.isValid())
Matt Arsenaulte3a676e2019-06-24 15:50:29 +0000188 return false;
Amara Emerson2b523f82019-04-09 21:22:33 +0000189 CurVT = TLI->getRegisterTypeForCallingConv(
190 F.getContext(), F.getCallingConv(), EVT(CurVT));
191 if (Handler.assignArg(i, CurVT, CurVT, CCValAssign::Full, Args[i], CCInfo))
192 return false;
193 }
Diana Picusf11f0422016-12-05 10:40:33 +0000194 }
195
Diana Picusca6a8902017-02-16 07:53:07 +0000196 for (unsigned i = 0, e = Args.size(), j = 0; i != e; ++i, ++j) {
197 assert(j < ArgLocs.size() && "Skipped too many arg locs");
198
199 CCValAssign &VA = ArgLocs[j];
200 assert(VA.getValNo() == i && "Location doesn't correspond to current arg");
201
202 if (VA.needsCustom()) {
203 j += Handler.assignCustomValue(Args[i], makeArrayRef(ArgLocs).slice(j));
204 continue;
205 }
Diana Picusf11f0422016-12-05 10:40:33 +0000206
Diana Picus69ce1c132019-06-27 08:50:53 +0000207 assert(Args[i].Regs.size() == 1 &&
208 "Can't handle multiple virtual regs yet");
209
210 // FIXME: Pack registers if we have more than one.
Matt Arsenault7e719022019-07-11 14:18:19 +0000211 Register ArgReg = Args[i].Regs[0];
Diana Picus69ce1c132019-06-27 08:50:53 +0000212
Amara Emerson2b523f82019-04-09 21:22:33 +0000213 if (VA.isRegLoc()) {
214 MVT OrigVT = MVT::getVT(Args[i].Ty);
215 MVT VAVT = VA.getValVT();
Amara Emersonbc1172d2019-08-05 23:05:28 +0000216 if (Handler.isIncomingArgumentHandler() && VAVT != OrigVT) {
Amara Emerson2b523f82019-04-09 21:22:33 +0000217 if (VAVT.getSizeInBits() < OrigVT.getSizeInBits())
218 return false; // Can't handle this type of arg yet.
219 const LLT VATy(VAVT);
Matt Arsenault7e719022019-07-11 14:18:19 +0000220 Register NewReg =
Amara Emerson2b523f82019-04-09 21:22:33 +0000221 MIRBuilder.getMRI()->createGenericVirtualRegister(VATy);
222 Handler.assignValueToReg(NewReg, VA.getLocReg(), VA);
223 // If it's a vector type, we either need to truncate the elements
224 // or do an unmerge to get the lower block of elements.
225 if (VATy.isVector() &&
226 VATy.getNumElements() > OrigVT.getVectorNumElements()) {
227 const LLT OrigTy(OrigVT);
228 // Just handle the case where the VA type is 2 * original type.
229 if (VATy.getNumElements() != OrigVT.getVectorNumElements() * 2) {
230 LLVM_DEBUG(dbgs()
231 << "Incoming promoted vector arg has too many elts");
232 return false;
233 }
234 auto Unmerge = MIRBuilder.buildUnmerge({OrigTy, OrigTy}, {NewReg});
Diana Picus69ce1c132019-06-27 08:50:53 +0000235 MIRBuilder.buildCopy(ArgReg, Unmerge.getReg(0));
Amara Emerson2b523f82019-04-09 21:22:33 +0000236 } else {
Diana Picus69ce1c132019-06-27 08:50:53 +0000237 MIRBuilder.buildTrunc(ArgReg, {NewReg}).getReg(0);
Amara Emerson2b523f82019-04-09 21:22:33 +0000238 }
239 } else {
Diana Picus69ce1c132019-06-27 08:50:53 +0000240 Handler.assignValueToReg(ArgReg, VA.getLocReg(), VA);
Amara Emerson2b523f82019-04-09 21:22:33 +0000241 }
242 } else if (VA.isMemLoc()) {
243 MVT VT = MVT::getVT(Args[i].Ty);
244 unsigned Size = VT == MVT::iPTR ? DL.getPointerSize()
245 : alignTo(VT.getSizeInBits(), 8) / 8;
Diana Picusf11f0422016-12-05 10:40:33 +0000246 unsigned Offset = VA.getLocMemOffset();
247 MachinePointerInfo MPO;
Matt Arsenault7e719022019-07-11 14:18:19 +0000248 Register StackAddr = Handler.getStackAddress(Size, Offset, MPO);
Diana Picus69ce1c132019-06-27 08:50:53 +0000249 Handler.assignValueToAddress(ArgReg, StackAddr, Size, MPO, VA);
Diana Picusf11f0422016-12-05 10:40:33 +0000250 } else {
251 // FIXME: Support byvals and other weirdness
252 return false;
253 }
254 }
255 return true;
256}
Diana Picus2d9adbf2016-12-13 10:46:12 +0000257
Matt Arsenaultfaeaedf2019-06-24 16:16:12 +0000258Register CallLowering::ValueHandler::extendRegister(Register ValReg,
Diana Picus2d9adbf2016-12-13 10:46:12 +0000259 CCValAssign &VA) {
260 LLT LocTy{VA.getLocVT()};
Amara Emerson2b523f82019-04-09 21:22:33 +0000261 if (LocTy.getSizeInBits() == MRI.getType(ValReg).getSizeInBits())
262 return ValReg;
Diana Picus2d9adbf2016-12-13 10:46:12 +0000263 switch (VA.getLocInfo()) {
264 default: break;
265 case CCValAssign::Full:
266 case CCValAssign::BCvt:
267 // FIXME: bitconverting between vector types may or may not be a
268 // nop in big-endian situations.
269 return ValReg;
Aditya Nandakumarc3bfc812017-10-09 20:07:43 +0000270 case CCValAssign::AExt: {
Aditya Nandakumarc3bfc812017-10-09 20:07:43 +0000271 auto MIB = MIRBuilder.buildAnyExt(LocTy, ValReg);
272 return MIB->getOperand(0).getReg();
273 }
Diana Picus2d9adbf2016-12-13 10:46:12 +0000274 case CCValAssign::SExt: {
Matt Arsenault7e719022019-07-11 14:18:19 +0000275 Register NewReg = MRI.createGenericVirtualRegister(LocTy);
Diana Picus2d9adbf2016-12-13 10:46:12 +0000276 MIRBuilder.buildSExt(NewReg, ValReg);
277 return NewReg;
278 }
279 case CCValAssign::ZExt: {
Matt Arsenault7e719022019-07-11 14:18:19 +0000280 Register NewReg = MRI.createGenericVirtualRegister(LocTy);
Diana Picus2d9adbf2016-12-13 10:46:12 +0000281 MIRBuilder.buildZExt(NewReg, ValReg);
282 return NewReg;
283 }
284 }
285 llvm_unreachable("unable to extend register");
286}
Richard Trieua87b70d2018-12-29 02:02:13 +0000287
288void CallLowering::ValueHandler::anchor() {}