diff options
Diffstat (limited to 'contrib/llvm/lib/Target/Mips/MipsISelLowering.cpp')
| -rw-r--r-- | contrib/llvm/lib/Target/Mips/MipsISelLowering.cpp | 186 |
1 files changed, 83 insertions, 103 deletions
diff --git a/contrib/llvm/lib/Target/Mips/MipsISelLowering.cpp b/contrib/llvm/lib/Target/Mips/MipsISelLowering.cpp index 20319f85696c..6448fd917560 100644 --- a/contrib/llvm/lib/Target/Mips/MipsISelLowering.cpp +++ b/contrib/llvm/lib/Target/Mips/MipsISelLowering.cpp @@ -1,4 +1,4 @@ -//===-- MipsISelLowering.cpp - Mips DAG Lowering Implementation -----------===// +//===- MipsISelLowering.cpp - Mips DAG Lowering Implementation ------------===// // // The LLVM Compiler Infrastructure // @@ -11,33 +11,70 @@ // selection DAG. // //===----------------------------------------------------------------------===// + #include "MipsISelLowering.h" #include "InstPrinter/MipsInstPrinter.h" #include "MCTargetDesc/MipsBaseInfo.h" +#include "MCTargetDesc/MipsMCTargetDesc.h" #include "MipsCCState.h" +#include "MipsInstrInfo.h" #include "MipsMachineFunction.h" +#include "MipsRegisterInfo.h" #include "MipsSubtarget.h" #include "MipsTargetMachine.h" #include "MipsTargetObjectFile.h" +#include "llvm/ADT/APFloat.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" +#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/CodeGen/CallingConvLower.h" #include "llvm/CodeGen/FunctionLoweringInfo.h" +#include "llvm/CodeGen/ISDOpcodes.h" +#include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineJumpTableInfo.h" +#include "llvm/CodeGen/MachineMemOperand.h" +#include "llvm/CodeGen/MachineOperand.h" #include "llvm/CodeGen/MachineRegisterInfo.h" -#include "llvm/CodeGen/SelectionDAGISel.h" +#include "llvm/CodeGen/MachineValueType.h" +#include "llvm/CodeGen/RuntimeLibcalls.h" +#include "llvm/CodeGen/SelectionDAG.h" +#include "llvm/CodeGen/SelectionDAGNodes.h" +#include "llvm/CodeGen/TargetFrameLowering.h" +#include "llvm/CodeGen/TargetInstrInfo.h" +#include "llvm/CodeGen/TargetRegisterInfo.h" #include "llvm/CodeGen/ValueTypes.h" #include "llvm/IR/CallingConv.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/DebugLoc.h" #include "llvm/IR/DerivedTypes.h" -#include "llvm/IR/GlobalVariable.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/GlobalValue.h" +#include "llvm/IR/Type.h" +#include "llvm/IR/Value.h" +#include "llvm/MC/MCRegisterInfo.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/CodeGen.h" #include "llvm/Support/CommandLine.h" -#include "llvm/Support/Debug.h" +#include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/MathExtras.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetOptions.h" +#include <algorithm> +#include <cassert> #include <cctype> +#include <cstdint> +#include <deque> +#include <iterator> +#include <utility> +#include <vector> using namespace llvm; @@ -102,7 +139,6 @@ unsigned MipsTargetLowering::getNumRegistersForCallingConv(LLVMContext &Context, unsigned MipsTargetLowering::getVectorTypeBreakdownForCallingConv( LLVMContext &Context, EVT VT, EVT &IntermediateVT, unsigned &NumIntermediates, MVT &RegisterVT) const { - // Break down vector types to either 2 i64s or 4 i32s. RegisterVT = getRegisterTypeForCallingConv(Context, VT) ; IntermediateVT = RegisterVT; @@ -166,6 +202,8 @@ const char *MipsTargetLowering::getTargetNodeName(unsigned Opcode) const { case MipsISD::EH_RETURN: return "MipsISD::EH_RETURN"; case MipsISD::FPBrcond: return "MipsISD::FPBrcond"; case MipsISD::FPCmp: return "MipsISD::FPCmp"; + case MipsISD::FSELECT: return "MipsISD::FSELECT"; + case MipsISD::MTC1_D64: return "MipsISD::MTC1_D64"; case MipsISD::CMovFP_T: return "MipsISD::CMovFP_T"; case MipsISD::CMovFP_F: return "MipsISD::CMovFP_F"; case MipsISD::TruncIntFP: return "MipsISD::TruncIntFP"; @@ -449,7 +487,6 @@ MipsTargetLowering::MipsTargetLowering(const MipsTargetMachine &TM, setOperationAction(ISD::ATOMIC_STORE, MVT::i64, Expand); } - if (!Subtarget.hasMips32r2()) { setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8, Expand); setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16, Expand); @@ -508,9 +545,9 @@ MipsTargetLowering::MipsTargetLowering(const MipsTargetMachine &TM, const MipsTargetLowering *MipsTargetLowering::create(const MipsTargetMachine &TM, const MipsSubtarget &STI) { if (STI.inMips16Mode()) - return llvm::createMips16TargetLowering(TM, STI); + return createMips16TargetLowering(TM, STI); - return llvm::createMipsSETargetLowering(TM, STI); + return createMipsSETargetLowering(TM, STI); } // Create a fast isel object. @@ -603,7 +640,6 @@ static Mips::CondCode condCodeToFCC(ISD::CondCode CC) { } } - /// This function returns true if the floating point conditional branches and /// conditional moves which use condition code CC should be inverted. static bool invertFPCondCodeUser(Mips::CondCode CC) { @@ -1076,38 +1112,6 @@ static SDValue performADDCombine(SDNode *N, SelectionDAG &DAG, return DAG.getNode(ISD::ADD, DL, ValTy, Add1, Lo); } -static SDValue performAssertZextCombine(SDNode *N, SelectionDAG &DAG, - TargetLowering::DAGCombinerInfo &DCI, - const MipsSubtarget &Subtarget) { - SDValue N0 = N->getOperand(0); - EVT NarrowerVT = cast<VTSDNode>(N->getOperand(1))->getVT(); - - if (N0.getOpcode() != ISD::TRUNCATE) - return SDValue(); - - if (N0.getOperand(0).getOpcode() != ISD::AssertZext) - return SDValue(); - - // fold (AssertZext (trunc (AssertZext x))) -> (trunc (AssertZext x)) - // if the type of the extension of the innermost AssertZext node is - // smaller from that of the outermost node, eg: - // (AssertZext:i32 (trunc:i32 (AssertZext:i64 X, i32)), i8) - // -> (trunc:i32 (AssertZext X, i8)) - SDValue WiderAssertZext = N0.getOperand(0); - EVT WiderVT = cast<VTSDNode>(WiderAssertZext->getOperand(1))->getVT(); - - if (NarrowerVT.bitsLT(WiderVT)) { - SDValue NewAssertZext = DAG.getNode( - ISD::AssertZext, SDLoc(N), WiderAssertZext.getValueType(), - WiderAssertZext.getOperand(0), DAG.getValueType(NarrowerVT)); - return DAG.getNode(ISD::TRUNCATE, SDLoc(N), N->getValueType(0), - NewAssertZext); - } - - return SDValue(); -} - - static SDValue performSHLCombine(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI, const MipsSubtarget &Subtarget) { @@ -1180,8 +1184,6 @@ SDValue MipsTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) return performORCombine(N, DAG, DCI, Subtarget); case ISD::ADD: return performADDCombine(N, DAG, DCI, Subtarget); - case ISD::AssertZext: - return performAssertZextCombine(N, DAG, DCI, Subtarget); case ISD::SHL: return performSHLCombine(N, DAG, DCI, Subtarget); case ISD::SUB: @@ -1393,14 +1395,6 @@ MipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI, case Mips::DMOD: case Mips::DMODU: return insertDivByZeroTrap(MI, *BB, *Subtarget.getInstrInfo(), true, false); - case Mips::DDIV_MM64R6: - case Mips::DDIVU_MM64R6: - case Mips::DMOD_MM64R6: - case Mips::DMODU_MM64R6: - return insertDivByZeroTrap(MI, *BB, *Subtarget.getInstrInfo(), true, true); - case Mips::SEL_D: - case Mips::SEL_D_MMR6: - return emitSEL_D(MI, BB); case Mips::PseudoSELECT_I: case Mips::PseudoSELECT_I64: @@ -1960,32 +1954,6 @@ MachineBasicBlock *MipsTargetLowering::emitAtomicCmpSwapPartword( return exitMBB; } -MachineBasicBlock *MipsTargetLowering::emitSEL_D(MachineInstr &MI, - MachineBasicBlock *BB) const { - MachineFunction *MF = BB->getParent(); - const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo(); - const TargetInstrInfo *TII = Subtarget.getInstrInfo(); - MachineRegisterInfo &RegInfo = MF->getRegInfo(); - DebugLoc DL = MI.getDebugLoc(); - MachineBasicBlock::iterator II(MI); - - unsigned Fc = MI.getOperand(1).getReg(); - const auto &FGR64RegClass = TRI->getRegClass(Mips::FGR64RegClassID); - - unsigned Fc2 = RegInfo.createVirtualRegister(FGR64RegClass); - - BuildMI(*BB, II, DL, TII->get(Mips::SUBREG_TO_REG), Fc2) - .addImm(0) - .addReg(Fc) - .addImm(Mips::sub_lo); - - // We don't erase the original instruction, we just replace the condition - // register with the 64-bit super-register. - MI.getOperand(1).setReg(Fc2); - - return BB; -} - SDValue MipsTargetLowering::lowerBRCOND(SDValue Op, SelectionDAG &DAG) const { // The first operand is the chain, the second is the condition, the third is // the block to branch to if the condition is true. @@ -2051,7 +2019,7 @@ SDValue MipsTargetLowering::lowerGlobalAddress(SDValue Op, const GlobalObject *GO = GV->getBaseObject(); if (GO && TLOF->IsGlobalInSmallSection(GO, getTargetMachine())) // %gp_rel relocation - return getAddrGPRel(N, SDLoc(N), Ty, DAG); + return getAddrGPRel(N, SDLoc(N), Ty, DAG, ABI.IsN64()); // %hi/%lo relocation return Subtarget.hasSym32() ? getAddrNonPIC(N, SDLoc(N), Ty, DAG) @@ -2206,7 +2174,7 @@ lowerConstantPool(SDValue Op, SelectionDAG &DAG) const if (TLOF->IsConstantInSmallSection(DAG.getDataLayout(), N->getConstVal(), getTargetMachine())) // %gp_rel relocation - return getAddrGPRel(N, SDLoc(N), Ty, DAG); + return getAddrGPRel(N, SDLoc(N), Ty, DAG, ABI.IsN64()); return Subtarget.hasSym32() ? getAddrNonPIC(N, SDLoc(N), Ty, DAG) : getAddrNonPICSym64(N, SDLoc(N), Ty, DAG); @@ -2839,8 +2807,7 @@ static bool CC_MipsO32(unsigned ValNo, MVT ValVT, MVT LocVT, llvm_unreachable("Cannot handle this ValVT."); if (!Reg) { - unsigned Offset = State.AllocateStack(ValVT.getSizeInBits() >> 3, - OrigAlign); + unsigned Offset = State.AllocateStack(ValVT.getStoreSize(), OrigAlign); State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo)); } else State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); @@ -2900,7 +2867,7 @@ SDValue MipsTargetLowering::passArgOnStack(SDValue StackPtr, unsigned Offset, void MipsTargetLowering:: getOpndList(SmallVectorImpl<SDValue> &Ops, - std::deque< std::pair<unsigned, SDValue> > &RegsToPass, + std::deque<std::pair<unsigned, SDValue>> &RegsToPass, bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage, bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const { @@ -2945,7 +2912,7 @@ getOpndList(SmallVectorImpl<SDValue> &Ops, assert(Mask && "Missing call preserved mask for calling convention"); if (Subtarget.inMips16HardFloat()) { if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(CLI.Callee)) { - llvm::StringRef Sym = G->getGlobal()->getName(); + StringRef Sym = G->getGlobal()->getName(); Function *F = G->getGlobal()->getParent()->getFunction(Sym); if (F && F->hasFnAttribute("__Mips16RetHelper")) { Mask = MipsRegisterInfo::getMips16RetHelperMask(); @@ -3012,7 +2979,7 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, G->getGlobal()->hasProtectedVisibility()); } } - if (!IsTailCall && CLI.CS && CLI.CS->isMustTailCall()) + if (!IsTailCall && CLI.CS && CLI.CS.isMustTailCall()) report_fatal_error("failed to perform tail call elimination on a call " "site marked musttail"); @@ -3033,7 +3000,7 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, DAG.getCopyFromReg(Chain, DL, ABI.IsN64() ? Mips::SP_64 : Mips::SP, getPointerTy(DAG.getDataLayout())); - std::deque< std::pair<unsigned, SDValue> > RegsToPass; + std::deque<std::pair<unsigned, SDValue>> RegsToPass; SmallVector<SDValue, 8> MemOpChains; CCInfo.rewindByValRegsInfo(); @@ -3145,22 +3112,36 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol // node so that legalize doesn't hack it. - SDValue CalleeLo; EVT Ty = Callee.getValueType(); bool GlobalOrExternal = false, IsCallReloc = false; // The long-calls feature is ignored in case of PIC. // While we do not support -mshared / -mno-shared properly, // ignore long-calls in case of -mabicalls too. - if (Subtarget.useLongCalls() && !Subtarget.isABICalls() && !IsPIC) { - // Get the address of the callee into a register to prevent - // using of the `jal` instruction for the direct call. - if (auto *N = dyn_cast<GlobalAddressSDNode>(Callee)) - Callee = Subtarget.hasSym32() ? getAddrNonPIC(N, SDLoc(N), Ty, DAG) - : getAddrNonPICSym64(N, SDLoc(N), Ty, DAG); - else if (auto *N = dyn_cast<ExternalSymbolSDNode>(Callee)) - Callee = Subtarget.hasSym32() ? getAddrNonPIC(N, SDLoc(N), Ty, DAG) - : getAddrNonPICSym64(N, SDLoc(N), Ty, DAG); + if (!Subtarget.isABICalls() && !IsPIC) { + // If the function should be called using "long call", + // get its address into a register to prevent using + // of the `jal` instruction for the direct call. + if (auto *N = dyn_cast<ExternalSymbolSDNode>(Callee)) { + if (Subtarget.useLongCalls()) + Callee = Subtarget.hasSym32() + ? getAddrNonPIC(N, SDLoc(N), Ty, DAG) + : getAddrNonPICSym64(N, SDLoc(N), Ty, DAG); + } else if (auto *N = dyn_cast<GlobalAddressSDNode>(Callee)) { + bool UseLongCalls = Subtarget.useLongCalls(); + // If the function has long-call/far/near attribute + // it overrides command line switch pased to the backend. + if (auto *F = dyn_cast<Function>(N->getGlobal())) { + if (F->hasFnAttribute("long-call")) + UseLongCalls = true; + else if (F->hasFnAttribute("short-call")) + UseLongCalls = false; + } + if (UseLongCalls) + Callee = Subtarget.hasSym32() + ? getAddrNonPIC(N, SDLoc(N), Ty, DAG) + : getAddrNonPICSym64(N, SDLoc(N), Ty, DAG); + } } if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) { @@ -3378,10 +3359,10 @@ SDValue MipsTargetLowering::LowerFormalArguments( MipsCCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs, *DAG.getContext()); CCInfo.AllocateStack(ABI.GetCalleeAllocdArgSizeInBytes(CallConv), 1); - const Function *Func = DAG.getMachineFunction().getFunction(); - Function::const_arg_iterator FuncArg = Func->arg_begin(); + const Function &Func = DAG.getMachineFunction().getFunction(); + Function::const_arg_iterator FuncArg = Func.arg_begin(); - if (Func->hasFnAttribute("interrupt") && !Func->arg_empty()) + if (Func.hasFnAttribute("interrupt") && !Func.arg_empty()) report_fatal_error( "Functions with the interrupt attribute cannot have arguments!"); @@ -3537,7 +3518,6 @@ SDValue MipsTargetLowering::LowerInterruptReturn(SmallVectorImpl<SDValue> &RetOps, const SDLoc &DL, SelectionDAG &DAG) const { - MachineFunction &MF = DAG.getMachineFunction(); MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>(); @@ -3620,7 +3600,7 @@ MipsTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, // the sret argument into $v0 for the return. We saved the argument into // a virtual register in the entry block, so now we copy the value out // and into $v0. - if (MF.getFunction()->hasStructRetAttr()) { + if (MF.getFunction().hasStructRetAttr()) { MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>(); unsigned Reg = MipsFI->getSRetReturnReg(); @@ -3642,7 +3622,7 @@ MipsTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, RetOps.push_back(Flag); // ISRs must use "eret". - if (DAG.getMachineFunction().getFunction()->hasFnAttribute("interrupt")) + if (DAG.getMachineFunction().getFunction().hasFnAttribute("interrupt")) return LowerInterruptReturn(RetOps, DL, DAG); // Standard return on Mips is a "jr $ra" @@ -4003,7 +3983,7 @@ void MipsTargetLowering::LowerAsmOperandForConstraint(SDValue Op, bool MipsTargetLowering::isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, - unsigned AS) const { + unsigned AS, Instruction *I) const { // No global is ever allowed as a base. if (AM.BaseGV) return false; |
