1 //===-- lib/CodeGen/GlobalISel/CallLowering.cpp - Call lowering -----------===//
3 // 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
7 //===----------------------------------------------------------------------===//
10 /// This file implements some simple delegations needed for call lowering.
12 //===----------------------------------------------------------------------===//
14 #include "llvm/CodeGen/GlobalISel/CallLowering.h"
15 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
16 #include "llvm/CodeGen/MachineOperand.h"
17 #include "llvm/CodeGen/MachineRegisterInfo.h"
18 #include "llvm/CodeGen/TargetLowering.h"
19 #include "llvm/IR/DataLayout.h"
20 #include "llvm/IR/Instructions.h"
21 #include "llvm/IR/Module.h"
25 void CallLowering::anchor() {}
27 bool CallLowering::lowerCall(
28 MachineIRBuilder
&MIRBuilder
, ImmutableCallSite CS
, unsigned ResReg
,
29 ArrayRef
<unsigned> ArgRegs
, std::function
<unsigned()> GetCalleeReg
) const {
30 auto &DL
= CS
.getParent()->getParent()->getParent()->getDataLayout();
32 // First step is to marshall all the function's parameters into the correct
33 // physregs and memory locations. Gather the sequence of argument types that
34 // we'll pass to the assigner function.
35 SmallVector
<ArgInfo
, 8> OrigArgs
;
37 unsigned NumFixedArgs
= CS
.getFunctionType()->getNumParams();
38 for (auto &Arg
: CS
.args()) {
39 ArgInfo OrigArg
{ArgRegs
[i
], Arg
->getType(), ISD::ArgFlagsTy
{},
41 setArgFlags(OrigArg
, i
+ AttributeList::FirstArgIndex
, DL
, CS
);
42 // We don't currently support swifterror or swiftself args.
43 if (OrigArg
.Flags
.isSwiftError() || OrigArg
.Flags
.isSwiftSelf())
45 OrigArgs
.push_back(OrigArg
);
49 MachineOperand Callee
= MachineOperand::CreateImm(0);
50 if (const Function
*F
= CS
.getCalledFunction())
51 Callee
= MachineOperand::CreateGA(F
, 0);
53 Callee
= MachineOperand::CreateReg(GetCalleeReg(), false);
55 ArgInfo OrigRet
{ResReg
, CS
.getType(), ISD::ArgFlagsTy
{}};
56 if (!OrigRet
.Ty
->isVoidTy())
57 setArgFlags(OrigRet
, AttributeList::ReturnIndex
, DL
, CS
);
59 return lowerCall(MIRBuilder
, CS
.getCallingConv(), Callee
, OrigRet
, OrigArgs
);
62 template <typename FuncInfoTy
>
63 void CallLowering::setArgFlags(CallLowering::ArgInfo
&Arg
, unsigned OpIdx
,
65 const FuncInfoTy
&FuncInfo
) const {
66 const AttributeList
&Attrs
= FuncInfo
.getAttributes();
67 if (Attrs
.hasAttribute(OpIdx
, Attribute::ZExt
))
69 if (Attrs
.hasAttribute(OpIdx
, Attribute::SExt
))
71 if (Attrs
.hasAttribute(OpIdx
, Attribute::InReg
))
73 if (Attrs
.hasAttribute(OpIdx
, Attribute::StructRet
))
75 if (Attrs
.hasAttribute(OpIdx
, Attribute::SwiftSelf
))
76 Arg
.Flags
.setSwiftSelf();
77 if (Attrs
.hasAttribute(OpIdx
, Attribute::SwiftError
))
78 Arg
.Flags
.setSwiftError();
79 if (Attrs
.hasAttribute(OpIdx
, Attribute::ByVal
))
81 if (Attrs
.hasAttribute(OpIdx
, Attribute::InAlloca
))
82 Arg
.Flags
.setInAlloca();
84 if (Arg
.Flags
.isByVal() || Arg
.Flags
.isInAlloca()) {
85 Type
*ElementTy
= cast
<PointerType
>(Arg
.Ty
)->getElementType();
86 Arg
.Flags
.setByValSize(DL
.getTypeAllocSize(ElementTy
));
87 // For ByVal, alignment should be passed from FE. BE will guess if
88 // this info is not there but there are cases it cannot get right.
90 if (FuncInfo
.getParamAlignment(OpIdx
- 2))
91 FrameAlign
= FuncInfo
.getParamAlignment(OpIdx
- 2);
93 FrameAlign
= getTLI()->getByValTypeAlignment(ElementTy
, DL
);
94 Arg
.Flags
.setByValAlign(FrameAlign
);
96 if (Attrs
.hasAttribute(OpIdx
, Attribute::Nest
))
98 Arg
.Flags
.setOrigAlign(DL
.getABITypeAlignment(Arg
.Ty
));
102 CallLowering::setArgFlags
<Function
>(CallLowering::ArgInfo
&Arg
, unsigned OpIdx
,
103 const DataLayout
&DL
,
104 const Function
&FuncInfo
) const;
107 CallLowering::setArgFlags
<CallInst
>(CallLowering::ArgInfo
&Arg
, unsigned OpIdx
,
108 const DataLayout
&DL
,
109 const CallInst
&FuncInfo
) const;
111 bool CallLowering::handleAssignments(MachineIRBuilder
&MIRBuilder
,
112 ArrayRef
<ArgInfo
> Args
,
113 ValueHandler
&Handler
) const {
114 MachineFunction
&MF
= MIRBuilder
.getMF();
115 const Function
&F
= MF
.getFunction();
116 const DataLayout
&DL
= F
.getParent()->getDataLayout();
118 SmallVector
<CCValAssign
, 16> ArgLocs
;
119 CCState
CCInfo(F
.getCallingConv(), F
.isVarArg(), MF
, ArgLocs
, F
.getContext());
121 unsigned NumArgs
= Args
.size();
122 for (unsigned i
= 0; i
!= NumArgs
; ++i
) {
123 MVT CurVT
= MVT::getVT(Args
[i
].Ty
);
124 if (Handler
.assignArg(i
, CurVT
, CurVT
, CCValAssign::Full
, Args
[i
], CCInfo
))
128 for (unsigned i
= 0, e
= Args
.size(), j
= 0; i
!= e
; ++i
, ++j
) {
129 assert(j
< ArgLocs
.size() && "Skipped too many arg locs");
131 CCValAssign
&VA
= ArgLocs
[j
];
132 assert(VA
.getValNo() == i
&& "Location doesn't correspond to current arg");
134 if (VA
.needsCustom()) {
135 j
+= Handler
.assignCustomValue(Args
[i
], makeArrayRef(ArgLocs
).slice(j
));
140 Handler
.assignValueToReg(Args
[i
].Reg
, VA
.getLocReg(), VA
);
141 else if (VA
.isMemLoc()) {
142 unsigned Size
= VA
.getValVT() == MVT::iPTR
143 ? DL
.getPointerSize()
144 : alignTo(VA
.getValVT().getSizeInBits(), 8) / 8;
145 unsigned Offset
= VA
.getLocMemOffset();
146 MachinePointerInfo MPO
;
147 unsigned StackAddr
= Handler
.getStackAddress(Size
, Offset
, MPO
);
148 Handler
.assignValueToAddress(Args
[i
].Reg
, StackAddr
, Size
, MPO
, VA
);
150 // FIXME: Support byvals and other weirdness
157 unsigned CallLowering::ValueHandler::extendRegister(unsigned ValReg
,
159 LLT LocTy
{VA
.getLocVT()};
160 switch (VA
.getLocInfo()) {
162 case CCValAssign::Full
:
163 case CCValAssign::BCvt
:
164 // FIXME: bitconverting between vector types may or may not be a
165 // nop in big-endian situations.
167 case CCValAssign::AExt
: {
168 auto MIB
= MIRBuilder
.buildAnyExt(LocTy
, ValReg
);
169 return MIB
->getOperand(0).getReg();
171 case CCValAssign::SExt
: {
172 unsigned NewReg
= MRI
.createGenericVirtualRegister(LocTy
);
173 MIRBuilder
.buildSExt(NewReg
, ValReg
);
176 case CCValAssign::ZExt
: {
177 unsigned NewReg
= MRI
.createGenericVirtualRegister(LocTy
);
178 MIRBuilder
.buildZExt(NewReg
, ValReg
);
182 llvm_unreachable("unable to extend register");
185 void CallLowering::ValueHandler::anchor() {}