LLVM  10.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/LLVMContext.h"
23 #include "llvm/IR/Module.h"
24 
25 #define DEBUG_TYPE "call-lowering"
26 
27 using namespace llvm;
28 
29 void CallLowering::anchor() {}
30 
32  ArrayRef<Register> ResRegs,
34  Register SwiftErrorVReg,
35  std::function<unsigned()> GetCalleeReg) const {
37  auto &DL = CS.getParent()->getParent()->getParent()->getDataLayout();
38 
39  // 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.
42  unsigned i = 0;
43  unsigned NumFixedArgs = CS.getFunctionType()->getNumParams();
44  for (auto &Arg : CS.args()) {
45  ArgInfo OrigArg{ArgRegs[i], Arg->getType(), ISD::ArgFlagsTy{},
46  i < NumFixedArgs};
47  setArgFlags(OrigArg, i + AttributeList::FirstArgIndex, DL, CS);
48  Info.OrigArgs.push_back(OrigArg);
49  ++i;
50  }
51 
52  if (const Function *F = CS.getCalledFunction())
54  else
55  Info.Callee = MachineOperand::CreateReg(GetCalleeReg(), false);
56 
57  Info.OrigRet = ArgInfo{ResRegs, CS.getType(), ISD::ArgFlagsTy{}};
58  if (!Info.OrigRet.Ty->isVoidTy())
60 
61  Info.KnownCallees =
62  CS.getInstruction()->getMetadata(LLVMContext::MD_callees);
63  Info.CallConv = CS.getCallingConv();
64  Info.SwiftErrorVReg = SwiftErrorVReg;
65 
66  return lowerCall(MIRBuilder, Info);
67 }
68 
69 template <typename FuncInfoTy>
71  const DataLayout &DL,
72  const FuncInfoTy &FuncInfo) const {
73  const AttributeList &Attrs = FuncInfo.getAttributes();
74  if (Attrs.hasAttribute(OpIdx, Attribute::ZExt))
75  Arg.Flags.setZExt();
76  if (Attrs.hasAttribute(OpIdx, Attribute::SExt))
77  Arg.Flags.setSExt();
78  if (Attrs.hasAttribute(OpIdx, Attribute::InReg))
79  Arg.Flags.setInReg();
80  if (Attrs.hasAttribute(OpIdx, Attribute::StructRet))
81  Arg.Flags.setSRet();
82  if (Attrs.hasAttribute(OpIdx, Attribute::SwiftSelf))
83  Arg.Flags.setSwiftSelf();
84  if (Attrs.hasAttribute(OpIdx, Attribute::SwiftError))
85  Arg.Flags.setSwiftError();
86  if (Attrs.hasAttribute(OpIdx, Attribute::ByVal))
87  Arg.Flags.setByVal();
88  if (Attrs.hasAttribute(OpIdx, Attribute::InAlloca))
89  Arg.Flags.setInAlloca();
90 
91  if (Arg.Flags.isByVal() || Arg.Flags.isInAlloca()) {
92  Type *ElementTy = cast<PointerType>(Arg.Ty)->getElementType();
93 
94  auto Ty = Attrs.getAttribute(OpIdx, Attribute::ByVal).getValueAsType();
95  Arg.Flags.setByValSize(DL.getTypeAllocSize(Ty ? Ty : ElementTy));
96 
97  // For ByVal, alignment should be passed from FE. BE will guess if
98  // this info is not there but there are cases it cannot get right.
99  unsigned FrameAlign;
100  if (FuncInfo.getParamAlignment(OpIdx - 2))
101  FrameAlign = FuncInfo.getParamAlignment(OpIdx - 2);
102  else
103  FrameAlign = getTLI()->getByValTypeAlignment(ElementTy, DL);
104  Arg.Flags.setByValAlign(FrameAlign);
105  }
106  if (Attrs.hasAttribute(OpIdx, Attribute::Nest))
107  Arg.Flags.setNest();
109 }
110 
111 template void
112 CallLowering::setArgFlags<Function>(CallLowering::ArgInfo &Arg, unsigned OpIdx,
113  const DataLayout &DL,
114  const Function &FuncInfo) const;
115 
116 template void
117 CallLowering::setArgFlags<CallInst>(CallLowering::ArgInfo &Arg, unsigned OpIdx,
118  const DataLayout &DL,
119  const CallInst &FuncInfo) const;
120 
122  MachineIRBuilder &MIRBuilder) const {
123  assert(SrcRegs.size() > 1 && "Nothing to pack");
124 
125  const DataLayout &DL = MIRBuilder.getMF().getDataLayout();
126  MachineRegisterInfo *MRI = MIRBuilder.getMRI();
127 
128  LLT PackedLLT = getLLTForType(*PackedTy, DL);
129 
130  SmallVector<LLT, 8> LLTs;
132  computeValueLLTs(DL, *PackedTy, LLTs, &Offsets);
133  assert(LLTs.size() == SrcRegs.size() && "Regs / types mismatch");
134 
135  Register Dst = MRI->createGenericVirtualRegister(PackedLLT);
136  MIRBuilder.buildUndef(Dst);
137  for (unsigned i = 0; i < SrcRegs.size(); ++i) {
138  Register NewDst = MRI->createGenericVirtualRegister(PackedLLT);
139  MIRBuilder.buildInsert(NewDst, Dst, SrcRegs[i], Offsets[i]);
140  Dst = NewDst;
141  }
142 
143  return Dst;
144 }
145 
147  Type *PackedTy,
148  MachineIRBuilder &MIRBuilder) const {
149  assert(DstRegs.size() > 1 && "Nothing to unpack");
150 
151  const DataLayout &DL = MIRBuilder.getMF().getDataLayout();
152 
153  SmallVector<LLT, 8> LLTs;
155  computeValueLLTs(DL, *PackedTy, LLTs, &Offsets);
156  assert(LLTs.size() == DstRegs.size() && "Regs / types mismatch");
157 
158  for (unsigned i = 0; i < DstRegs.size(); ++i)
159  MIRBuilder.buildExtract(DstRegs[i], SrcReg, Offsets[i]);
160 }
161 
164  ValueHandler &Handler) const {
165  MachineFunction &MF = MIRBuilder.getMF();
166  const Function &F = MF.getFunction();
168  CCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs, F.getContext());
169  return handleAssignments(CCInfo, ArgLocs, MIRBuilder, Args, Handler);
170 }
171 
174  MachineIRBuilder &MIRBuilder,
176  ValueHandler &Handler) const {
177  MachineFunction &MF = MIRBuilder.getMF();
178  const Function &F = MF.getFunction();
179  const DataLayout &DL = F.getParent()->getDataLayout();
180 
181  unsigned NumArgs = Args.size();
182  for (unsigned i = 0; i != NumArgs; ++i) {
183  MVT CurVT = MVT::getVT(Args[i].Ty);
184  if (Handler.assignArg(i, CurVT, CurVT, CCValAssign::Full, Args[i], CCInfo)) {
185  // Try to use the register type if we couldn't assign the VT.
186  if (!Handler.isIncomingArgumentHandler() || !CurVT.isValid())
187  return false;
188  CurVT = TLI->getRegisterTypeForCallingConv(
189  F.getContext(), F.getCallingConv(), EVT(CurVT));
190  if (Handler.assignArg(i, CurVT, CurVT, CCValAssign::Full, Args[i], CCInfo))
191  return false;
192  }
193  }
194 
195  for (unsigned i = 0, e = Args.size(), j = 0; i != e; ++i, ++j) {
196  assert(j < ArgLocs.size() && "Skipped too many arg locs");
197 
198  CCValAssign &VA = ArgLocs[j];
199  assert(VA.getValNo() == i && "Location doesn't correspond to current arg");
200 
201  if (VA.needsCustom()) {
202  j += Handler.assignCustomValue(Args[i], makeArrayRef(ArgLocs).slice(j));
203  continue;
204  }
205 
206  assert(Args[i].Regs.size() == 1 &&
207  "Can't handle multiple virtual regs yet");
208 
209  // FIXME: Pack registers if we have more than one.
210  Register ArgReg = Args[i].Regs[0];
211 
212  if (VA.isRegLoc()) {
213  MVT OrigVT = MVT::getVT(Args[i].Ty);
214  MVT VAVT = VA.getValVT();
215  if (Handler.isIncomingArgumentHandler() && VAVT != OrigVT) {
216  if (VAVT.getSizeInBits() < OrigVT.getSizeInBits())
217  return false; // Can't handle this type of arg yet.
218  const LLT VATy(VAVT);
219  Register NewReg =
220  MIRBuilder.getMRI()->createGenericVirtualRegister(VATy);
221  Handler.assignValueToReg(NewReg, VA.getLocReg(), VA);
222  // If it's a vector type, we either need to truncate the elements
223  // or do an unmerge to get the lower block of elements.
224  if (VATy.isVector() &&
225  VATy.getNumElements() > OrigVT.getVectorNumElements()) {
226  const LLT OrigTy(OrigVT);
227  // Just handle the case where the VA type is 2 * original type.
228  if (VATy.getNumElements() != OrigVT.getVectorNumElements() * 2) {
229  LLVM_DEBUG(dbgs()
230  << "Incoming promoted vector arg has too many elts");
231  return false;
232  }
233  auto Unmerge = MIRBuilder.buildUnmerge({OrigTy, OrigTy}, {NewReg});
234  MIRBuilder.buildCopy(ArgReg, Unmerge.getReg(0));
235  } else {
236  MIRBuilder.buildTrunc(ArgReg, {NewReg}).getReg(0);
237  }
238  } else {
239  Handler.assignValueToReg(ArgReg, VA.getLocReg(), VA);
240  }
241  } else if (VA.isMemLoc()) {
242  MVT VT = MVT::getVT(Args[i].Ty);
243  unsigned Size = VT == MVT::iPTR ? DL.getPointerSize()
244  : alignTo(VT.getSizeInBits(), 8) / 8;
245  unsigned Offset = VA.getLocMemOffset();
246  MachinePointerInfo MPO;
247  Register StackAddr = Handler.getStackAddress(Size, Offset, MPO);
248  Handler.assignValueToAddress(ArgReg, StackAddr, Size, MPO, VA);
249  } else {
250  // FIXME: Support byvals and other weirdness
251  return false;
252  }
253  }
254  return true;
255 }
256 
258  CCValAssign &VA) {
259  LLT LocTy{VA.getLocVT()};
260  if (LocTy.getSizeInBits() == MRI.getType(ValReg).getSizeInBits())
261  return ValReg;
262  switch (VA.getLocInfo()) {
263  default: break;
264  case CCValAssign::Full:
265  case CCValAssign::BCvt:
266  // FIXME: bitconverting between vector types may or may not be a
267  // nop in big-endian situations.
268  return ValReg;
269  case CCValAssign::AExt: {
270  auto MIB = MIRBuilder.buildAnyExt(LocTy, ValReg);
271  return MIB->getOperand(0).getReg();
272  }
273  case CCValAssign::SExt: {
274  Register NewReg = MRI.createGenericVirtualRegister(LocTy);
275  MIRBuilder.buildSExt(NewReg, ValReg);
276  return NewReg;
277  }
278  case CCValAssign::ZExt: {
279  Register NewReg = MRI.createGenericVirtualRegister(LocTy);
280  MIRBuilder.buildZExt(NewReg, ValReg);
281  return NewReg;
282  }
283  }
284  llvm_unreachable("unable to extend register");
285 }
286 
287 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:111
MachineOperand Callee
Destination of the call.
Definition: CallLowering.h:70
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)
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
Register SwiftErrorVReg
Valid if the call has a swifterror inout parameter, and contains the vreg that the swifterror should ...
Definition: CallLowering.h:80
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
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:152
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
static MachineOperand CreateGA(const GlobalValue *GV, int64_t Offset, unsigned TargetFlags=0)
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
virtual bool lowerCall(MachineIRBuilder &MIRBuilder, CallLoweringInfo &Info) const
This hook must be implemented to lower the given call instruction, including argument and return valu...
Definition: CallLowering.h:251
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
InstrTy * getInstruction() const
Definition: CallSite.h:96
virtual bool isIncomingArgumentHandler() const
Returns true if the handler is dealing with incoming arguments, i.e.
Definition: CallLowering.h:100
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.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
Definition: Instruction.h:234
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)
Analysis containing CSE Info
Definition: CSEInfo.cpp:20
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
bool isVoidTy() const
Return true if this is &#39;void&#39;.
Definition: Type.h:140
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:651
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...
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:442
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 MachineOperand CreateReg(Register 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)
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:91
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:127
LLT getLLTForType(Type &Ty, const DataLayout &DL)
Construct a low-level type based on an LLVM type.
SmallVector< ArgInfo, 8 > OrigArgs
List of descriptors of the arguments passed to the function.
Definition: CallLowering.h:76
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
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.
unsigned getABITypeAlignment(Type *Ty) const
Returns the minimum ABI-required alignment for the specified type.
Definition: DataLayout.cpp:752
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
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:470
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:126
CallingConv::ID CallConv
Calling convention to be used for the call.
Definition: CallLowering.h:66
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
virtual bool assignArg(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, const ArgInfo &Info, CCState &State)
Definition: CallLowering.h:136
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
ArgInfo OrigRet
Descriptor for the return type of the function.
Definition: CallLowering.h:73
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
This file describes how to lower LLVM code to machine code.