1*0b57cec5SDimitry Andric //===-- CallingConvLower.cpp - Calling Conventions ------------------------===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric // 9*0b57cec5SDimitry Andric // This file implements the CCState class, used for lowering and implementing 10*0b57cec5SDimitry Andric // calling conventions. 11*0b57cec5SDimitry Andric // 12*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 13*0b57cec5SDimitry Andric 14*0b57cec5SDimitry Andric #include "llvm/CodeGen/CallingConvLower.h" 15*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h" 16*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h" 17*0b57cec5SDimitry Andric #include "llvm/CodeGen/TargetLowering.h" 18*0b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h" 19*0b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h" 20*0b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h" 21*0b57cec5SDimitry Andric #include "llvm/Support/Debug.h" 22*0b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 23*0b57cec5SDimitry Andric #include "llvm/Support/SaveAndRestore.h" 24*0b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 25*0b57cec5SDimitry Andric #include <algorithm> 26*0b57cec5SDimitry Andric 27*0b57cec5SDimitry Andric using namespace llvm; 28*0b57cec5SDimitry Andric 29*0b57cec5SDimitry Andric CCState::CCState(CallingConv::ID CC, bool isVarArg, MachineFunction &mf, 30*0b57cec5SDimitry Andric SmallVectorImpl<CCValAssign> &locs, LLVMContext &C) 31*0b57cec5SDimitry Andric : CallingConv(CC), IsVarArg(isVarArg), MF(mf), 32*0b57cec5SDimitry Andric TRI(*MF.getSubtarget().getRegisterInfo()), Locs(locs), Context(C) { 33*0b57cec5SDimitry Andric // No stack is used. 34*0b57cec5SDimitry Andric StackOffset = 0; 35*0b57cec5SDimitry Andric MaxStackArgAlign = 1; 36*0b57cec5SDimitry Andric 37*0b57cec5SDimitry Andric clearByValRegsInfo(); 38*0b57cec5SDimitry Andric UsedRegs.resize((TRI.getNumRegs()+31)/32); 39*0b57cec5SDimitry Andric } 40*0b57cec5SDimitry Andric 41*0b57cec5SDimitry Andric /// Allocate space on the stack large enough to pass an argument by value. 42*0b57cec5SDimitry Andric /// The size and alignment information of the argument is encoded in 43*0b57cec5SDimitry Andric /// its parameter attribute. 44*0b57cec5SDimitry Andric void CCState::HandleByVal(unsigned ValNo, MVT ValVT, 45*0b57cec5SDimitry Andric MVT LocVT, CCValAssign::LocInfo LocInfo, 46*0b57cec5SDimitry Andric int MinSize, int MinAlign, 47*0b57cec5SDimitry Andric ISD::ArgFlagsTy ArgFlags) { 48*0b57cec5SDimitry Andric unsigned Align = ArgFlags.getByValAlign(); 49*0b57cec5SDimitry Andric unsigned Size = ArgFlags.getByValSize(); 50*0b57cec5SDimitry Andric if (MinSize > (int)Size) 51*0b57cec5SDimitry Andric Size = MinSize; 52*0b57cec5SDimitry Andric if (MinAlign > (int)Align) 53*0b57cec5SDimitry Andric Align = MinAlign; 54*0b57cec5SDimitry Andric ensureMaxAlignment(Align); 55*0b57cec5SDimitry Andric MF.getSubtarget().getTargetLowering()->HandleByVal(this, Size, Align); 56*0b57cec5SDimitry Andric Size = unsigned(alignTo(Size, MinAlign)); 57*0b57cec5SDimitry Andric unsigned Offset = AllocateStack(Size, Align); 58*0b57cec5SDimitry Andric addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo)); 59*0b57cec5SDimitry Andric } 60*0b57cec5SDimitry Andric 61*0b57cec5SDimitry Andric /// Mark a register and all of its aliases as allocated. 62*0b57cec5SDimitry Andric void CCState::MarkAllocated(unsigned Reg) { 63*0b57cec5SDimitry Andric for (MCRegAliasIterator AI(Reg, &TRI, true); AI.isValid(); ++AI) 64*0b57cec5SDimitry Andric UsedRegs[*AI/32] |= 1 << (*AI&31); 65*0b57cec5SDimitry Andric } 66*0b57cec5SDimitry Andric 67*0b57cec5SDimitry Andric bool CCState::IsShadowAllocatedReg(unsigned Reg) const { 68*0b57cec5SDimitry Andric if (!isAllocated(Reg)) 69*0b57cec5SDimitry Andric return false; 70*0b57cec5SDimitry Andric 71*0b57cec5SDimitry Andric for (auto const &ValAssign : Locs) { 72*0b57cec5SDimitry Andric if (ValAssign.isRegLoc()) { 73*0b57cec5SDimitry Andric for (MCRegAliasIterator AI(ValAssign.getLocReg(), &TRI, true); 74*0b57cec5SDimitry Andric AI.isValid(); ++AI) { 75*0b57cec5SDimitry Andric if (*AI == Reg) 76*0b57cec5SDimitry Andric return false; 77*0b57cec5SDimitry Andric } 78*0b57cec5SDimitry Andric } 79*0b57cec5SDimitry Andric } 80*0b57cec5SDimitry Andric return true; 81*0b57cec5SDimitry Andric } 82*0b57cec5SDimitry Andric 83*0b57cec5SDimitry Andric /// Analyze an array of argument values, 84*0b57cec5SDimitry Andric /// incorporating info about the formals into this state. 85*0b57cec5SDimitry Andric void 86*0b57cec5SDimitry Andric CCState::AnalyzeFormalArguments(const SmallVectorImpl<ISD::InputArg> &Ins, 87*0b57cec5SDimitry Andric CCAssignFn Fn) { 88*0b57cec5SDimitry Andric unsigned NumArgs = Ins.size(); 89*0b57cec5SDimitry Andric 90*0b57cec5SDimitry Andric for (unsigned i = 0; i != NumArgs; ++i) { 91*0b57cec5SDimitry Andric MVT ArgVT = Ins[i].VT; 92*0b57cec5SDimitry Andric ISD::ArgFlagsTy ArgFlags = Ins[i].Flags; 93*0b57cec5SDimitry Andric if (Fn(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, *this)) { 94*0b57cec5SDimitry Andric #ifndef NDEBUG 95*0b57cec5SDimitry Andric dbgs() << "Formal argument #" << i << " has unhandled type " 96*0b57cec5SDimitry Andric << EVT(ArgVT).getEVTString() << '\n'; 97*0b57cec5SDimitry Andric #endif 98*0b57cec5SDimitry Andric llvm_unreachable(nullptr); 99*0b57cec5SDimitry Andric } 100*0b57cec5SDimitry Andric } 101*0b57cec5SDimitry Andric } 102*0b57cec5SDimitry Andric 103*0b57cec5SDimitry Andric /// Analyze the return values of a function, returning true if the return can 104*0b57cec5SDimitry Andric /// be performed without sret-demotion and false otherwise. 105*0b57cec5SDimitry Andric bool CCState::CheckReturn(const SmallVectorImpl<ISD::OutputArg> &Outs, 106*0b57cec5SDimitry Andric CCAssignFn Fn) { 107*0b57cec5SDimitry Andric // Determine which register each value should be copied into. 108*0b57cec5SDimitry Andric for (unsigned i = 0, e = Outs.size(); i != e; ++i) { 109*0b57cec5SDimitry Andric MVT VT = Outs[i].VT; 110*0b57cec5SDimitry Andric ISD::ArgFlagsTy ArgFlags = Outs[i].Flags; 111*0b57cec5SDimitry Andric if (Fn(i, VT, VT, CCValAssign::Full, ArgFlags, *this)) 112*0b57cec5SDimitry Andric return false; 113*0b57cec5SDimitry Andric } 114*0b57cec5SDimitry Andric return true; 115*0b57cec5SDimitry Andric } 116*0b57cec5SDimitry Andric 117*0b57cec5SDimitry Andric /// Analyze the returned values of a return, 118*0b57cec5SDimitry Andric /// incorporating info about the result values into this state. 119*0b57cec5SDimitry Andric void CCState::AnalyzeReturn(const SmallVectorImpl<ISD::OutputArg> &Outs, 120*0b57cec5SDimitry Andric CCAssignFn Fn) { 121*0b57cec5SDimitry Andric // Determine which register each value should be copied into. 122*0b57cec5SDimitry Andric for (unsigned i = 0, e = Outs.size(); i != e; ++i) { 123*0b57cec5SDimitry Andric MVT VT = Outs[i].VT; 124*0b57cec5SDimitry Andric ISD::ArgFlagsTy ArgFlags = Outs[i].Flags; 125*0b57cec5SDimitry Andric if (Fn(i, VT, VT, CCValAssign::Full, ArgFlags, *this)) { 126*0b57cec5SDimitry Andric #ifndef NDEBUG 127*0b57cec5SDimitry Andric dbgs() << "Return operand #" << i << " has unhandled type " 128*0b57cec5SDimitry Andric << EVT(VT).getEVTString() << '\n'; 129*0b57cec5SDimitry Andric #endif 130*0b57cec5SDimitry Andric llvm_unreachable(nullptr); 131*0b57cec5SDimitry Andric } 132*0b57cec5SDimitry Andric } 133*0b57cec5SDimitry Andric } 134*0b57cec5SDimitry Andric 135*0b57cec5SDimitry Andric /// Analyze the outgoing arguments to a call, 136*0b57cec5SDimitry Andric /// incorporating info about the passed values into this state. 137*0b57cec5SDimitry Andric void CCState::AnalyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Outs, 138*0b57cec5SDimitry Andric CCAssignFn Fn) { 139*0b57cec5SDimitry Andric unsigned NumOps = Outs.size(); 140*0b57cec5SDimitry Andric for (unsigned i = 0; i != NumOps; ++i) { 141*0b57cec5SDimitry Andric MVT ArgVT = Outs[i].VT; 142*0b57cec5SDimitry Andric ISD::ArgFlagsTy ArgFlags = Outs[i].Flags; 143*0b57cec5SDimitry Andric if (Fn(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, *this)) { 144*0b57cec5SDimitry Andric #ifndef NDEBUG 145*0b57cec5SDimitry Andric dbgs() << "Call operand #" << i << " has unhandled type " 146*0b57cec5SDimitry Andric << EVT(ArgVT).getEVTString() << '\n'; 147*0b57cec5SDimitry Andric #endif 148*0b57cec5SDimitry Andric llvm_unreachable(nullptr); 149*0b57cec5SDimitry Andric } 150*0b57cec5SDimitry Andric } 151*0b57cec5SDimitry Andric } 152*0b57cec5SDimitry Andric 153*0b57cec5SDimitry Andric /// Same as above except it takes vectors of types and argument flags. 154*0b57cec5SDimitry Andric void CCState::AnalyzeCallOperands(SmallVectorImpl<MVT> &ArgVTs, 155*0b57cec5SDimitry Andric SmallVectorImpl<ISD::ArgFlagsTy> &Flags, 156*0b57cec5SDimitry Andric CCAssignFn Fn) { 157*0b57cec5SDimitry Andric unsigned NumOps = ArgVTs.size(); 158*0b57cec5SDimitry Andric for (unsigned i = 0; i != NumOps; ++i) { 159*0b57cec5SDimitry Andric MVT ArgVT = ArgVTs[i]; 160*0b57cec5SDimitry Andric ISD::ArgFlagsTy ArgFlags = Flags[i]; 161*0b57cec5SDimitry Andric if (Fn(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, *this)) { 162*0b57cec5SDimitry Andric #ifndef NDEBUG 163*0b57cec5SDimitry Andric dbgs() << "Call operand #" << i << " has unhandled type " 164*0b57cec5SDimitry Andric << EVT(ArgVT).getEVTString() << '\n'; 165*0b57cec5SDimitry Andric #endif 166*0b57cec5SDimitry Andric llvm_unreachable(nullptr); 167*0b57cec5SDimitry Andric } 168*0b57cec5SDimitry Andric } 169*0b57cec5SDimitry Andric } 170*0b57cec5SDimitry Andric 171*0b57cec5SDimitry Andric /// Analyze the return values of a call, incorporating info about the passed 172*0b57cec5SDimitry Andric /// values into this state. 173*0b57cec5SDimitry Andric void CCState::AnalyzeCallResult(const SmallVectorImpl<ISD::InputArg> &Ins, 174*0b57cec5SDimitry Andric CCAssignFn Fn) { 175*0b57cec5SDimitry Andric for (unsigned i = 0, e = Ins.size(); i != e; ++i) { 176*0b57cec5SDimitry Andric MVT VT = Ins[i].VT; 177*0b57cec5SDimitry Andric ISD::ArgFlagsTy Flags = Ins[i].Flags; 178*0b57cec5SDimitry Andric if (Fn(i, VT, VT, CCValAssign::Full, Flags, *this)) { 179*0b57cec5SDimitry Andric #ifndef NDEBUG 180*0b57cec5SDimitry Andric dbgs() << "Call result #" << i << " has unhandled type " 181*0b57cec5SDimitry Andric << EVT(VT).getEVTString() << '\n'; 182*0b57cec5SDimitry Andric #endif 183*0b57cec5SDimitry Andric llvm_unreachable(nullptr); 184*0b57cec5SDimitry Andric } 185*0b57cec5SDimitry Andric } 186*0b57cec5SDimitry Andric } 187*0b57cec5SDimitry Andric 188*0b57cec5SDimitry Andric /// Same as above except it's specialized for calls that produce a single value. 189*0b57cec5SDimitry Andric void CCState::AnalyzeCallResult(MVT VT, CCAssignFn Fn) { 190*0b57cec5SDimitry Andric if (Fn(0, VT, VT, CCValAssign::Full, ISD::ArgFlagsTy(), *this)) { 191*0b57cec5SDimitry Andric #ifndef NDEBUG 192*0b57cec5SDimitry Andric dbgs() << "Call result has unhandled type " 193*0b57cec5SDimitry Andric << EVT(VT).getEVTString() << '\n'; 194*0b57cec5SDimitry Andric #endif 195*0b57cec5SDimitry Andric llvm_unreachable(nullptr); 196*0b57cec5SDimitry Andric } 197*0b57cec5SDimitry Andric } 198*0b57cec5SDimitry Andric 199*0b57cec5SDimitry Andric static bool isValueTypeInRegForCC(CallingConv::ID CC, MVT VT) { 200*0b57cec5SDimitry Andric if (VT.isVector()) 201*0b57cec5SDimitry Andric return true; // Assume -msse-regparm might be in effect. 202*0b57cec5SDimitry Andric if (!VT.isInteger()) 203*0b57cec5SDimitry Andric return false; 204*0b57cec5SDimitry Andric if (CC == CallingConv::X86_VectorCall || CC == CallingConv::X86_FastCall) 205*0b57cec5SDimitry Andric return true; 206*0b57cec5SDimitry Andric return false; 207*0b57cec5SDimitry Andric } 208*0b57cec5SDimitry Andric 209*0b57cec5SDimitry Andric void CCState::getRemainingRegParmsForType(SmallVectorImpl<MCPhysReg> &Regs, 210*0b57cec5SDimitry Andric MVT VT, CCAssignFn Fn) { 211*0b57cec5SDimitry Andric unsigned SavedStackOffset = StackOffset; 212*0b57cec5SDimitry Andric unsigned SavedMaxStackArgAlign = MaxStackArgAlign; 213*0b57cec5SDimitry Andric unsigned NumLocs = Locs.size(); 214*0b57cec5SDimitry Andric 215*0b57cec5SDimitry Andric // Set the 'inreg' flag if it is used for this calling convention. 216*0b57cec5SDimitry Andric ISD::ArgFlagsTy Flags; 217*0b57cec5SDimitry Andric if (isValueTypeInRegForCC(CallingConv, VT)) 218*0b57cec5SDimitry Andric Flags.setInReg(); 219*0b57cec5SDimitry Andric 220*0b57cec5SDimitry Andric // Allocate something of this value type repeatedly until we get assigned a 221*0b57cec5SDimitry Andric // location in memory. 222*0b57cec5SDimitry Andric bool HaveRegParm = true; 223*0b57cec5SDimitry Andric while (HaveRegParm) { 224*0b57cec5SDimitry Andric if (Fn(0, VT, VT, CCValAssign::Full, Flags, *this)) { 225*0b57cec5SDimitry Andric #ifndef NDEBUG 226*0b57cec5SDimitry Andric dbgs() << "Call has unhandled type " << EVT(VT).getEVTString() 227*0b57cec5SDimitry Andric << " while computing remaining regparms\n"; 228*0b57cec5SDimitry Andric #endif 229*0b57cec5SDimitry Andric llvm_unreachable(nullptr); 230*0b57cec5SDimitry Andric } 231*0b57cec5SDimitry Andric HaveRegParm = Locs.back().isRegLoc(); 232*0b57cec5SDimitry Andric } 233*0b57cec5SDimitry Andric 234*0b57cec5SDimitry Andric // Copy all the registers from the value locations we added. 235*0b57cec5SDimitry Andric assert(NumLocs < Locs.size() && "CC assignment failed to add location"); 236*0b57cec5SDimitry Andric for (unsigned I = NumLocs, E = Locs.size(); I != E; ++I) 237*0b57cec5SDimitry Andric if (Locs[I].isRegLoc()) 238*0b57cec5SDimitry Andric Regs.push_back(MCPhysReg(Locs[I].getLocReg())); 239*0b57cec5SDimitry Andric 240*0b57cec5SDimitry Andric // Clear the assigned values and stack memory. We leave the registers marked 241*0b57cec5SDimitry Andric // as allocated so that future queries don't return the same registers, i.e. 242*0b57cec5SDimitry Andric // when i64 and f64 are both passed in GPRs. 243*0b57cec5SDimitry Andric StackOffset = SavedStackOffset; 244*0b57cec5SDimitry Andric MaxStackArgAlign = SavedMaxStackArgAlign; 245*0b57cec5SDimitry Andric Locs.resize(NumLocs); 246*0b57cec5SDimitry Andric } 247*0b57cec5SDimitry Andric 248*0b57cec5SDimitry Andric void CCState::analyzeMustTailForwardedRegisters( 249*0b57cec5SDimitry Andric SmallVectorImpl<ForwardedRegister> &Forwards, ArrayRef<MVT> RegParmTypes, 250*0b57cec5SDimitry Andric CCAssignFn Fn) { 251*0b57cec5SDimitry Andric // Oftentimes calling conventions will not user register parameters for 252*0b57cec5SDimitry Andric // variadic functions, so we need to assume we're not variadic so that we get 253*0b57cec5SDimitry Andric // all the registers that might be used in a non-variadic call. 254*0b57cec5SDimitry Andric SaveAndRestore<bool> SavedVarArg(IsVarArg, false); 255*0b57cec5SDimitry Andric SaveAndRestore<bool> SavedMustTail(AnalyzingMustTailForwardedRegs, true); 256*0b57cec5SDimitry Andric 257*0b57cec5SDimitry Andric for (MVT RegVT : RegParmTypes) { 258*0b57cec5SDimitry Andric SmallVector<MCPhysReg, 8> RemainingRegs; 259*0b57cec5SDimitry Andric getRemainingRegParmsForType(RemainingRegs, RegVT, Fn); 260*0b57cec5SDimitry Andric const TargetLowering *TL = MF.getSubtarget().getTargetLowering(); 261*0b57cec5SDimitry Andric const TargetRegisterClass *RC = TL->getRegClassFor(RegVT); 262*0b57cec5SDimitry Andric for (MCPhysReg PReg : RemainingRegs) { 263*0b57cec5SDimitry Andric unsigned VReg = MF.addLiveIn(PReg, RC); 264*0b57cec5SDimitry Andric Forwards.push_back(ForwardedRegister(VReg, PReg, RegVT)); 265*0b57cec5SDimitry Andric } 266*0b57cec5SDimitry Andric } 267*0b57cec5SDimitry Andric } 268*0b57cec5SDimitry Andric 269*0b57cec5SDimitry Andric bool CCState::resultsCompatible(CallingConv::ID CalleeCC, 270*0b57cec5SDimitry Andric CallingConv::ID CallerCC, MachineFunction &MF, 271*0b57cec5SDimitry Andric LLVMContext &C, 272*0b57cec5SDimitry Andric const SmallVectorImpl<ISD::InputArg> &Ins, 273*0b57cec5SDimitry Andric CCAssignFn CalleeFn, CCAssignFn CallerFn) { 274*0b57cec5SDimitry Andric if (CalleeCC == CallerCC) 275*0b57cec5SDimitry Andric return true; 276*0b57cec5SDimitry Andric SmallVector<CCValAssign, 4> RVLocs1; 277*0b57cec5SDimitry Andric CCState CCInfo1(CalleeCC, false, MF, RVLocs1, C); 278*0b57cec5SDimitry Andric CCInfo1.AnalyzeCallResult(Ins, CalleeFn); 279*0b57cec5SDimitry Andric 280*0b57cec5SDimitry Andric SmallVector<CCValAssign, 4> RVLocs2; 281*0b57cec5SDimitry Andric CCState CCInfo2(CallerCC, false, MF, RVLocs2, C); 282*0b57cec5SDimitry Andric CCInfo2.AnalyzeCallResult(Ins, CallerFn); 283*0b57cec5SDimitry Andric 284*0b57cec5SDimitry Andric if (RVLocs1.size() != RVLocs2.size()) 285*0b57cec5SDimitry Andric return false; 286*0b57cec5SDimitry Andric for (unsigned I = 0, E = RVLocs1.size(); I != E; ++I) { 287*0b57cec5SDimitry Andric const CCValAssign &Loc1 = RVLocs1[I]; 288*0b57cec5SDimitry Andric const CCValAssign &Loc2 = RVLocs2[I]; 289*0b57cec5SDimitry Andric if (Loc1.getLocInfo() != Loc2.getLocInfo()) 290*0b57cec5SDimitry Andric return false; 291*0b57cec5SDimitry Andric bool RegLoc1 = Loc1.isRegLoc(); 292*0b57cec5SDimitry Andric if (RegLoc1 != Loc2.isRegLoc()) 293*0b57cec5SDimitry Andric return false; 294*0b57cec5SDimitry Andric if (RegLoc1) { 295*0b57cec5SDimitry Andric if (Loc1.getLocReg() != Loc2.getLocReg()) 296*0b57cec5SDimitry Andric return false; 297*0b57cec5SDimitry Andric } else { 298*0b57cec5SDimitry Andric if (Loc1.getLocMemOffset() != Loc2.getLocMemOffset()) 299*0b57cec5SDimitry Andric return false; 300*0b57cec5SDimitry Andric } 301*0b57cec5SDimitry Andric } 302*0b57cec5SDimitry Andric return true; 303*0b57cec5SDimitry Andric } 304