diff options
author | Daniel Sanders <daniel.sanders@imgtec.com> | 2014-11-01 19:17:10 +0000 |
---|---|---|
committer | Daniel Sanders <daniel.sanders@imgtec.com> | 2014-11-01 19:17:10 +0000 |
commit | ea8769cbe874dbbd5887512ea6d44a25e69ec148 (patch) | |
tree | 58e2c6c2b40d52fb35f070cd0a5d8816db273659 /lib/Target | |
parent | 73d60e69f4e84d4f2399c73f5414fe2300e1ce02 (diff) |
[mips] Move all ByVal handling into CCState and tablegen-erated code. NFC.
Summary:
CCState already contains a byval implementation that is very similar to the
Mips custom code. This patch merges the custom code into the existing
common code and tablegen-erated code.
Reviewers: vmedic
Reviewed By: vmedic
Subscribers: rnk, llvm-commits
Differential Revision: http://reviews.llvm.org/D5977
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@221059 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target')
-rw-r--r-- | lib/Target/Mips/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lib/Target/Mips/Mips16ISelLowering.cpp | 7 | ||||
-rw-r--r-- | lib/Target/Mips/Mips16ISelLowering.h | 6 | ||||
-rw-r--r-- | lib/Target/Mips/MipsABIInfo.cpp | 29 | ||||
-rw-r--r-- | lib/Target/Mips/MipsABIInfo.h | 6 | ||||
-rw-r--r-- | lib/Target/Mips/MipsCallingConv.td | 25 | ||||
-rw-r--r-- | lib/Target/Mips/MipsISelLowering.cpp | 176 | ||||
-rw-r--r-- | lib/Target/Mips/MipsISelLowering.h | 40 | ||||
-rw-r--r-- | lib/Target/Mips/MipsSEISelLowering.cpp | 9 | ||||
-rw-r--r-- | lib/Target/Mips/MipsSEISelLowering.h | 6 |
10 files changed, 157 insertions, 148 deletions
diff --git a/lib/Target/Mips/CMakeLists.txt b/lib/Target/Mips/CMakeLists.txt index 6028db68507..c109b34df51 100644 --- a/lib/Target/Mips/CMakeLists.txt +++ b/lib/Target/Mips/CMakeLists.txt @@ -21,6 +21,7 @@ add_llvm_target(MipsCodeGen Mips16ISelDAGToDAG.cpp Mips16ISelLowering.cpp Mips16RegisterInfo.cpp + MipsABIInfo.cpp MipsAnalyzeImmediate.cpp MipsAsmPrinter.cpp MipsConstantIslandPass.cpp diff --git a/lib/Target/Mips/Mips16ISelLowering.cpp b/lib/Target/Mips/Mips16ISelLowering.cpp index 58f2d74f36a..d4852c4ece4 100644 --- a/lib/Target/Mips/Mips16ISelLowering.cpp +++ b/lib/Target/Mips/Mips16ISelLowering.cpp @@ -244,10 +244,9 @@ Mips16TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, } } -bool Mips16TargetLowering:: -isEligibleForTailCallOptimization(const MipsCC &MipsCCInfo, - unsigned NextStackOffset, - const MipsFunctionInfo& FI) const { +bool Mips16TargetLowering::isEligibleForTailCallOptimization( + const CCState &CCInfo, unsigned NextStackOffset, + const MipsFunctionInfo &FI) const { // No tail call optimization for mips16. return false; } diff --git a/lib/Target/Mips/Mips16ISelLowering.h b/lib/Target/Mips/Mips16ISelLowering.h index 4c21a919e71..d3b9f750f34 100644 --- a/lib/Target/Mips/Mips16ISelLowering.h +++ b/lib/Target/Mips/Mips16ISelLowering.h @@ -31,9 +31,9 @@ namespace llvm { MachineBasicBlock *MBB) const override; private: - bool isEligibleForTailCallOptimization(const MipsCC &MipsCCInfo, - unsigned NextStackOffset, - const MipsFunctionInfo& FI) const override; + bool isEligibleForTailCallOptimization( + const CCState &CCInfo, unsigned NextStackOffset, + const MipsFunctionInfo &FI) const override; void setMips16HardFloatLibCalls(); diff --git a/lib/Target/Mips/MipsABIInfo.cpp b/lib/Target/Mips/MipsABIInfo.cpp new file mode 100644 index 00000000000..97e04b1d9f9 --- /dev/null +++ b/lib/Target/Mips/MipsABIInfo.cpp @@ -0,0 +1,29 @@ +//===---- MipsABIInfo.cpp - Information about MIPS ABI's ------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "MipsABIInfo.h" +#include "MipsRegisterInfo.h" + +using namespace llvm; + +namespace { +static const MCPhysReg O32IntRegs[4] = {Mips::A0, Mips::A1, Mips::A2, Mips::A3}; + +static const MCPhysReg Mips64IntRegs[8] = { + Mips::A0_64, Mips::A1_64, Mips::A2_64, Mips::A3_64, + Mips::T0_64, Mips::T1_64, Mips::T2_64, Mips::T3_64}; +} + +const ArrayRef<MCPhysReg> MipsABIInfo::GetByValArgRegs() const { + if (IsO32()) + return makeArrayRef(O32IntRegs); + if (IsN32() || IsN64()) + return makeArrayRef(Mips64IntRegs); + llvm_unreachable("Unhandled ABI"); +} diff --git a/lib/Target/Mips/MipsABIInfo.h b/lib/Target/Mips/MipsABIInfo.h index c1d90a7c4f7..778b04d9ce7 100644 --- a/lib/Target/Mips/MipsABIInfo.h +++ b/lib/Target/Mips/MipsABIInfo.h @@ -10,7 +10,11 @@ #ifndef MIPSABIINFO_H #define MIPSABIINFO_H +#include "llvm/ADT/ArrayRef.h" +#include "llvm/MC/MCRegisterInfo.h" + namespace llvm { + class MipsABIInfo { public: enum class ABI { Unknown, O32, N32, N64, EABI }; @@ -34,6 +38,8 @@ public: bool IsEABI() const { return ThisABI == ABI::EABI; } ABI GetEnumValue() const { return ThisABI; } + const ArrayRef<MCPhysReg> GetByValArgRegs() const; + /// Ordering of ABI's /// MipsGenSubtargetInfo.inc will use this to resolve conflicts when given /// multiple ABI options. diff --git a/lib/Target/Mips/MipsCallingConv.td b/lib/Target/Mips/MipsCallingConv.td index ae1b01b4019..7e5c2a902f1 100644 --- a/lib/Target/Mips/MipsCallingConv.td +++ b/lib/Target/Mips/MipsCallingConv.td @@ -279,13 +279,6 @@ def CC_Mips_FastCC : CallingConv<[ CCDelegateTo<CC_MipsN_FastCC> ]>; -//== - -def CC_Mips16RetHelper : CallingConv<[ - // Integer arguments are passed in integer registers. - CCIfType<[i32], CCAssignToReg<[V0, V1, A0, A1]>> -]>; - //===----------------------------------------------------------------------===// // Mips Calling Convention Dispatch //===----------------------------------------------------------------------===// @@ -297,7 +290,14 @@ def RetCC_Mips : CallingConv<[ CCDelegateTo<RetCC_MipsO32> ]>; +def CC_Mips_ByVal : CallingConv<[ + CCIfSubtarget<"isABI_O32()", CCIfByVal<CCPassByVal<4, 4>>>, + CCIfByVal<CCPassByVal<8, 8>> +]>; + def CC_Mips_FixedArg : CallingConv<[ + CCIfByVal<CCDelegateTo<CC_Mips_ByVal>>, + // f128 needs to be handled similarly to f32 and f64 on hard-float. However, // f128 is not legal and is lowered to i128 which is further lowered to a pair // of i64's. @@ -322,12 +322,23 @@ def CC_Mips_FixedArg : CallingConv<[ ]>; def CC_Mips_VarArg : CallingConv<[ + CCIfByVal<CCDelegateTo<CC_Mips_ByVal>>, + // FIXME: There wasn't an EABI case in the original code and it seems unlikely // that it's the same as CC_MipsN_VarArg CCIfSubtarget<"isABI_O32()", CCDelegateTo<CC_MipsO32_FP>>, CCDelegateTo<CC_MipsN_VarArg> ]>; +//== + +def CC_Mips16RetHelper : CallingConv<[ + CCIfByVal<CCDelegateTo<CC_Mips_ByVal>>, + + // Integer arguments are passed in integer registers. + CCIfType<[i32], CCAssignToReg<[V0, V1, A0, A1]>> +]>; + //===----------------------------------------------------------------------===// // Callee-saved register lists. //===----------------------------------------------------------------------===// diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index c6a6187b094..ffdaf914c5b 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -2601,9 +2601,8 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, // Check if it's really possible to do a tail call. if (IsTailCall) - IsTailCall = - isEligibleForTailCallOptimization(MipsCCInfo, NextStackOffset, - *MF.getInfo<MipsFunctionInfo>()); + IsTailCall = isEligibleForTailCallOptimization( + CCInfo, NextStackOffset, *MF.getInfo<MipsFunctionInfo>()); if (!IsTailCall && CLI.CS && CLI.CS->isMustTailCall()) report_fatal_error("failed to perform tail call elimination on a call " @@ -2629,7 +2628,8 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, // With EABI is it possible to have 16 args on registers. std::deque< std::pair<unsigned, SDValue> > RegsToPass; SmallVector<SDValue, 8> MemOpChains; - MipsCC::byval_iterator ByValArg = MipsCCInfo.byval_begin(); + + CCInfo.rewindByValRegsInfo(); // Walk the register/memloc assignments, inserting copies/loads. for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { @@ -2640,14 +2640,19 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, // ByVal Arg. if (Flags.isByVal()) { + unsigned FirstByValReg, LastByValReg; + unsigned ByValIdx = CCInfo.getInRegsParamsProceed(); + CCInfo.getInRegsParamInfo(ByValIdx, FirstByValReg, LastByValReg); + assert(Flags.getByValSize() && "ByVal args of size 0 should have been ignored by front-end."); - assert(ByValArg != MipsCCInfo.byval_end()); + assert(ByValIdx < CCInfo.getInRegsParamsCount()); assert(!IsTailCall && "Do not tail-call optimize if there is a byval argument."); passByValArg(Chain, DL, RegsToPass, MemOpChains, StackPtr, MFI, DAG, Arg, - MipsCCInfo, *ByValArg, Flags, Subtarget.isLittle(), VA); - ++ByValArg; + MipsCCInfo, FirstByValReg, LastByValReg, Flags, + Subtarget.isLittle(), VA); + CCInfo.nextInRegsParam(); continue; } @@ -2886,10 +2891,10 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain, MipsCCInfo.analyzeFormalArguments(Ins, UseSoftFloat, CCInfo); CCInfo.ClearOriginalArgWasF128(); MipsFI->setFormalArgInfo(CCInfo.getNextStackOffset(), - MipsCCInfo.hasByValArg()); + CCInfo.getInRegsParamsCount() > 0); unsigned CurArgIdx = 0; - MipsCC::byval_iterator ByValArg = MipsCCInfo.byval_begin(); + CCInfo.rewindByValRegsInfo(); for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { CCValAssign &VA = ArgLocs[i]; @@ -2900,12 +2905,16 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain, bool IsRegLoc = VA.isRegLoc(); if (Flags.isByVal()) { + unsigned FirstByValReg, LastByValReg; + unsigned ByValIdx = CCInfo.getInRegsParamsProceed(); + CCInfo.getInRegsParamInfo(ByValIdx, FirstByValReg, LastByValReg); + assert(Flags.getByValSize() && "ByVal args of size 0 should have been ignored by front-end."); - assert(ByValArg != MipsCCInfo.byval_end()); + assert(ByValIdx < CCInfo.getInRegsParamsCount()); copyByValRegs(Chain, DL, OutChains, DAG, Flags, InVals, &*FuncArg, - MipsCCInfo, *ByValArg, VA); - ++ByValArg; + MipsCCInfo, FirstByValReg, LastByValReg, VA); + CCInfo.nextInRegsParam(); continue; } @@ -3612,11 +3621,6 @@ void MipsTargetLowering::MipsCC::analyzeCallOperands( ISD::ArgFlagsTy ArgFlags = Args[I].Flags; bool R; - if (ArgFlags.isByVal()) { - handleByValArg(I, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, State); - continue; - } - if (IsVarArg && !Args[I].IsFixed) R = CC_Mips_VarArg(I, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, State); else @@ -3641,11 +3645,6 @@ void MipsTargetLowering::MipsCC::analyzeFormalArguments( MVT ArgVT = Args[I].VT; ISD::ArgFlagsTy ArgFlags = Args[I].Flags; - if (ArgFlags.isByVal()) { - handleByValArg(I, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, State); - continue; - } - if (!CC_Mips_FixedArg(I, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, State)) continue; @@ -3657,30 +3656,6 @@ void MipsTargetLowering::MipsCC::analyzeFormalArguments( } } -void MipsTargetLowering::MipsCC::handleByValArg(unsigned ValNo, MVT ValVT, - MVT LocVT, - CCValAssign::LocInfo LocInfo, - ISD::ArgFlagsTy ArgFlags, - CCState &State) { - assert(ArgFlags.getByValSize() && "Byval argument's size shouldn't be 0."); - - struct ByValArgInfo ByVal; - unsigned RegSizeInBytes = Subtarget.getGPRSizeInBytes(); - unsigned ByValSize = - RoundUpToAlignment(ArgFlags.getByValSize(), RegSizeInBytes); - unsigned Align = std::min(std::max(ArgFlags.getByValAlign(), RegSizeInBytes), - RegSizeInBytes * 2); - - if (useRegsForByval()) - allocateRegs(ByVal, ByValSize, Align, State); - - // Allocate space on caller's stack. - unsigned Offset = - State.AllocateStack(ByValSize - RegSizeInBytes * ByVal.NumRegs, Align); - State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo)); - ByValArgs.push_back(ByVal); -} - unsigned MipsTargetLowering::MipsCC::reservedArgArea() const { return (Subtarget.isABI_O32() && (CallConv != CallingConv::Fast)) ? 16 : 0; } @@ -3691,35 +3666,6 @@ const ArrayRef<MCPhysReg> MipsTargetLowering::MipsCC::intArgRegs() const { return makeArrayRef(Mips64IntRegs); } -const MCPhysReg *MipsTargetLowering::MipsCC::shadowRegs() const { - return Subtarget.isABI_O32() ? O32IntRegs : Mips64DPRegs; -} - -void MipsTargetLowering::MipsCC::allocateRegs(ByValArgInfo &ByVal, - unsigned ByValSize, - unsigned Align, CCState &State) { - unsigned RegSizeInBytes = Subtarget.getGPRSizeInBytes(); - const ArrayRef<MCPhysReg> IntArgRegs = intArgRegs(); - const MCPhysReg *ShadowRegs = shadowRegs(); - assert(!(ByValSize % RegSizeInBytes) && !(Align % RegSizeInBytes) && - "Byval argument's size and alignment should be a multiple of" - "RegSizeInBytes."); - - ByVal.FirstIdx = - State.getFirstUnallocated(IntArgRegs.data(), IntArgRegs.size()); - - // If Align > RegSizeInBytes, the first arg register must be even. - if ((Align > RegSizeInBytes) && (ByVal.FirstIdx % 2)) { - State.AllocateReg(IntArgRegs[ByVal.FirstIdx], ShadowRegs[ByVal.FirstIdx]); - ++ByVal.FirstIdx; - } - - // Mark the registers allocated. - for (unsigned I = ByVal.FirstIdx; ByValSize && (I < IntArgRegs.size()); - ByValSize -= RegSizeInBytes, ++I, ++ByVal.NumRegs) - State.AllocateReg(IntArgRegs[I], ShadowRegs[I]); -} - MVT MipsTargetLowering::MipsCC::getRegVT(MVT VT, const Type *OrigTy, const SDNode *CallNode, bool IsSoftFloat) const { @@ -3738,19 +3684,20 @@ MVT MipsTargetLowering::MipsCC::getRegVT(MVT VT, const Type *OrigTy, void MipsTargetLowering::copyByValRegs( SDValue Chain, SDLoc DL, std::vector<SDValue> &OutChains, SelectionDAG &DAG, const ISD::ArgFlagsTy &Flags, SmallVectorImpl<SDValue> &InVals, - const Argument *FuncArg, const MipsCC &CC, const ByValArgInfo &ByVal, - const CCValAssign &VA) const { + const Argument *FuncArg, const MipsCC &CC, unsigned FirstReg, + unsigned LastReg, const CCValAssign &VA) const { MachineFunction &MF = DAG.getMachineFunction(); MachineFrameInfo *MFI = MF.getFrameInfo(); unsigned GPRSizeInBytes = Subtarget.getGPRSizeInBytes(); - unsigned RegAreaSize = ByVal.NumRegs * GPRSizeInBytes; + unsigned NumRegs = LastReg - FirstReg; + unsigned RegAreaSize = NumRegs * GPRSizeInBytes; unsigned FrameObjSize = std::max(Flags.getByValSize(), RegAreaSize); int FrameObjOffset; if (RegAreaSize) FrameObjOffset = (int)CC.reservedArgArea() - - (int)((CC.intArgRegs().size() - ByVal.FirstIdx) * GPRSizeInBytes); + (int)((CC.intArgRegs().size() - FirstReg) * GPRSizeInBytes); else FrameObjOffset = VA.getLocMemOffset(); @@ -3760,15 +3707,15 @@ void MipsTargetLowering::copyByValRegs( SDValue FIN = DAG.getFrameIndex(FI, PtrTy); InVals.push_back(FIN); - if (!ByVal.NumRegs) + if (!NumRegs) return; // Copy arg registers. MVT RegTy = MVT::getIntegerVT(GPRSizeInBytes * 8); const TargetRegisterClass *RC = getRegClassFor(RegTy); - for (unsigned I = 0; I < ByVal.NumRegs; ++I) { - unsigned ArgReg = CC.intArgRegs()[ByVal.FirstIdx + I]; + for (unsigned I = 0; I < NumRegs; ++I) { + unsigned ArgReg = CC.intArgRegs()[FirstReg + I]; unsigned VReg = addLiveIn(MF, ArgReg, RC); unsigned Offset = I * GPRSizeInBytes; SDValue StorePtr = DAG.getNode(ISD::ADD, DL, PtrTy, FIN, @@ -3786,29 +3733,29 @@ void MipsTargetLowering::passByValArg( std::deque<std::pair<unsigned, SDValue>> &RegsToPass, SmallVectorImpl<SDValue> &MemOpChains, SDValue StackPtr, MachineFrameInfo *MFI, SelectionDAG &DAG, SDValue Arg, const MipsCC &CC, - const ByValArgInfo &ByVal, const ISD::ArgFlagsTy &Flags, bool isLittle, - const CCValAssign &VA) const { + unsigned FirstReg, unsigned LastReg, const ISD::ArgFlagsTy &Flags, + bool isLittle, const CCValAssign &VA) const { unsigned ByValSizeInBytes = Flags.getByValSize(); unsigned OffsetInBytes = 0; // From beginning of struct unsigned RegSizeInBytes = Subtarget.getGPRSizeInBytes(); unsigned Alignment = std::min(Flags.getByValAlign(), RegSizeInBytes); EVT PtrTy = getPointerTy(), RegTy = MVT::getIntegerVT(RegSizeInBytes * 8); + unsigned NumRegs = LastReg - FirstReg; - if (ByVal.NumRegs) { + if (NumRegs) { const ArrayRef<MCPhysReg> ArgRegs = CC.intArgRegs(); - bool LeftoverBytes = (ByVal.NumRegs * RegSizeInBytes > ByValSizeInBytes); + bool LeftoverBytes = (NumRegs * RegSizeInBytes > ByValSizeInBytes); unsigned I = 0; // Copy words to registers. - for (; I < ByVal.NumRegs - LeftoverBytes; - ++I, OffsetInBytes += RegSizeInBytes) { + for (; I < NumRegs - LeftoverBytes; ++I, OffsetInBytes += RegSizeInBytes) { SDValue LoadPtr = DAG.getNode(ISD::ADD, DL, PtrTy, Arg, DAG.getConstant(OffsetInBytes, PtrTy)); SDValue LoadVal = DAG.getLoad(RegTy, DL, Chain, LoadPtr, MachinePointerInfo(), false, false, false, Alignment); MemOpChains.push_back(LoadVal.getValue(1)); - unsigned ArgReg = ArgRegs[ByVal.FirstIdx + I]; + unsigned ArgReg = ArgRegs[FirstReg + I]; RegsToPass.push_back(std::make_pair(ArgReg, LoadVal)); } @@ -3818,9 +3765,6 @@ void MipsTargetLowering::passByValArg( // Copy the remainder of the byval argument with sub-word loads and shifts. if (LeftoverBytes) { - assert((ByValSizeInBytes > OffsetInBytes) && - (ByValSizeInBytes < OffsetInBytes + RegSizeInBytes) && - "Size of the remainder should be smaller than RegSizeInBytes."); SDValue Val; for (unsigned LoadSizeInBytes = RegSizeInBytes / 2, TotalBytesLoaded = 0; @@ -3860,7 +3804,7 @@ void MipsTargetLowering::passByValArg( Alignment = std::min(Alignment, LoadSizeInBytes); } - unsigned ArgReg = ArgRegs[ByVal.FirstIdx + I]; + unsigned ArgReg = ArgRegs[FirstReg + I]; RegsToPass.push_back(std::make_pair(ArgReg, Val)); return; } @@ -3923,3 +3867,49 @@ void MipsTargetLowering::writeVarArgRegs(std::vector<SDValue> &OutChains, OutChains.push_back(Store); } } + +void MipsTargetLowering::HandleByVal(CCState *State, unsigned &Size, + unsigned Align) const { + MachineFunction &MF = State->getMachineFunction(); + const TargetFrameLowering *TFL = MF.getSubtarget().getFrameLowering(); + + assert(Size && "Byval argument's size shouldn't be 0."); + + Align = std::min(Align, TFL->getStackAlignment()); + + unsigned FirstReg = 0; + unsigned NumRegs = 0; + + if (State->getCallingConv() != CallingConv::Fast) { + unsigned RegSizeInBytes = Subtarget.getGPRSizeInBytes(); + const ArrayRef<MCPhysReg> IntArgRegs = Subtarget.getABI().GetByValArgRegs(); + // FIXME: The O32 case actually describes no shadow registers. + const MCPhysReg *ShadowRegs = + Subtarget.isABI_O32() ? IntArgRegs.data() : Mips64DPRegs; + + // We used to check the size as well but we can't do that anymore since + // CCState::HandleByVal() rounds up the size after calling this function. + assert(!(Align % RegSizeInBytes) && + "Byval argument's alignment should be a multiple of" + "RegSizeInBytes."); + + FirstReg = State->getFirstUnallocated(IntArgRegs.data(), IntArgRegs.size()); + + // If Align > RegSizeInBytes, the first arg register must be even. + // FIXME: This condition happens to do the right thing but it's not the + // right way to test it. We want to check that the stack frame offset + // of the register is aligned. + if ((Align > RegSizeInBytes) && (FirstReg % 2)) { + State->AllocateReg(IntArgRegs[FirstReg], ShadowRegs[FirstReg]); + ++FirstReg; + } + + // Mark the registers allocated. + Size = RoundUpToAlignment(Size, RegSizeInBytes); + for (unsigned I = FirstReg; Size > 0 && (I < IntArgRegs.size()); + Size -= RegSizeInBytes, ++I, ++NumRegs) + State->AllocateReg(IntArgRegs[I], ShadowRegs[I]); + } + + State->addInRegsParamInfo(FirstReg, FirstReg + NumRegs); +} diff --git a/lib/Target/Mips/MipsISelLowering.h b/lib/Target/Mips/MipsISelLowering.h index 6ba3e59902a..9fae7af676e 100644 --- a/lib/Target/Mips/MipsISelLowering.h +++ b/lib/Target/Mips/MipsISelLowering.h @@ -259,6 +259,8 @@ namespace llvm { } }; + void HandleByVal(CCState *, unsigned &, unsigned) const override; + protected: SDValue getGlobalReg(SelectionDAG &DAG, EVT Ty) const; @@ -339,14 +341,6 @@ namespace llvm { bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const; - /// ByValArgInfo - Byval argument information. - struct ByValArgInfo { - unsigned FirstIdx; // Index of the first register used. - unsigned NumRegs; // Number of registers used for this argument. - - ByValArgInfo() : FirstIdx(0), NumRegs(0) {} - }; - /// MipsCC - This class provides methods used to analyze formal and call /// arguments and inquire about calling convention information. class MipsCC { @@ -367,9 +361,6 @@ namespace llvm { bool IsSoftFloat, CCState &State); - /// hasByValArg - Returns true if function has byval arguments. - bool hasByValArg() const { return !ByValArgs.empty(); } - /// reservedArgArea - The size of the area the caller reserves for /// register arguments. This is 16-byte if ABI is O32. unsigned reservedArgArea() const; @@ -377,24 +368,7 @@ namespace llvm { /// Return pointer to array of integer argument registers. const ArrayRef<MCPhysReg> intArgRegs() const; - typedef SmallVectorImpl<ByValArgInfo>::const_iterator byval_iterator; - byval_iterator byval_begin() const { return ByValArgs.begin(); } - byval_iterator byval_end() const { return ByValArgs.end(); } - private: - void handleByValArg(unsigned ValNo, MVT ValVT, MVT LocVT, - CCValAssign::LocInfo LocInfo, - ISD::ArgFlagsTy ArgFlags, CCState &State); - - /// useRegsForByval - Returns true if the calling convention allows the - /// use of registers to pass byval arguments. - bool useRegsForByval() const { return CallConv != CallingConv::Fast; } - - const MCPhysReg *shadowRegs() const; - - void allocateRegs(ByValArgInfo &ByVal, unsigned ByValSize, unsigned Align, - CCState &State); - /// Return the type of the register which is used to pass an argument or /// return a value. This function returns f64 if the argument is an i64 /// value which has been generated as a result of softening an f128 value. @@ -410,7 +384,6 @@ namespace llvm { CallingConv::ID CallConv; const MipsSubtarget &Subtarget; - SmallVector<ByValArgInfo, 2> ByValArgs; }; protected: SDValue lowerLOAD(SDValue Op, SelectionDAG &DAG) const; @@ -475,9 +448,9 @@ namespace llvm { /// isEligibleForTailCallOptimization - Check whether the call is eligible /// for tail call optimization. virtual bool - isEligibleForTailCallOptimization(const MipsCC &MipsCCInfo, + isEligibleForTailCallOptimization(const CCState &CCInfo, unsigned NextStackOffset, - const MipsFunctionInfo& FI) const = 0; + const MipsFunctionInfo &FI) const = 0; /// copyByValArg - Copy argument registers which were used to pass a byval /// argument to the stack. Create a stack frame object for the byval @@ -486,14 +459,15 @@ namespace llvm { SelectionDAG &DAG, const ISD::ArgFlagsTy &Flags, SmallVectorImpl<SDValue> &InVals, const Argument *FuncArg, const MipsCC &CC, - const ByValArgInfo &ByVal, const CCValAssign &VA) const; + unsigned FirstReg, unsigned LastReg, + const CCValAssign &VA) const; /// passByValArg - Pass a byval argument in registers or on stack. void passByValArg(SDValue Chain, SDLoc DL, std::deque<std::pair<unsigned, SDValue>> &RegsToPass, SmallVectorImpl<SDValue> &MemOpChains, SDValue StackPtr, MachineFrameInfo *MFI, SelectionDAG &DAG, SDValue Arg, - const MipsCC &CC, const ByValArgInfo &ByVal, + const MipsCC &CC, unsigned FirstReg, unsigned LastReg, const ISD::ArgFlagsTy &Flags, bool isLittle, const CCValAssign &VA) const; diff --git a/lib/Target/Mips/MipsSEISelLowering.cpp b/lib/Target/Mips/MipsSEISelLowering.cpp index 7417f6dc79f..4a0ce096edd 100644 --- a/lib/Target/Mips/MipsSEISelLowering.cpp +++ b/lib/Target/Mips/MipsSEISelLowering.cpp @@ -1167,15 +1167,14 @@ MipsSETargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, } } -bool MipsSETargetLowering:: -isEligibleForTailCallOptimization(const MipsCC &MipsCCInfo, - unsigned NextStackOffset, - const MipsFunctionInfo& FI) const { +bool MipsSETargetLowering::isEligibleForTailCallOptimization( + const CCState &CCInfo, unsigned NextStackOffset, + const MipsFunctionInfo &FI) const { if (!EnableMipsTailCalls) return false; // Return false if either the callee or caller has a byval argument. - if (MipsCCInfo.hasByValArg() || FI.hasByvalArg()) + if (CCInfo.getInRegsParamsCount() > 0 || FI.hasByvalArg()) return false; // Return true if the callee's argument area is no larger than the diff --git a/lib/Target/Mips/MipsSEISelLowering.h b/lib/Target/Mips/MipsSEISelLowering.h index 4ca94addf2c..d44f8d82ec3 100644 --- a/lib/Target/Mips/MipsSEISelLowering.h +++ b/lib/Target/Mips/MipsSEISelLowering.h @@ -51,9 +51,9 @@ namespace llvm { const TargetRegisterClass *getRepRegClassFor(MVT VT) const override; private: - bool isEligibleForTailCallOptimization(const MipsCC &MipsCCInfo, - unsigned NextStackOffset, - const MipsFunctionInfo& FI) const override; + bool isEligibleForTailCallOptimization( + const CCState &CCInfo, unsigned NextStackOffset, + const MipsFunctionInfo &FI) const override; void getOpndList(SmallVectorImpl<SDValue> &Ops, |