1 //===-- lib/CodeGen/GlobalISel/CallLowering.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 some simple delegations needed for call lowering. 12 /// 13 //===----------------------------------------------------------------------===// 14 15 16 #include "llvm/CodeGen/GlobalISel/CallLowering.h" 17 #include "llvm/CodeGen/MachineOperand.h" 18 #include "llvm/IR/Instructions.h" 19 #include "llvm/IR/DataLayout.h" 20 #include "llvm/IR/Module.h" 21 #include "llvm/Target/TargetLowering.h" 22 23 using namespace llvm; 24 25 bool CallLowering::lowerCall( 26 MachineIRBuilder &MIRBuilder, const CallInst &CI, unsigned ResReg, 27 ArrayRef<unsigned> ArgRegs, std::function<unsigned()> GetCalleeReg) const { 28 auto &DL = CI.getParent()->getParent()->getParent()->getDataLayout(); 29 30 // First step is to marshall all the function's parameters into the correct 31 // physregs and memory locations. Gather the sequence of argument types that 32 // we'll pass to the assigner function. 33 SmallVector<ArgInfo, 8> OrigArgs; 34 unsigned i = 0; 35 for (auto &Arg : CI.arg_operands()) { 36 ArgInfo OrigArg{ArgRegs[i], Arg->getType(), ISD::ArgFlagsTy{}}; 37 setArgFlags(OrigArg, i + 1, DL, CI); 38 OrigArgs.push_back(OrigArg); 39 ++i; 40 } 41 42 MachineOperand Callee = MachineOperand::CreateImm(0); 43 if (Function *F = CI.getCalledFunction()) 44 Callee = MachineOperand::CreateGA(F, 0); 45 else 46 Callee = MachineOperand::CreateReg(GetCalleeReg(), false); 47 48 ArgInfo OrigRet{ResReg, CI.getType(), ISD::ArgFlagsTy{}}; 49 if (!OrigRet.Ty->isVoidTy()) 50 setArgFlags(OrigRet, AttributeSet::ReturnIndex, DL, CI); 51 52 return lowerCall(MIRBuilder, Callee, OrigRet, OrigArgs); 53 } 54 55 template <typename FuncInfoTy> 56 void CallLowering::setArgFlags(CallLowering::ArgInfo &Arg, unsigned OpIdx, 57 const DataLayout &DL, 58 const FuncInfoTy &FuncInfo) const { 59 const AttributeSet &Attrs = FuncInfo.getAttributes(); 60 if (Attrs.hasAttribute(OpIdx, Attribute::ZExt)) 61 Arg.Flags.setZExt(); 62 if (Attrs.hasAttribute(OpIdx, Attribute::SExt)) 63 Arg.Flags.setSExt(); 64 if (Attrs.hasAttribute(OpIdx, Attribute::InReg)) 65 Arg.Flags.setInReg(); 66 if (Attrs.hasAttribute(OpIdx, Attribute::StructRet)) 67 Arg.Flags.setSRet(); 68 if (Attrs.hasAttribute(OpIdx, Attribute::SwiftSelf)) 69 Arg.Flags.setSwiftSelf(); 70 if (Attrs.hasAttribute(OpIdx, Attribute::SwiftError)) 71 Arg.Flags.setSwiftError(); 72 if (Attrs.hasAttribute(OpIdx, Attribute::ByVal)) 73 Arg.Flags.setByVal(); 74 if (Attrs.hasAttribute(OpIdx, Attribute::InAlloca)) 75 Arg.Flags.setInAlloca(); 76 77 if (Arg.Flags.isByVal() || Arg.Flags.isInAlloca()) { 78 Type *ElementTy = cast<PointerType>(Arg.Ty)->getElementType(); 79 Arg.Flags.setByValSize(DL.getTypeAllocSize(ElementTy)); 80 // For ByVal, alignment should be passed from FE. BE will guess if 81 // this info is not there but there are cases it cannot get right. 82 unsigned FrameAlign; 83 if (FuncInfo.getParamAlignment(OpIdx)) 84 FrameAlign = FuncInfo.getParamAlignment(OpIdx); 85 else 86 FrameAlign = getTLI()->getByValTypeAlignment(ElementTy, DL); 87 Arg.Flags.setByValAlign(FrameAlign); 88 } 89 if (Attrs.hasAttribute(OpIdx, Attribute::Nest)) 90 Arg.Flags.setNest(); 91 Arg.Flags.setOrigAlign(DL.getABITypeAlignment(Arg.Ty)); 92 } 93 94 template void 95 CallLowering::setArgFlags<Function>(CallLowering::ArgInfo &Arg, unsigned OpIdx, 96 const DataLayout &DL, 97 const Function &FuncInfo) const; 98 99 template void 100 CallLowering::setArgFlags<CallInst>(CallLowering::ArgInfo &Arg, unsigned OpIdx, 101 const DataLayout &DL, 102 const CallInst &FuncInfo) const; 103