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 #include "llvm/CodeGen/GlobalISel/CallLowering.h" 16 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" 17 #include "llvm/CodeGen/MachineOperand.h" 18 #include "llvm/IR/DataLayout.h" 19 #include "llvm/IR/Instructions.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 104 bool CallLowering::handleAssignments(MachineIRBuilder &MIRBuilder, 105 CCAssignFn *AssignFn, 106 ArrayRef<ArgInfo> Args, 107 ValueHandler &Handler) const { 108 MachineFunction &MF = MIRBuilder.getMF(); 109 const Function &F = *MF.getFunction(); 110 const DataLayout &DL = F.getParent()->getDataLayout(); 111 112 SmallVector<CCValAssign, 16> ArgLocs; 113 CCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs, F.getContext()); 114 115 unsigned NumArgs = Args.size(); 116 for (unsigned i = 0; i != NumArgs; ++i) { 117 MVT CurVT = MVT::getVT(Args[i].Ty); 118 if (AssignFn(i, CurVT, CurVT, CCValAssign::Full, Args[i].Flags, CCInfo)) 119 return false; 120 } 121 122 for (unsigned i = 0, e = Args.size(); i != e; ++i) { 123 CCValAssign &VA = ArgLocs[i]; 124 125 if (VA.isRegLoc()) 126 Handler.assignValueToReg(Args[i].Reg, VA.getLocReg(), VA); 127 else if (VA.isMemLoc()) { 128 unsigned Size = VA.getValVT() == MVT::iPTR 129 ? DL.getPointerSize() 130 : alignTo(VA.getValVT().getSizeInBits(), 8) / 8; 131 unsigned Offset = VA.getLocMemOffset(); 132 MachinePointerInfo MPO; 133 unsigned StackAddr = Handler.getStackAddress(Size, Offset, MPO); 134 Handler.assignValueToAddress(Args[i].Reg, StackAddr, Size, MPO, VA); 135 } else { 136 // FIXME: Support byvals and other weirdness 137 return false; 138 } 139 } 140 return true; 141 } 142