Tim Northover | fe5f89b | 2016-08-29 19:07:08 +0000 | [diff] [blame] | 1 | //===-- lib/CodeGen/GlobalISel/CallLowering.cpp - Call lowering -----------===// |
| 2 | // |
Chandler Carruth | 2946cd7 | 2019-01-19 08:50:56 +0000 | [diff] [blame^] | 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 |
Tim Northover | fe5f89b | 2016-08-29 19:07:08 +0000 | [diff] [blame] | 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | /// |
| 9 | /// \file |
| 10 | /// This file implements some simple delegations needed for call lowering. |
| 11 | /// |
| 12 | //===----------------------------------------------------------------------===// |
| 13 | |
Tim Northover | fe5f89b | 2016-08-29 19:07:08 +0000 | [diff] [blame] | 14 | #include "llvm/CodeGen/GlobalISel/CallLowering.h" |
Diana Picus | f11f042 | 2016-12-05 10:40:33 +0000 | [diff] [blame] | 15 | #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" |
Tim Northover | fe5f89b | 2016-08-29 19:07:08 +0000 | [diff] [blame] | 16 | #include "llvm/CodeGen/MachineOperand.h" |
Diana Picus | 2d9adbf | 2016-12-13 10:46:12 +0000 | [diff] [blame] | 17 | #include "llvm/CodeGen/MachineRegisterInfo.h" |
David Blaikie | b3bde2e | 2017-11-17 01:07:10 +0000 | [diff] [blame] | 18 | #include "llvm/CodeGen/TargetLowering.h" |
Tim Northover | 9a46718 | 2016-09-21 12:57:45 +0000 | [diff] [blame] | 19 | #include "llvm/IR/DataLayout.h" |
Diana Picus | f11f042 | 2016-12-05 10:40:33 +0000 | [diff] [blame] | 20 | #include "llvm/IR/Instructions.h" |
Tim Northover | 9a46718 | 2016-09-21 12:57:45 +0000 | [diff] [blame] | 21 | #include "llvm/IR/Module.h" |
Tim Northover | fe5f89b | 2016-08-29 19:07:08 +0000 | [diff] [blame] | 22 | |
| 23 | using namespace llvm; |
| 24 | |
Richard Trieu | a87b70d | 2018-12-29 02:02:13 +0000 | [diff] [blame] | 25 | void CallLowering::anchor() {} |
| 26 | |
Tim Northover | fe5f89b | 2016-08-29 19:07:08 +0000 | [diff] [blame] | 27 | bool CallLowering::lowerCall( |
Ahmed Bougacha | d22b84b | 2017-03-10 00:25:44 +0000 | [diff] [blame] | 28 | MachineIRBuilder &MIRBuilder, ImmutableCallSite CS, unsigned ResReg, |
Tim Northover | fe5f89b | 2016-08-29 19:07:08 +0000 | [diff] [blame] | 29 | ArrayRef<unsigned> ArgRegs, std::function<unsigned()> GetCalleeReg) const { |
Ahmed Bougacha | d22b84b | 2017-03-10 00:25:44 +0000 | [diff] [blame] | 30 | auto &DL = CS.getParent()->getParent()->getParent()->getDataLayout(); |
Tim Northover | 9a46718 | 2016-09-21 12:57:45 +0000 | [diff] [blame] | 31 | |
Tim Northover | fe5f89b | 2016-08-29 19:07:08 +0000 | [diff] [blame] | 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. |
Tim Northover | 9a46718 | 2016-09-21 12:57:45 +0000 | [diff] [blame] | 35 | SmallVector<ArgInfo, 8> OrigArgs; |
| 36 | unsigned i = 0; |
Ahmed Bougacha | d22b84b | 2017-03-10 00:25:44 +0000 | [diff] [blame] | 37 | unsigned NumFixedArgs = CS.getFunctionType()->getNumParams(); |
| 38 | for (auto &Arg : CS.args()) { |
Tim Northover | d943354 | 2017-01-17 22:30:10 +0000 | [diff] [blame] | 39 | ArgInfo OrigArg{ArgRegs[i], Arg->getType(), ISD::ArgFlagsTy{}, |
| 40 | i < NumFixedArgs}; |
Reid Kleckner | a0b45f4 | 2017-05-03 18:17:31 +0000 | [diff] [blame] | 41 | setArgFlags(OrigArg, i + AttributeList::FirstArgIndex, DL, CS); |
Amara Emerson | fdd089a | 2018-07-26 01:25:58 +0000 | [diff] [blame] | 42 | // We don't currently support swifterror or swiftself args. |
| 43 | if (OrigArg.Flags.isSwiftError() || OrigArg.Flags.isSwiftSelf()) |
| 44 | return false; |
Tim Northover | 9a46718 | 2016-09-21 12:57:45 +0000 | [diff] [blame] | 45 | OrigArgs.push_back(OrigArg); |
| 46 | ++i; |
| 47 | } |
Tim Northover | fe5f89b | 2016-08-29 19:07:08 +0000 | [diff] [blame] | 48 | |
| 49 | MachineOperand Callee = MachineOperand::CreateImm(0); |
Ahmed Bougacha | d22b84b | 2017-03-10 00:25:44 +0000 | [diff] [blame] | 50 | if (const Function *F = CS.getCalledFunction()) |
Tim Northover | fe5f89b | 2016-08-29 19:07:08 +0000 | [diff] [blame] | 51 | Callee = MachineOperand::CreateGA(F, 0); |
| 52 | else |
| 53 | Callee = MachineOperand::CreateReg(GetCalleeReg(), false); |
| 54 | |
Ahmed Bougacha | d22b84b | 2017-03-10 00:25:44 +0000 | [diff] [blame] | 55 | ArgInfo OrigRet{ResReg, CS.getType(), ISD::ArgFlagsTy{}}; |
Tim Northover | 9a46718 | 2016-09-21 12:57:45 +0000 | [diff] [blame] | 56 | if (!OrigRet.Ty->isVoidTy()) |
Reid Kleckner | b518054 | 2017-03-21 16:57:19 +0000 | [diff] [blame] | 57 | setArgFlags(OrigRet, AttributeList::ReturnIndex, DL, CS); |
Tim Northover | 9a46718 | 2016-09-21 12:57:45 +0000 | [diff] [blame] | 58 | |
Diana Picus | d79253a | 2017-03-20 14:40:18 +0000 | [diff] [blame] | 59 | return lowerCall(MIRBuilder, CS.getCallingConv(), Callee, OrigRet, OrigArgs); |
Tim Northover | fe5f89b | 2016-08-29 19:07:08 +0000 | [diff] [blame] | 60 | } |
Tim Northover | 9a46718 | 2016-09-21 12:57:45 +0000 | [diff] [blame] | 61 | |
| 62 | template <typename FuncInfoTy> |
| 63 | void CallLowering::setArgFlags(CallLowering::ArgInfo &Arg, unsigned OpIdx, |
| 64 | const DataLayout &DL, |
| 65 | const FuncInfoTy &FuncInfo) const { |
Reid Kleckner | b518054 | 2017-03-21 16:57:19 +0000 | [diff] [blame] | 66 | const AttributeList &Attrs = FuncInfo.getAttributes(); |
Tim Northover | 9a46718 | 2016-09-21 12:57:45 +0000 | [diff] [blame] | 67 | if (Attrs.hasAttribute(OpIdx, Attribute::ZExt)) |
| 68 | Arg.Flags.setZExt(); |
| 69 | if (Attrs.hasAttribute(OpIdx, Attribute::SExt)) |
| 70 | Arg.Flags.setSExt(); |
| 71 | if (Attrs.hasAttribute(OpIdx, Attribute::InReg)) |
| 72 | Arg.Flags.setInReg(); |
| 73 | if (Attrs.hasAttribute(OpIdx, Attribute::StructRet)) |
| 74 | Arg.Flags.setSRet(); |
| 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)) |
| 80 | Arg.Flags.setByVal(); |
| 81 | if (Attrs.hasAttribute(OpIdx, Attribute::InAlloca)) |
| 82 | Arg.Flags.setInAlloca(); |
| 83 | |
| 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. |
| 89 | unsigned FrameAlign; |
Reid Kleckner | ee4930b | 2017-05-02 22:07:37 +0000 | [diff] [blame] | 90 | if (FuncInfo.getParamAlignment(OpIdx - 2)) |
| 91 | FrameAlign = FuncInfo.getParamAlignment(OpIdx - 2); |
Tim Northover | 9a46718 | 2016-09-21 12:57:45 +0000 | [diff] [blame] | 92 | else |
| 93 | FrameAlign = getTLI()->getByValTypeAlignment(ElementTy, DL); |
| 94 | Arg.Flags.setByValAlign(FrameAlign); |
| 95 | } |
| 96 | if (Attrs.hasAttribute(OpIdx, Attribute::Nest)) |
| 97 | Arg.Flags.setNest(); |
| 98 | Arg.Flags.setOrigAlign(DL.getABITypeAlignment(Arg.Ty)); |
| 99 | } |
| 100 | |
| 101 | template void |
| 102 | CallLowering::setArgFlags<Function>(CallLowering::ArgInfo &Arg, unsigned OpIdx, |
| 103 | const DataLayout &DL, |
| 104 | const Function &FuncInfo) const; |
| 105 | |
| 106 | template void |
| 107 | CallLowering::setArgFlags<CallInst>(CallLowering::ArgInfo &Arg, unsigned OpIdx, |
| 108 | const DataLayout &DL, |
| 109 | const CallInst &FuncInfo) const; |
Diana Picus | f11f042 | 2016-12-05 10:40:33 +0000 | [diff] [blame] | 110 | |
| 111 | bool CallLowering::handleAssignments(MachineIRBuilder &MIRBuilder, |
Diana Picus | f11f042 | 2016-12-05 10:40:33 +0000 | [diff] [blame] | 112 | ArrayRef<ArgInfo> Args, |
| 113 | ValueHandler &Handler) const { |
| 114 | MachineFunction &MF = MIRBuilder.getMF(); |
Matthias Braun | f1caa28 | 2017-12-15 22:22:58 +0000 | [diff] [blame] | 115 | const Function &F = MF.getFunction(); |
Tim Northover | c0bd197 | 2016-12-05 22:20:32 +0000 | [diff] [blame] | 116 | const DataLayout &DL = F.getParent()->getDataLayout(); |
Diana Picus | f11f042 | 2016-12-05 10:40:33 +0000 | [diff] [blame] | 117 | |
| 118 | SmallVector<CCValAssign, 16> ArgLocs; |
| 119 | CCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs, F.getContext()); |
| 120 | |
| 121 | unsigned NumArgs = Args.size(); |
| 122 | for (unsigned i = 0; i != NumArgs; ++i) { |
| 123 | MVT CurVT = MVT::getVT(Args[i].Ty); |
Tim Northover | d943354 | 2017-01-17 22:30:10 +0000 | [diff] [blame] | 124 | if (Handler.assignArg(i, CurVT, CurVT, CCValAssign::Full, Args[i], CCInfo)) |
Diana Picus | f11f042 | 2016-12-05 10:40:33 +0000 | [diff] [blame] | 125 | return false; |
| 126 | } |
| 127 | |
Diana Picus | ca6a890 | 2017-02-16 07:53:07 +0000 | [diff] [blame] | 128 | for (unsigned i = 0, e = Args.size(), j = 0; i != e; ++i, ++j) { |
| 129 | assert(j < ArgLocs.size() && "Skipped too many arg locs"); |
| 130 | |
| 131 | CCValAssign &VA = ArgLocs[j]; |
| 132 | assert(VA.getValNo() == i && "Location doesn't correspond to current arg"); |
| 133 | |
| 134 | if (VA.needsCustom()) { |
| 135 | j += Handler.assignCustomValue(Args[i], makeArrayRef(ArgLocs).slice(j)); |
| 136 | continue; |
| 137 | } |
Diana Picus | f11f042 | 2016-12-05 10:40:33 +0000 | [diff] [blame] | 138 | |
| 139 | if (VA.isRegLoc()) |
| 140 | Handler.assignValueToReg(Args[i].Reg, VA.getLocReg(), VA); |
| 141 | else if (VA.isMemLoc()) { |
Tim Northover | c0bd197 | 2016-12-05 22:20:32 +0000 | [diff] [blame] | 142 | unsigned Size = VA.getValVT() == MVT::iPTR |
| 143 | ? DL.getPointerSize() |
Tim Northover | 14ceb45 | 2016-12-06 21:02:19 +0000 | [diff] [blame] | 144 | : alignTo(VA.getValVT().getSizeInBits(), 8) / 8; |
Diana Picus | f11f042 | 2016-12-05 10:40:33 +0000 | [diff] [blame] | 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); |
| 149 | } else { |
| 150 | // FIXME: Support byvals and other weirdness |
| 151 | return false; |
| 152 | } |
| 153 | } |
| 154 | return true; |
| 155 | } |
Diana Picus | 2d9adbf | 2016-12-13 10:46:12 +0000 | [diff] [blame] | 156 | |
| 157 | unsigned CallLowering::ValueHandler::extendRegister(unsigned ValReg, |
| 158 | CCValAssign &VA) { |
| 159 | LLT LocTy{VA.getLocVT()}; |
| 160 | switch (VA.getLocInfo()) { |
| 161 | default: break; |
| 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. |
| 166 | return ValReg; |
Aditya Nandakumar | c3bfc81 | 2017-10-09 20:07:43 +0000 | [diff] [blame] | 167 | case CCValAssign::AExt: { |
Aditya Nandakumar | c3bfc81 | 2017-10-09 20:07:43 +0000 | [diff] [blame] | 168 | auto MIB = MIRBuilder.buildAnyExt(LocTy, ValReg); |
| 169 | return MIB->getOperand(0).getReg(); |
| 170 | } |
Diana Picus | 2d9adbf | 2016-12-13 10:46:12 +0000 | [diff] [blame] | 171 | case CCValAssign::SExt: { |
| 172 | unsigned NewReg = MRI.createGenericVirtualRegister(LocTy); |
| 173 | MIRBuilder.buildSExt(NewReg, ValReg); |
| 174 | return NewReg; |
| 175 | } |
| 176 | case CCValAssign::ZExt: { |
| 177 | unsigned NewReg = MRI.createGenericVirtualRegister(LocTy); |
| 178 | MIRBuilder.buildZExt(NewReg, ValReg); |
| 179 | return NewReg; |
| 180 | } |
| 181 | } |
| 182 | llvm_unreachable("unable to extend register"); |
| 183 | } |
Richard Trieu | a87b70d | 2018-12-29 02:02:13 +0000 | [diff] [blame] | 184 | |
| 185 | void CallLowering::ValueHandler::anchor() {} |