1498e5f89SDan Gohman //===-- CallingConvLower.cpp - Calling Conventions ------------------------===// 2498e5f89SDan Gohman // 3498e5f89SDan Gohman // The LLVM Compiler Infrastructure 4498e5f89SDan Gohman // 5498e5f89SDan Gohman // This file is distributed under the University of Illinois Open Source 6498e5f89SDan Gohman // License. See LICENSE.TXT for details. 7498e5f89SDan Gohman // 8498e5f89SDan Gohman //===----------------------------------------------------------------------===// 9498e5f89SDan Gohman // 10498e5f89SDan Gohman // This file implements the CCState class, used for lowering and implementing 11498e5f89SDan Gohman // calling conventions. 12498e5f89SDan Gohman // 13498e5f89SDan Gohman //===----------------------------------------------------------------------===// 14498e5f89SDan Gohman 15498e5f89SDan Gohman #include "llvm/CodeGen/CallingConvLower.h" 160713a9d8SEric Christopher #include "llvm/CodeGen/MachineFrameInfo.h" 17ce009334SReid Kleckner #include "llvm/CodeGen/MachineRegisterInfo.h" 18*b3bde2eaSDavid Blaikie #include "llvm/CodeGen/TargetLowering.h" 19*b3bde2eaSDavid Blaikie #include "llvm/CodeGen/TargetRegisterInfo.h" 20*b3bde2eaSDavid Blaikie #include "llvm/CodeGen/TargetSubtargetInfo.h" 219fb823bbSChandler Carruth #include "llvm/IR/DataLayout.h" 22498e5f89SDan Gohman #include "llvm/Support/Debug.h" 23498e5f89SDan Gohman #include "llvm/Support/ErrorHandling.h" 24ce009334SReid Kleckner #include "llvm/Support/SaveAndRestore.h" 25498e5f89SDan Gohman #include "llvm/Support/raw_ostream.h" 263b951570SOren Ben Simhon #include <algorithm> 273b951570SOren Ben Simhon 28498e5f89SDan Gohman using namespace llvm; 29498e5f89SDan Gohman 300713a9d8SEric Christopher CCState::CCState(CallingConv::ID CC, bool isVarArg, MachineFunction &mf, 31b5217507SEric Christopher SmallVectorImpl<CCValAssign> &locs, LLVMContext &C) 32b5217507SEric Christopher : CallingConv(CC), IsVarArg(isVarArg), MF(mf), 33c35139ecSReid Kleckner TRI(*MF.getSubtarget().getRegisterInfo()), Locs(locs), Context(C) { 34498e5f89SDan Gohman // No stack is used. 35498e5f89SDan Gohman StackOffset = 0; 36740f9d79SJeroen Ketema MaxStackArgAlign = 1; 37498e5f89SDan Gohman 388c02c982SStepan Dyatkovskiy clearByValRegsInfo(); 39498e5f89SDan Gohman UsedRegs.resize((TRI.getNumRegs()+31)/32); 40498e5f89SDan Gohman } 41498e5f89SDan Gohman 428b2150efSSanjay Patel /// Allocate space on the stack large enough to pass an argument by value. 438b2150efSSanjay Patel /// The size and alignment information of the argument is encoded in 448b2150efSSanjay Patel /// its parameter attribute. 4571049f78SDuncan Sands void CCState::HandleByVal(unsigned ValNo, MVT ValVT, 46f5dda01fSDuncan Sands MVT LocVT, CCValAssign::LocInfo LocInfo, 47498e5f89SDan Gohman int MinSize, int MinAlign, 48498e5f89SDan Gohman ISD::ArgFlagsTy ArgFlags) { 49498e5f89SDan Gohman unsigned Align = ArgFlags.getByValAlign(); 50498e5f89SDan Gohman unsigned Size = ArgFlags.getByValSize(); 51498e5f89SDan Gohman if (MinSize > (int)Size) 52498e5f89SDan Gohman Size = MinSize; 53498e5f89SDan Gohman if (MinAlign > (int)Align) 54498e5f89SDan Gohman Align = MinAlign; 5518ec96f0SReid Kleckner ensureMaxAlignment(Align); 56b5217507SEric Christopher MF.getSubtarget().getTargetLowering()->HandleByVal(this, Size, Align); 57da00f2fdSRui Ueyama Size = unsigned(alignTo(Size, MinAlign)); 58498e5f89SDan Gohman unsigned Offset = AllocateStack(Size, Align); 59498e5f89SDan Gohman addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo)); 60498e5f89SDan Gohman } 61498e5f89SDan Gohman 628b2150efSSanjay Patel /// Mark a register and all of its aliases as allocated. 63498e5f89SDan Gohman void CCState::MarkAllocated(unsigned Reg) { 6454038d79SJakob Stoklund Olesen for (MCRegAliasIterator AI(Reg, &TRI, true); AI.isValid(); ++AI) 6554038d79SJakob Stoklund Olesen UsedRegs[*AI/32] |= 1 << (*AI&31); 66498e5f89SDan Gohman } 67498e5f89SDan Gohman 683b951570SOren Ben Simhon bool CCState::IsShadowAllocatedReg(unsigned Reg) const { 693b951570SOren Ben Simhon if (!isAllocated(Reg)) 703b951570SOren Ben Simhon return false; 713b951570SOren Ben Simhon 723b951570SOren Ben Simhon for (auto const &ValAssign : Locs) { 733b951570SOren Ben Simhon if (ValAssign.isRegLoc()) { 743b951570SOren Ben Simhon for (MCRegAliasIterator AI(ValAssign.getLocReg(), &TRI, true); 753b951570SOren Ben Simhon AI.isValid(); ++AI) { 763b951570SOren Ben Simhon if (*AI == Reg) 773b951570SOren Ben Simhon return false; 783b951570SOren Ben Simhon } 793b951570SOren Ben Simhon } 803b951570SOren Ben Simhon } 813b951570SOren Ben Simhon return true; 823b951570SOren Ben Simhon } 833b951570SOren Ben Simhon 848b2150efSSanjay Patel /// Analyze an array of argument values, 85498e5f89SDan Gohman /// incorporating info about the formals into this state. 86498e5f89SDan Gohman void 87498e5f89SDan Gohman CCState::AnalyzeFormalArguments(const SmallVectorImpl<ISD::InputArg> &Ins, 88498e5f89SDan Gohman CCAssignFn Fn) { 89498e5f89SDan Gohman unsigned NumArgs = Ins.size(); 90498e5f89SDan Gohman 91498e5f89SDan Gohman for (unsigned i = 0; i != NumArgs; ++i) { 92f5dda01fSDuncan Sands MVT ArgVT = Ins[i].VT; 93498e5f89SDan Gohman ISD::ArgFlagsTy ArgFlags = Ins[i].Flags; 94498e5f89SDan Gohman if (Fn(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, *this)) { 95498e5f89SDan Gohman #ifndef NDEBUG 96498e5f89SDan Gohman dbgs() << "Formal argument #" << i << " has unhandled type " 9704a5cc39SCraig Topper << EVT(ArgVT).getEVTString() << '\n'; 98498e5f89SDan Gohman #endif 99c0196b1bSCraig Topper llvm_unreachable(nullptr); 100498e5f89SDan Gohman } 101498e5f89SDan Gohman } 102498e5f89SDan Gohman } 103498e5f89SDan Gohman 1048b2150efSSanjay Patel /// Analyze the return values of a function, returning true if the return can 1058b2150efSSanjay Patel /// be performed without sret-demotion and false otherwise. 106d7b5ce33SDan Gohman bool CCState::CheckReturn(const SmallVectorImpl<ISD::OutputArg> &Outs, 107498e5f89SDan Gohman CCAssignFn Fn) { 108498e5f89SDan Gohman // Determine which register each value should be copied into. 109d7b5ce33SDan Gohman for (unsigned i = 0, e = Outs.size(); i != e; ++i) { 110f5dda01fSDuncan Sands MVT VT = Outs[i].VT; 111d7b5ce33SDan Gohman ISD::ArgFlagsTy ArgFlags = Outs[i].Flags; 112498e5f89SDan Gohman if (Fn(i, VT, VT, CCValAssign::Full, ArgFlags, *this)) 113498e5f89SDan Gohman return false; 114498e5f89SDan Gohman } 115498e5f89SDan Gohman return true; 116498e5f89SDan Gohman } 117498e5f89SDan Gohman 1188b2150efSSanjay Patel /// Analyze the returned values of a return, 119498e5f89SDan Gohman /// incorporating info about the result values into this state. 120498e5f89SDan Gohman void CCState::AnalyzeReturn(const SmallVectorImpl<ISD::OutputArg> &Outs, 121498e5f89SDan Gohman CCAssignFn Fn) { 122498e5f89SDan Gohman // Determine which register each value should be copied into. 123498e5f89SDan Gohman for (unsigned i = 0, e = Outs.size(); i != e; ++i) { 124f5dda01fSDuncan Sands MVT VT = Outs[i].VT; 125498e5f89SDan Gohman ISD::ArgFlagsTy ArgFlags = Outs[i].Flags; 126498e5f89SDan Gohman if (Fn(i, VT, VT, CCValAssign::Full, ArgFlags, *this)) { 127498e5f89SDan Gohman #ifndef NDEBUG 128498e5f89SDan Gohman dbgs() << "Return operand #" << i << " has unhandled type " 12904a5cc39SCraig Topper << EVT(VT).getEVTString() << '\n'; 130498e5f89SDan Gohman #endif 131c0196b1bSCraig Topper llvm_unreachable(nullptr); 132498e5f89SDan Gohman } 133498e5f89SDan Gohman } 134498e5f89SDan Gohman } 135498e5f89SDan Gohman 1368b2150efSSanjay Patel /// Analyze the outgoing arguments to a call, 137498e5f89SDan Gohman /// incorporating info about the passed values into this state. 138498e5f89SDan Gohman void CCState::AnalyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Outs, 139498e5f89SDan Gohman CCAssignFn Fn) { 140498e5f89SDan Gohman unsigned NumOps = Outs.size(); 141498e5f89SDan Gohman for (unsigned i = 0; i != NumOps; ++i) { 142f5dda01fSDuncan Sands MVT ArgVT = Outs[i].VT; 143498e5f89SDan Gohman ISD::ArgFlagsTy ArgFlags = Outs[i].Flags; 144498e5f89SDan Gohman if (Fn(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, *this)) { 145498e5f89SDan Gohman #ifndef NDEBUG 146498e5f89SDan Gohman dbgs() << "Call operand #" << i << " has unhandled type " 14704a5cc39SCraig Topper << EVT(ArgVT).getEVTString() << '\n'; 148498e5f89SDan Gohman #endif 149c0196b1bSCraig Topper llvm_unreachable(nullptr); 150498e5f89SDan Gohman } 151498e5f89SDan Gohman } 152498e5f89SDan Gohman } 153498e5f89SDan Gohman 1548b2150efSSanjay Patel /// Same as above except it takes vectors of types and argument flags. 155f5dda01fSDuncan Sands void CCState::AnalyzeCallOperands(SmallVectorImpl<MVT> &ArgVTs, 156498e5f89SDan Gohman SmallVectorImpl<ISD::ArgFlagsTy> &Flags, 157498e5f89SDan Gohman CCAssignFn Fn) { 158498e5f89SDan Gohman unsigned NumOps = ArgVTs.size(); 159498e5f89SDan Gohman for (unsigned i = 0; i != NumOps; ++i) { 160f5dda01fSDuncan Sands MVT ArgVT = ArgVTs[i]; 161498e5f89SDan Gohman ISD::ArgFlagsTy ArgFlags = Flags[i]; 162498e5f89SDan Gohman if (Fn(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, *this)) { 163498e5f89SDan Gohman #ifndef NDEBUG 164498e5f89SDan Gohman dbgs() << "Call operand #" << i << " has unhandled type " 16504a5cc39SCraig Topper << EVT(ArgVT).getEVTString() << '\n'; 166498e5f89SDan Gohman #endif 167c0196b1bSCraig Topper llvm_unreachable(nullptr); 168498e5f89SDan Gohman } 169498e5f89SDan Gohman } 170498e5f89SDan Gohman } 171498e5f89SDan Gohman 1728b2150efSSanjay Patel /// Analyze the return values of a call, incorporating info about the passed 1738b2150efSSanjay Patel /// values into this state. 174498e5f89SDan Gohman void CCState::AnalyzeCallResult(const SmallVectorImpl<ISD::InputArg> &Ins, 175498e5f89SDan Gohman CCAssignFn Fn) { 176498e5f89SDan Gohman for (unsigned i = 0, e = Ins.size(); i != e; ++i) { 177f5dda01fSDuncan Sands MVT VT = Ins[i].VT; 178498e5f89SDan Gohman ISD::ArgFlagsTy Flags = Ins[i].Flags; 179498e5f89SDan Gohman if (Fn(i, VT, VT, CCValAssign::Full, Flags, *this)) { 180498e5f89SDan Gohman #ifndef NDEBUG 181498e5f89SDan Gohman dbgs() << "Call result #" << i << " has unhandled type " 18204a5cc39SCraig Topper << EVT(VT).getEVTString() << '\n'; 183498e5f89SDan Gohman #endif 184c0196b1bSCraig Topper llvm_unreachable(nullptr); 185498e5f89SDan Gohman } 186498e5f89SDan Gohman } 187498e5f89SDan Gohman } 188498e5f89SDan Gohman 1898b2150efSSanjay Patel /// Same as above except it's specialized for calls that produce a single value. 190f5dda01fSDuncan Sands void CCState::AnalyzeCallResult(MVT VT, CCAssignFn Fn) { 191498e5f89SDan Gohman if (Fn(0, VT, VT, CCValAssign::Full, ISD::ArgFlagsTy(), *this)) { 192498e5f89SDan Gohman #ifndef NDEBUG 193498e5f89SDan Gohman dbgs() << "Call result has unhandled type " 19404a5cc39SCraig Topper << EVT(VT).getEVTString() << '\n'; 195498e5f89SDan Gohman #endif 196c0196b1bSCraig Topper llvm_unreachable(nullptr); 197498e5f89SDan Gohman } 198498e5f89SDan Gohman } 199ce009334SReid Kleckner 200bba20f06SReid Kleckner static bool isValueTypeInRegForCC(CallingConv::ID CC, MVT VT) { 201bba20f06SReid Kleckner if (VT.isVector()) 202bba20f06SReid Kleckner return true; // Assume -msse-regparm might be in effect. 203bba20f06SReid Kleckner if (!VT.isInteger()) 204bba20f06SReid Kleckner return false; 205bba20f06SReid Kleckner if (CC == CallingConv::X86_VectorCall || CC == CallingConv::X86_FastCall) 206bba20f06SReid Kleckner return true; 207bba20f06SReid Kleckner return false; 208bba20f06SReid Kleckner } 209bba20f06SReid Kleckner 210ce009334SReid Kleckner void CCState::getRemainingRegParmsForType(SmallVectorImpl<MCPhysReg> &Regs, 211ce009334SReid Kleckner MVT VT, CCAssignFn Fn) { 212ce009334SReid Kleckner unsigned SavedStackOffset = StackOffset; 213740f9d79SJeroen Ketema unsigned SavedMaxStackArgAlign = MaxStackArgAlign; 214ce009334SReid Kleckner unsigned NumLocs = Locs.size(); 215ce009334SReid Kleckner 216bba20f06SReid Kleckner // Set the 'inreg' flag if it is used for this calling convention. 217ce009334SReid Kleckner ISD::ArgFlagsTy Flags; 218bba20f06SReid Kleckner if (isValueTypeInRegForCC(CallingConv, VT)) 219ce009334SReid Kleckner Flags.setInReg(); 220bba20f06SReid Kleckner 221bba20f06SReid Kleckner // Allocate something of this value type repeatedly until we get assigned a 222bba20f06SReid Kleckner // location in memory. 223ce009334SReid Kleckner bool HaveRegParm = true; 224ce009334SReid Kleckner while (HaveRegParm) { 225ce009334SReid Kleckner if (Fn(0, VT, VT, CCValAssign::Full, Flags, *this)) { 226ce009334SReid Kleckner #ifndef NDEBUG 227ce009334SReid Kleckner dbgs() << "Call has unhandled type " << EVT(VT).getEVTString() 228ce009334SReid Kleckner << " while computing remaining regparms\n"; 229ce009334SReid Kleckner #endif 230ce009334SReid Kleckner llvm_unreachable(nullptr); 231ce009334SReid Kleckner } 232ce009334SReid Kleckner HaveRegParm = Locs.back().isRegLoc(); 233ce009334SReid Kleckner } 234ce009334SReid Kleckner 235ce009334SReid Kleckner // Copy all the registers from the value locations we added. 236ce009334SReid Kleckner assert(NumLocs < Locs.size() && "CC assignment failed to add location"); 237ce009334SReid Kleckner for (unsigned I = NumLocs, E = Locs.size(); I != E; ++I) 238ce009334SReid Kleckner if (Locs[I].isRegLoc()) 239ce009334SReid Kleckner Regs.push_back(MCPhysReg(Locs[I].getLocReg())); 240ce009334SReid Kleckner 241ce009334SReid Kleckner // Clear the assigned values and stack memory. We leave the registers marked 242ce009334SReid Kleckner // as allocated so that future queries don't return the same registers, i.e. 243ce009334SReid Kleckner // when i64 and f64 are both passed in GPRs. 244ce009334SReid Kleckner StackOffset = SavedStackOffset; 245740f9d79SJeroen Ketema MaxStackArgAlign = SavedMaxStackArgAlign; 246ce009334SReid Kleckner Locs.resize(NumLocs); 247ce009334SReid Kleckner } 248ce009334SReid Kleckner 249ce009334SReid Kleckner void CCState::analyzeMustTailForwardedRegisters( 250ce009334SReid Kleckner SmallVectorImpl<ForwardedRegister> &Forwards, ArrayRef<MVT> RegParmTypes, 251ce009334SReid Kleckner CCAssignFn Fn) { 252ce009334SReid Kleckner // Oftentimes calling conventions will not user register parameters for 253ce009334SReid Kleckner // variadic functions, so we need to assume we're not variadic so that we get 254ce009334SReid Kleckner // all the registers that might be used in a non-variadic call. 255ce009334SReid Kleckner SaveAndRestore<bool> SavedVarArg(IsVarArg, false); 25618ec96f0SReid Kleckner SaveAndRestore<bool> SavedMustTail(AnalyzingMustTailForwardedRegs, true); 257ce009334SReid Kleckner 258ce009334SReid Kleckner for (MVT RegVT : RegParmTypes) { 259ce009334SReid Kleckner SmallVector<MCPhysReg, 8> RemainingRegs; 260ce009334SReid Kleckner getRemainingRegParmsForType(RemainingRegs, RegVT, Fn); 261ce009334SReid Kleckner const TargetLowering *TL = MF.getSubtarget().getTargetLowering(); 262ce009334SReid Kleckner const TargetRegisterClass *RC = TL->getRegClassFor(RegVT); 263ce009334SReid Kleckner for (MCPhysReg PReg : RemainingRegs) { 264ce009334SReid Kleckner unsigned VReg = MF.addLiveIn(PReg, RC); 265ce009334SReid Kleckner Forwards.push_back(ForwardedRegister(VReg, PReg, RegVT)); 266ce009334SReid Kleckner } 267ce009334SReid Kleckner } 268ce009334SReid Kleckner } 2698d414360SMatthias Braun 2708d414360SMatthias Braun bool CCState::resultsCompatible(CallingConv::ID CalleeCC, 2718d414360SMatthias Braun CallingConv::ID CallerCC, MachineFunction &MF, 2728d414360SMatthias Braun LLVMContext &C, 2738d414360SMatthias Braun const SmallVectorImpl<ISD::InputArg> &Ins, 2748d414360SMatthias Braun CCAssignFn CalleeFn, CCAssignFn CallerFn) { 2758d414360SMatthias Braun if (CalleeCC == CallerCC) 2768d414360SMatthias Braun return true; 2778d414360SMatthias Braun SmallVector<CCValAssign, 4> RVLocs1; 2788d414360SMatthias Braun CCState CCInfo1(CalleeCC, false, MF, RVLocs1, C); 2798d414360SMatthias Braun CCInfo1.AnalyzeCallResult(Ins, CalleeFn); 2808d414360SMatthias Braun 2818d414360SMatthias Braun SmallVector<CCValAssign, 4> RVLocs2; 2828d414360SMatthias Braun CCState CCInfo2(CallerCC, false, MF, RVLocs2, C); 2838d414360SMatthias Braun CCInfo2.AnalyzeCallResult(Ins, CallerFn); 2848d414360SMatthias Braun 2858d414360SMatthias Braun if (RVLocs1.size() != RVLocs2.size()) 2868d414360SMatthias Braun return false; 2878d414360SMatthias Braun for (unsigned I = 0, E = RVLocs1.size(); I != E; ++I) { 2888d414360SMatthias Braun const CCValAssign &Loc1 = RVLocs1[I]; 2898d414360SMatthias Braun const CCValAssign &Loc2 = RVLocs2[I]; 2908d414360SMatthias Braun if (Loc1.getLocInfo() != Loc2.getLocInfo()) 2918d414360SMatthias Braun return false; 2928d414360SMatthias Braun bool RegLoc1 = Loc1.isRegLoc(); 2938d414360SMatthias Braun if (RegLoc1 != Loc2.isRegLoc()) 2948d414360SMatthias Braun return false; 2958d414360SMatthias Braun if (RegLoc1) { 2968d414360SMatthias Braun if (Loc1.getLocReg() != Loc2.getLocReg()) 2978d414360SMatthias Braun return false; 2988d414360SMatthias Braun } else { 2998d414360SMatthias Braun if (Loc1.getLocMemOffset() != Loc2.getLocMemOffset()) 3008d414360SMatthias Braun return false; 3018d414360SMatthias Braun } 3028d414360SMatthias Braun } 3038d414360SMatthias Braun return true; 3048d414360SMatthias Braun } 305