LLVM  9.0.0svn
CallLowering.cpp
Go to the documentation of this file.
1 //===-- lib/CodeGen/GlobalISel/CallLowering.cpp - Call lowering -----------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// This file implements some simple delegations needed for call lowering.
11 ///
12 //===----------------------------------------------------------------------===//
13 
15 #include "llvm/CodeGen/Analysis.h"
20 #include "llvm/IR/DataLayout.h"
21 #include "llvm/IR/Instructions.h"
22 #include "llvm/IR/Module.h"
23 
24 #define DEBUG_TYPE "call-lowering"
25 
26 using namespace llvm;
27 
28 void CallLowering::anchor() {}
29 
31  ArrayRef<Register> ResRegs,
33  Register SwiftErrorVReg,
34  std::function<unsigned()> GetCalleeReg) const {
35  auto &DL = CS.getParent()->getParent()->getParent()->getDataLayout();
36 
37  // First step is to marshall all the function's parameters into the correct
38  // physregs and memory locations. Gather the sequence of argument types that
39  // we'll pass to the assigner function.
40  SmallVector<ArgInfo, 8> OrigArgs;
41  unsigned i = 0;
42  unsigned NumFixedArgs = CS.getFunctionType()->getNumParams();
43  for (auto &Arg : CS.args()) {
44  ArgInfo OrigArg{ArgRegs[i], Arg->getType(), ISD::ArgFlagsTy{},
45  i < NumFixedArgs};
46  setArgFlags(OrigArg, i + AttributeList::FirstArgIndex, DL, CS);
47  // We don't currently support swiftself args.
48  if (OrigArg.Flags.isSwiftSelf())
49  return false;
50  OrigArgs.push_back(OrigArg);
51  ++i;
52  }
53 
55  if (const Function *F = CS.getCalledFunction())
56  Callee = MachineOperand::CreateGA(F, 0);
57  else
58  Callee = MachineOperand::CreateReg(GetCalleeReg(), false);
59 
60  ArgInfo OrigRet{ResRegs, CS.getType(), ISD::ArgFlagsTy{}};
61  if (!OrigRet.Ty->isVoidTy())
62  setArgFlags(OrigRet, AttributeList::ReturnIndex, DL, CS);
63 
64  return lowerCall(MIRBuilder, CS.getCallingConv(), Callee, OrigRet, OrigArgs,
65  SwiftErrorVReg);
66 }
67 
68 template <typename FuncInfoTy>
70  const DataLayout &DL,
71  const FuncInfoTy &FuncInfo) const {
72  const AttributeList &Attrs = FuncInfo.getAttributes();
73  if (Attrs.hasAttribute(OpIdx, Attribute::ZExt))
74  Arg.Flags.setZExt();
75  if (Attrs.hasAttribute(OpIdx, Attribute::SExt))
76  Arg.Flags.setSExt();
77  if (Attrs.hasAttribute(OpIdx, Attribute::InReg))
78  Arg.Flags.setInReg();
79  if (Attrs.hasAttribute(OpIdx, Attribute::StructRet))
80  Arg.Flags.setSRet();
81  if (Attrs.hasAttribute(OpIdx, Attribute::SwiftSelf))
82  Arg.Flags.setSwiftSelf();
83  if (Attrs.hasAttribute(OpIdx, Attribute::SwiftError))
84  Arg.Flags.setSwiftError();
85  if (Attrs.hasAttribute(OpIdx, Attribute::ByVal))
86  Arg.Flags.setByVal();
87  if (Attrs.hasAttribute(OpIdx, Attribute::InAlloca))
88  Arg.Flags.setInAlloca();
89 
90  if (Arg.Flags.isByVal() || Arg.Flags.isInAlloca()) {
91  Type *ElementTy = cast<PointerType>(Arg.Ty)->getElementType();
92 
93  auto Ty = Attrs.getAttribute(OpIdx, Attribute::ByVal).getValueAsType();
94  Arg.Flags.setByValSize(DL.getTypeAllocSize(Ty ? Ty : ElementTy));
95 
96  // For ByVal, alignment should be passed from FE. BE will guess if
97  // this info is not there but there are cases it cannot get right.
98  unsigned FrameAlign;
99  if (FuncInfo.getParamAlignment(OpIdx - 2))
100  FrameAlign = FuncInfo.getParamAlignment(OpIdx - 2);
101  else
102  FrameAlign = getTLI()->getByValTypeAlignment(ElementTy, DL);
103  Arg.Flags.setByValAlign(FrameAlign);
104  }
105  if (Attrs.hasAttribute(OpIdx, Attribute::Nest))
106  Arg.Flags.setNest();
108 }
109 
110 template void
111 CallLowering::setArgFlags<Function>(CallLowering::ArgInfo &Arg, unsigned OpIdx,
112  const DataLayout &DL,
113  const Function &FuncInfo) const;
114 
115 template void
116 CallLowering::setArgFlags<CallInst>(CallLowering::ArgInfo &Arg, unsigned OpIdx,
117  const DataLayout &DL,
118  const CallInst &FuncInfo) const;
119 
121  MachineIRBuilder &MIRBuilder) const {
122  assert(SrcRegs.size() > 1 && "Nothing to pack");
123 
124  const DataLayout &DL = MIRBuilder.getMF().getDataLayout();
125  MachineRegisterInfo *MRI = MIRBuilder.getMRI();
126 
127  LLT PackedLLT = getLLTForType(*PackedTy, DL);
128 
129  SmallVector<LLT, 8> LLTs;
131  computeValueLLTs(DL, *PackedTy, LLTs, &Offsets);
132  assert(LLTs.size() == SrcRegs.size() && "Regs / types mismatch");
133 
134  Register Dst = MRI->createGenericVirtualRegister(PackedLLT);
135  MIRBuilder.buildUndef(Dst);
136  for (unsigned i = 0; i < SrcRegs.size(); ++i) {
137  Register NewDst = MRI->createGenericVirtualRegister(PackedLLT);
138  MIRBuilder.buildInsert(NewDst, Dst, SrcRegs[i], Offsets[i]);
139  Dst = NewDst;
140  }
141 
142  return Dst;
143 }
144 
146  Type *PackedTy,
147  MachineIRBuilder &MIRBuilder) const {
148  assert(DstRegs.size() > 1 && "Nothing to unpack");
149 
150  const DataLayout &DL = MIRBuilder.getMF().getDataLayout();
151 
152  SmallVector<LLT, 8> LLTs;
154  computeValueLLTs(DL, *PackedTy, LLTs, &Offsets);
155  assert(LLTs.size() == DstRegs.size() && "Regs / types mismatch");
156 
157  for (unsigned i = 0; i < DstRegs.size(); ++i)
158  MIRBuilder.buildExtract(DstRegs[i], SrcReg, Offsets[i]);
159 }
160 
163  ValueHandler &Handler) const {
164  MachineFunction &MF = MIRBuilder.getMF();
165  const Function &F = MF.getFunction();
167  CCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs, F.getContext());
168  return handleAssignments(CCInfo, ArgLocs, MIRBuilder, Args, Handler);
169 }
170 
173  MachineIRBuilder &MIRBuilder,
175  ValueHandler &Handler) const {
176  MachineFunction &MF = MIRBuilder.getMF();
177  const Function &F = MF.getFunction();
178  const DataLayout &DL = F.getParent()->getDataLayout();
179 
180  unsigned NumArgs = Args.size();
181  for (unsigned i = 0; i != NumArgs; ++i) {
182  MVT CurVT = MVT::getVT(Args[i].Ty);
183  if (Handler.assignArg(i, CurVT, CurVT, CCValAssign::Full, Args[i], CCInfo)) {
184  // Try to use the register type if we couldn't assign the VT.
185  if (!Handler.isArgumentHandler() || !CurVT.isValid())
186  return false;
187  CurVT = TLI->getRegisterTypeForCallingConv(
188  F.getContext(), F.getCallingConv(), EVT(CurVT));
189  if (Handler.assignArg(i, CurVT, CurVT, CCValAssign::Full, Args[i], CCInfo))
190  return false;
191  }
192  }
193 
194  for (unsigned i = 0, e = Args.size(), j = 0; i != e; ++i, ++j) {
195  assert(j < ArgLocs.size() && "Skipped too many arg locs");
196 
197  CCValAssign &VA = ArgLocs[j];
198  assert(VA.getValNo() == i && "Location doesn't correspond to current arg");
199 
200  if (VA.needsCustom()) {
201  j += Handler.assignCustomValue(Args[i], makeArrayRef(ArgLocs).slice(j));
202  continue;
203  }
204 
205  assert(Args[i].Regs.size() == 1 &&
206  "Can't handle multiple virtual regs yet");
207 
208  // FIXME: Pack registers if we have more than one.
209  Register ArgReg = Args[i].Regs[0];
210 
211  if (VA.isRegLoc()) {
212  MVT OrigVT = MVT::getVT(Args[i].Ty);
213  MVT VAVT = VA.getValVT();
214  if (Handler.isArgumentHandler() && VAVT != OrigVT) {
215  if (VAVT.getSizeInBits() < OrigVT.getSizeInBits())
216  return false; // Can't handle this type of arg yet.
217  const LLT VATy(VAVT);
218  Register NewReg =
219  MIRBuilder.getMRI()->createGenericVirtualRegister(VATy);
220  Handler.assignValueToReg(NewReg, VA.getLocReg(), VA);
221  // If it's a vector type, we either need to truncate the elements
222  // or do an unmerge to get the lower block of elements.
223  if (VATy.isVector() &&
224  VATy.getNumElements() > OrigVT.getVectorNumElements()) {
225  const LLT OrigTy(OrigVT);
226  // Just handle the case where the VA type is 2 * original type.
227  if (VATy.getNumElements() != OrigVT.getVectorNumElements() * 2) {
228  LLVM_DEBUG(dbgs()
229  << "Incoming promoted vector arg has too many elts");
230  return false;
231  }
232  auto Unmerge = MIRBuilder.buildUnmerge({OrigTy, OrigTy}, {NewReg});
233  MIRBuilder.buildCopy(ArgReg, Unmerge.getReg(0));
234  } else {
235  MIRBuilder.buildTrunc(ArgReg, {NewReg}).getReg(0);
236  }
237  } else {
238  Handler.assignValueToReg(ArgReg, VA.getLocReg(), VA);
239  }
240  } else if (VA.isMemLoc()) {
241  MVT VT = MVT::getVT(Args[i].Ty);
242  unsigned Size = VT == MVT::iPTR ? DL.getPointerSize()
243  : alignTo(VT.getSizeInBits(), 8) / 8;
244  unsigned Offset = VA.getLocMemOffset();
245  MachinePointerInfo MPO;
246  Register StackAddr = Handler.getStackAddress(Size, Offset, MPO);
247  Handler.assignValueToAddress(ArgReg, StackAddr, Size, MPO, VA);
248  } else {
249  // FIXME: Support byvals and other weirdness
250  return false;
251  }
252  }
253  return true;
254 }
255 
257  CCValAssign &VA) {
258  LLT LocTy{VA.getLocVT()};
259  if (LocTy.getSizeInBits() == MRI.getType(ValReg).getSizeInBits())
260  return ValReg;
261  switch (VA.getLocInfo()) {
262  default: break;
263  case CCValAssign::Full:
264  case CCValAssign::BCvt:
265  // FIXME: bitconverting between vector types may or may not be a
266  // nop in big-endian situations.
267  return ValReg;
268  case CCValAssign::AExt: {
269  auto MIB = MIRBuilder.buildAnyExt(LocTy, ValReg);
270  return MIB->getOperand(0).getReg();
271  }
272  case CCValAssign::SExt: {
273  Register NewReg = MRI.createGenericVirtualRegister(LocTy);
274  MIRBuilder.buildSExt(NewReg, ValReg);
275  return NewReg;
276  }
277  case CCValAssign::ZExt: {
278  Register NewReg = MRI.createGenericVirtualRegister(LocTy);
279  MIRBuilder.buildZExt(NewReg, ValReg);
280  return NewReg;
281  }
282  }
283  llvm_unreachable("unable to extend register");
284 }
285 
286 void CallLowering::ValueHandler::anchor() {}
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
Definition: Function.h:176
void setByValAlign(unsigned A)
A parsed version of the target data layout string in and methods for querying it. ...
Definition: DataLayout.h:110
MachineInstrBuilder buildUnmerge(ArrayRef< LLT > Res, const SrcOp &Op)
Build and insert Res0, ...
This class represents lattice values for constants.
Definition: AllocatorList.h:23
MachineInstrBuilder buildInsert(Register Res, Register Src, Register Op, unsigned Index)
This class represents a function call, abstracting a target machine&#39;s calling convention.
unsigned getVectorNumElements() const
Offsets
Offsets in bytes from the start of the input buffer.
Definition: SIInstrInfo.h:1100
F(f)
uint64_t alignTo(uint64_t Value, uint64_t Align, uint64_t Skew=0)
Returns the next integer (mod 2**64) that is greater than or equal to Value and is a multiple of Alig...
Definition: MathExtras.h:689
FunTy * getCalledFunction() const
Return the function being called if this is a direct call, otherwise return null (if it&#39;s an indirect...
Definition: CallSite.h:111
virtual void assignValueToAddress(Register ValVReg, Register Addr, uint64_t Size, MachinePointerInfo &MPO, CCValAssign &VA)=0
The specified value has been assigned to a stack location.
virtual unsigned getByValTypeAlignment(Type *Ty, const DataLayout &DL) const
Return the desired alignment for ByVal or InAlloca aggregate function arguments in the caller paramet...
bool hasAttribute(unsigned Index, Attribute::AttrKind Kind) const
Return true if the attribute exists at the given index.
bool isValid() const
Return true if this is a valid simple valuetype.
FunctionType * getFunctionType() const
Definition: CallSite.h:328
static MachineOperand CreateReg(unsigned Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
CallingConv::ID getCallingConv() const
Get the calling convention of the call.
Definition: CallSite.h:320
MachineInstrBuilder buildExtract(const DstOp &Res, const SrcOp &Src, uint64_t Index)
Build and insert `Res0, ...
bool isVector() const
bool handleAssignments(MachineIRBuilder &MIRBuilder, ArrayRef< ArgInfo > Args, ValueHandler &Handler) const
Invoke Handler::assignArg on each of the given Args and then use Callback to move them to the assigne...
const TargetLowering * getTLI() const
Getter for generic TargetLowering class.
Definition: CallLowering.h:129
MachineInstrBuilder buildAnyExt(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_ANYEXT Op0.
const DataLayout & getDataLayout() const
Get the data layout for the module&#39;s target platform.
Definition: Module.cpp:369
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
Definition: ArrayRef.h:450
virtual MVT getRegisterTypeForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const
Certain combinations of ABIs, Targets and features require that types are legal for some operations a...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:41
void setByValSize(unsigned S)
Type * getType() const
Return the type of the instruction that generated this call site.
Definition: CallSite.h:272
LocInfo getLocInfo() const
unsigned getSizeInBits() const
Type * getValueAsType() const
Return the attribute&#39;s value as a Type.
Definition: Attributes.cpp:230
MachineFunction & getMF()
Getter for the function we currently build.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:32
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
void setOrigAlign(unsigned A)
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
MachineInstrBuilder buildSExt(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_SEXT Op.
MachineRegisterInfo * getMRI()
Getter for MRI.
unsigned const MachineRegisterInfo * MRI
Machine Value Type.
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
MachineInstrBuilder buildZExt(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_ZEXT Op.
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:148
unsigned getPointerSize(unsigned AS=0) const
Layout pointer size FIXME: The defaults need to be removed once all of the backends/clients are updat...
Definition: DataLayout.cpp:645
void computeValueLLTs(const DataLayout &DL, Type &Ty, SmallVectorImpl< LLT > &ValueTys, SmallVectorImpl< uint64_t > *Offsets=nullptr, uint64_t StartingOffset=0)
computeValueLLTs - Given an LLVM IR type, compute a sequence of LLTs that represent all the individua...
Definition: Analysis.cpp:127
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
Definition: DerivedTypes.h:139
Helper class to build MachineInstr.
Register packRegs(ArrayRef< Register > SrcRegs, Type *PackedTy, MachineIRBuilder &MIRBuilder) const
Generate instructions for packing SrcRegs into one big register corresponding to the aggregate type P...
static MachineOperand CreateGA(const GlobalValue *GV, int64_t Offset, unsigned char TargetFlags=0)
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
static MVT getVT(Type *Ty, bool HandleUnknown=false)
Return the value type corresponding to the specified type.
Definition: ValueTypes.cpp:312
void setArgFlags(ArgInfo &Arg, unsigned OpIdx, const DataLayout &DL, const FuncInfoTy &FuncInfo) const
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
Definition: Function.cpp:205
static unsigned NumFixedArgs
Extended Value Type.
Definition: ValueTypes.h:33
MachineInstrBuilder buildCopy(const DstOp &Res, const SrcOp &Op)
Build and insert Res = COPY Op.
MachineInstrBuilder buildTrunc(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_TRUNC Op.
Attribute getAttribute(unsigned Index, Attribute::AttrKind Kind) const
Return the attribute object that exists at the given index.
size_t size() const
Definition: SmallVector.h:52
Argument handling is mostly uniform between the four places that make these decisions: function forma...
Definition: CallLowering.h:68
This class contains a discriminated union of information about pointers in memory operands...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
iterator_range< IterTy > args() const
Definition: CallSite.h:222
virtual unsigned assignCustomValue(const ArgInfo &Arg, ArrayRef< CCValAssign > VAs)
Handle custom values, which may be passed into one or more of VAs.
Definition: CallLowering.h:104
LLT getLLTForType(Type &Ty, const DataLayout &DL)
Construct a low-level type based on an LLVM type.
void unpackRegs(ArrayRef< Register > DstRegs, Register SrcReg, Type *PackedTy, MachineIRBuilder &MIRBuilder) const
Generate instructions for unpacking SrcReg into the DstRegs corresponding to the aggregate type Packe...
Register extendRegister(Register ValReg, CCValAssign &VA)
CCState - This class holds information needed while lowering arguments and return values...
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Definition: Function.h:212
MachineOperand class - Representation of each machine instruction operand.
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:837
Module.h This file contains the declarations for the Module class.
CCValAssign - Represent assignment of one arg/retval to a location.
virtual bool lowerCall(MachineIRBuilder &MIRBuilder, CallingConv::ID CallConv, const MachineOperand &Callee, const ArgInfo &OrigRet, ArrayRef< ArgInfo > OrigArgs, Register SwiftErrorVReg) const
This hook must be implemented to lower the given call instruction, including argument and return valu...
Definition: CallLowering.h:241
unsigned getABITypeAlignment(Type *Ty) const
Returns the minimum ABI-required alignment for the specified type.
Definition: DataLayout.cpp:746
const Function & getFunction() const
Return the LLVM function that this machine code represents.
This file declares the MachineIRBuilder class.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
amdgpu Simplify well known AMD library false FunctionCallee Callee
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
BBTy * getParent() const
Get the basic block containing the call site.
Definition: CallSite.h:101
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
virtual void assignValueToReg(Register ValVReg, Register PhysReg, CCValAssign &VA)=0
The specified value has been assigned to a physical register, handle the appropriate COPY (either to ...
uint64_t getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
Definition: DataLayout.h:469
Establish a view to a call site for examination.
Definition: CallSite.h:897
const Function * getParent() const
Return the enclosing method, or null if none.
Definition: BasicBlock.h:106
static MachineOperand CreateImm(int64_t Val)
virtual bool isArgumentHandler() const
Returns true if the handler is dealing with formal arguments, not with return values etc...
Definition: CallLowering.h:77
virtual bool assignArg(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, const ArgInfo &Info, CCState &State)
Definition: CallLowering.h:113
uint32_t Size
Definition: Profile.cpp:46
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:575
uint16_t getNumElements() const
Returns the number of elements in a vector LLT.
This file describes how to lower LLVM calls to machine code calls.
virtual Register getStackAddress(uint64_t Size, int64_t Offset, MachinePointerInfo &MPO)=0
Materialize a VReg containing the address of the specified stack-based object.
print Print MemDeps of function
MachineInstrBuilder buildUndef(const DstOp &Res)
Build and insert Res = IMPLICIT_DEF.
Register createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
Register getReg() const
getReg - Returns the register number.
#define LLVM_DEBUG(X)
Definition: Debug.h:122
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:416
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Wrapper class representing virtual and physical registers.
Definition: Register.h:18
This file describes how to lower LLVM code to machine code.