Index: include/llvm/Target/TargetCallingConv.td =================================================================== --- include/llvm/Target/TargetCallingConv.td +++ include/llvm/Target/TargetCallingConv.td @@ -67,6 +67,9 @@ /// the specified action. class CCIfSRet : CCIf<"ArgFlags.isSRet()", A> {} +/// CCIfVarArg - If the current function is vararg - apply the action +class CCIfVarArg : CCIf<"State.isVarArg()", A> {} + /// CCIfNotVarArg - If the current function is not vararg - apply the action class CCIfNotVarArg : CCIf<"!State.isVarArg()", A> {} Index: lib/Target/Mips/MipsCallingConv.td =================================================================== --- lib/Target/Mips/MipsCallingConv.td +++ lib/Target/Mips/MipsCallingConv.td @@ -343,6 +343,13 @@ CCDelegateTo ]>; +def CC_Mips : CallingConv<[ + CCIfVarArg< + CCIf<"!static_cast(&State)->IsCallOperandFixed(ValNo)", + CCDelegateTo>>, + CCDelegateTo +]>; + //===----------------------------------------------------------------------===// // Callee-saved register lists. //===----------------------------------------------------------------------===// Index: lib/Target/Mips/MipsISelLowering.h =================================================================== --- lib/Target/Mips/MipsISelLowering.h +++ lib/Target/Mips/MipsISelLowering.h @@ -348,10 +348,6 @@ MipsCC(CallingConv::ID CallConv, const MipsSubtarget &Subtarget, CCState &Info); - void analyzeCallOperands(const SmallVectorImpl &Outs, - std::vector &FuncArgs, - CCState &State); - /// reservedArgArea - The size of the area the caller reserves for /// register arguments. This is 16-byte if ABI is O32. unsigned reservedArgArea() const; Index: lib/Target/Mips/MipsISelLowering.cpp =================================================================== --- lib/Target/Mips/MipsISelLowering.cpp +++ lib/Target/Mips/MipsISelLowering.cpp @@ -118,12 +118,15 @@ /// Identify lowered values that originated from f128 arguments and record /// this. - void PreAnalyzeCallOperandsForF128( + void PreAnalyzeCallOperands( const SmallVectorImpl &Outs, - std::vector &FuncArgs, SDNode *CallNode) { - for (unsigned i = 0; i < Outs.size(); ++i) + std::vector &FuncArgs, + const SDNode *CallNode) { + for (unsigned i = 0; i < Outs.size(); ++i) { OriginalArgWasF128.push_back( originalTypeIsF128(FuncArgs[Outs[i].OrigArgIndex].Ty, CallNode)); + CallOperandIsFixed.push_back(Outs[i].IsFixed); + } } /// Identify lowered values that originated from f128 arguments and record @@ -152,27 +155,41 @@ /// Records whether the value has been lowered from an f128. SmallVector OriginalArgWasF128; + /// Records whether the value was a fixed argument. + /// See ISD::OutputArg::IsFixed, + SmallVector CallOperandIsFixed; + // Used to handle MIPS16-specific calling convention tweaks. // FIXME: This should probably be a fully fledged calling convention. SpecialCallingConvType SpecialCallingConv; public: - // FIXME: Remove this from a public inteface ASAP. It's a temporary trap door - // to allow analyzeCallOperands to be removed incrementally. - void PreAnalyzeCallOperandsForF128_( - const SmallVectorImpl &Outs, - std::vector &FuncArgs, SDNode *CallNode) { - PreAnalyzeCallOperandsForF128(Outs, FuncArgs, CallNode); - } - // FIXME: Remove this from a public inteface ASAP. It's a temporary trap door - // to clean up after the above functions. - void ClearOriginalArgWasF128() { OriginalArgWasF128.clear(); } MipsCCState(CallingConv::ID CC, bool isVarArg, MachineFunction &MF, SmallVectorImpl &locs, LLVMContext &C, SpecialCallingConvType SpecialCC = NoSpecialCallingConv) : CCState(CC, isVarArg, MF, locs, C), SpecialCallingConv(SpecialCC) {} + void + AnalyzeCallOperands(const SmallVectorImpl &Outs, + CCAssignFn Fn, + std::vector &FuncArgs, + const SDNode *CallNode) { + PreAnalyzeCallOperands(Outs, FuncArgs, CallNode); + CCState::AnalyzeCallOperands(Outs, Fn); + OriginalArgWasF128.clear(); + CallOperandIsFixed.clear(); + } + + // The AnalyzeCallOperands in the base class is not usable since we must + // provide a means of accessing ArgListEntry::IsFixed. Delete them from this + // class. This doesn't stop them being used via the base class though. + void AnalyzeCallOperands(const SmallVectorImpl &Outs, + CCAssignFn Fn) = delete; + void AnalyzeCallOperands(const SmallVectorImpl &Outs, + SmallVectorImpl &Flags, + CCAssignFn Fn) = delete; + void AnalyzeFormalArguments(const SmallVectorImpl &Ins, CCAssignFn Fn) { PreAnalyzeFormalArgumentsForF128(Ins); @@ -204,6 +221,7 @@ } bool WasOriginalArgF128(unsigned ValNo) { return OriginalArgWasF128[ValNo]; } + bool IsCallOperandFixed(unsigned ValNo) { return CallOperandIsFixed[ValNo]; } SpecialCallingConvType getSpecialCallingConv() { return SpecialCallingConv; } }; } @@ -2629,9 +2647,7 @@ MipsCCState::getSpecialCallingConvForCallee(Callee.getNode(), Subtarget)); MipsCC MipsCCInfo(CallConv, Subtarget, CCInfo); - CCInfo.PreAnalyzeCallOperandsForF128_(Outs, CLI.getArgs(), Callee.getNode()); - MipsCCInfo.analyzeCallOperands(Outs, CLI.getArgs(), CCInfo); - CCInfo.ClearOriginalArgWasF128(); + CCInfo.AnalyzeCallOperands(Outs, CC_Mips, CLI.getArgs(), Callee.getNode()); // Get a count of how many bytes are to be pushed on the stack. unsigned NextStackOffset = CCInfo.getNextStackOffset(); @@ -3617,34 +3633,6 @@ Info.AllocateStack(reservedArgArea(), 1); } -void MipsTargetLowering::MipsCC::analyzeCallOperands( - const SmallVectorImpl &Args, - std::vector &FuncArgs, CCState &State) { - assert((CallConv != CallingConv::Fast || !State.isVarArg()) && - "CallingConv::Fast shouldn't be used for vararg functions."); - - unsigned NumOpnds = Args.size(); - - for (unsigned I = 0; I != NumOpnds; ++I) { - MVT ArgVT = Args[I].VT; - ISD::ArgFlagsTy ArgFlags = Args[I].Flags; - bool R; - - if (State.isVarArg() && !Args[I].IsFixed) - R = CC_Mips_VarArg(I, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, State); - else - R = CC_Mips_FixedArg(I, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, State); - - if (R) { -#ifndef NDEBUG - dbgs() << "Call operand #" << I << " has unhandled type " - << EVT(ArgVT).getEVTString(); -#endif - llvm_unreachable(nullptr); - } - } -} - unsigned MipsTargetLowering::MipsCC::reservedArgArea() const { return (Subtarget.isABI_O32() && (CallConv != CallingConv::Fast)) ? 16 : 0; }