From 12c49af81e370df835ca1b72cdcefcadafcede4b Mon Sep 17 00:00:00 2001 From: Anton Korobeynikov Date: Tue, 21 Nov 2006 00:01:06 +0000 Subject: [PATCH] Refactored *GVRequiresExtraLoad() to Subtarget method. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@31887 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/X86ISelLowering.cpp | 201 ++++++++++++----------------- lib/Target/X86/X86Subtarget.h | 28 +++- 2 files changed, 109 insertions(+), 120 deletions(-) diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 77a4b539cfe..b46780cd446 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -35,8 +35,6 @@ #include "llvm/ADT/StringExtras.h" using namespace llvm; -static bool WindowsGVRequiresExtraLoad(GlobalValue *GV); - // FIXME: temporary. static cl::opt EnableFastCC("enable-x86-fastcc", cl::Hidden, cl::desc("Enable fastcc on X86")); @@ -59,7 +57,7 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM) if (!Subtarget->isTargetDarwin()) // Darwin should use _setjmp/_longjmp instead of setjmp/longjmp. setUseUnderscoreSetJmpLongJmp(true); - + // Add legal addressing mode scale values. addLegalAddressScale(8); addLegalAddressScale(4); @@ -69,7 +67,7 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM) addLegalAddressScale(9); addLegalAddressScale(5); addLegalAddressScale(3); - + // Set up the register classes. addRegisterClass(MVT::i8, X86::GR8RegisterClass); addRegisterClass(MVT::i16, X86::GR16RegisterClass); @@ -229,12 +227,12 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM) // VASTART needs to be custom lowered to use the VarArgsFrameIndex setOperationAction(ISD::VASTART , MVT::Other, Custom); - + // Use the default implementation. setOperationAction(ISD::VAARG , MVT::Other, Expand); setOperationAction(ISD::VACOPY , MVT::Other, Expand); setOperationAction(ISD::VAEND , MVT::Other, Expand); - setOperationAction(ISD::STACKSAVE, MVT::Other, Expand); + setOperationAction(ISD::STACKSAVE, MVT::Other, Expand); setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand); if (Subtarget->is64Bit()) setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64, Expand); @@ -272,9 +270,9 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM) } else { // Set up the FP register classes. addRegisterClass(MVT::f64, X86::RFPRegisterClass); - + setOperationAction(ISD::UNDEF, MVT::f64, Expand); - + if (!UnsafeFPMath) { setOperationAction(ISD::FSIN , MVT::f64 , Expand); setOperationAction(ISD::FCOS , MVT::f64 , Expand); @@ -372,7 +370,7 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM) setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v2f64, Custom); setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v2i64, Custom); - // Promote v16i8, v8i16, v4i32 load, select, and, or, xor to v2i64. + // Promote v16i8, v8i16, v4i32 load, select, and, or, xor to v2i64. for (unsigned VT = (unsigned)MVT::v16i8; VT != (unsigned)MVT::v2i64; VT++) { setOperationAction(ISD::AND, (MVT::ValueType)VT, Promote); AddPromotedToType (ISD::AND, (MVT::ValueType)VT, MVT::v2i64); @@ -655,8 +653,7 @@ SDOperand X86TargetLowering::LowerCCCCallTo(SDOperand Op, SelectionDAG &DAG) { // turn it into a TargetGlobalAddress node so that legalize doesn't hack it. if (GlobalAddressSDNode *G = dyn_cast(Callee)) { // We should use extra load for direct calls to dllimported functions - if (!((Subtarget->isTargetCygwin() || Subtarget->isTargetWindows()) && - WindowsGVRequiresExtraLoad(G->getGlobal()))) + if (!Subtarget->GVRequiresExtraLoad(G->getGlobal(), true)) Callee = DAG.getTargetGlobalAddress(G->getGlobal(), getPointerTy()); } else if (ExternalSymbolSDNode *S = dyn_cast(Callee)) Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy()); @@ -671,7 +668,7 @@ SDOperand X86TargetLowering::LowerCCCCallTo(SDOperand Op, SelectionDAG &DAG) { // Add argument registers to the end of the list so that they are known live // into the call. for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) - Ops.push_back(DAG.getRegister(RegsToPass[i].first, + Ops.push_back(DAG.getRegister(RegsToPass[i].first, RegsToPass[i].second.getValueType())); if (InFlag.Val) @@ -689,7 +686,7 @@ SDOperand X86TargetLowering::LowerCCCCallTo(SDOperand Op, SelectionDAG &DAG) { // This is common for Darwin/X86, Linux & Mingw32 targets. if (CallingConv == CallingConv::CSRet) NumBytesForCalleeToPush = 4; - + NodeTys.clear(); NodeTys.push_back(MVT::Other); // Returns a chain if (RetVT != MVT::Other) @@ -702,7 +699,7 @@ SDOperand X86TargetLowering::LowerCCCCallTo(SDOperand Op, SelectionDAG &DAG) { Chain = DAG.getNode(ISD::CALLSEQ_END, NodeTys, &Ops[0], Ops.size()); if (RetVT != MVT::Other) InFlag = Chain.getValue(1); - + std::vector ResultVals; NodeTys.clear(); switch (RetVT) { @@ -751,7 +748,7 @@ SDOperand X86TargetLowering::LowerCCCCallTo(SDOperand Op, SelectionDAG &DAG) { std::vector Ops; Ops.push_back(Chain); Ops.push_back(InFlag); - SDOperand RetVal = DAG.getNode(X86ISD::FP_GET_RESULT, Tys, + SDOperand RetVal = DAG.getNode(X86ISD::FP_GET_RESULT, Tys, &Ops[0], Ops.size()); Chain = RetVal.getValue(1); InFlag = RetVal.getValue(2); @@ -788,7 +785,7 @@ SDOperand X86TargetLowering::LowerCCCCallTo(SDOperand Op, SelectionDAG &DAG) { // If the function returns void, just return the chain. if (ResultVals.empty()) return Chain; - + // Otherwise, merge everything together with a MERGE_VALUES node. NodeTys.push_back(MVT::Other); ResultVals.push_back(Chain); @@ -923,7 +920,7 @@ X86TargetLowering::LowerX86_64CCCArguments(SDOperand Op, SelectionDAG &DAG) { TargetRegisterClass *RC = NULL; switch (ObjectVT) { default: break; - case MVT::i8: + case MVT::i8: RC = X86::GR8RegisterClass; Reg = GPR8ArgRegs[NumIntRegs]; break; @@ -1193,8 +1190,7 @@ X86TargetLowering::LowerX86_64CCCCallTo(SDOperand Op, SelectionDAG &DAG) { // turn it into a TargetGlobalAddress node so that legalize doesn't hack it. if (GlobalAddressSDNode *G = dyn_cast(Callee)) { // We should use extra load for direct calls to dllimported functions - if (!((Subtarget->isTargetCygwin() || Subtarget->isTargetWindows()) && - WindowsGVRequiresExtraLoad(G->getGlobal()))) + if (!Subtarget->GVRequiresExtraLoad(G->getGlobal(), true)) Callee = DAG.getTargetGlobalAddress(G->getGlobal(), getPointerTy()); } else if (ExternalSymbolSDNode *S = dyn_cast(Callee)) Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy()); @@ -1209,7 +1205,7 @@ X86TargetLowering::LowerX86_64CCCCallTo(SDOperand Op, SelectionDAG &DAG) { // Add argument registers to the end of the list so that they are known live // into the call. for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) - Ops.push_back(DAG.getRegister(RegsToPass[i].first, + Ops.push_back(DAG.getRegister(RegsToPass[i].first, RegsToPass[i].second.getValueType())); if (InFlag.Val) @@ -1232,7 +1228,7 @@ X86TargetLowering::LowerX86_64CCCCallTo(SDOperand Op, SelectionDAG &DAG) { Chain = DAG.getNode(ISD::CALLSEQ_END, NodeTys, &Ops[0], Ops.size()); if (RetVT != MVT::Other) InFlag = Chain.getValue(1); - + std::vector ResultVals; NodeTys.clear(); switch (RetVT) { @@ -1286,7 +1282,7 @@ X86TargetLowering::LowerX86_64CCCCallTo(SDOperand Op, SelectionDAG &DAG) { // If the function returns void, just return the chain. if (ResultVals.empty()) return Chain; - + // Otherwise, merge everything together with a MERGE_VALUES node. NodeTys.push_back(MVT::Other); ResultVals.push_back(Chain); @@ -1407,7 +1403,7 @@ X86TargetLowering::LowerFastCCArguments(SDOperand Op, SelectionDAG &DAG) { static const unsigned XMMArgRegs[] = { X86::XMM0, X86::XMM1, X86::XMM2, X86::XMM3 }; - + for (unsigned i = 0; i < NumArgs; ++i) { MVT::ValueType ObjectVT = Op.getValue(i).getValueType(); unsigned ArgIncrement = 4; @@ -1558,7 +1554,7 @@ SDOperand X86TargetLowering::LowerFastCCCallTo(SDOperand Op, SelectionDAG &DAG, { X86::CL, X86::DL }, { X86::CX, X86::DX }, { X86::ECX, X86::EDX } - }; + }; #endif static const unsigned XMMArgRegs[] = { X86::XMM0, X86::XMM1, X86::XMM2, X86::XMM3 @@ -1668,7 +1664,7 @@ SDOperand X86TargetLowering::LowerFastCCCallTo(SDOperand Op, SelectionDAG &DAG, PtrOff = DAG.getNode(ISD::ADD, getPointerTy(), StackPtr, PtrOff); MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0)); ArgOffset += 16; - } + } } break; } @@ -1691,8 +1687,7 @@ SDOperand X86TargetLowering::LowerFastCCCallTo(SDOperand Op, SelectionDAG &DAG, // turn it into a TargetGlobalAddress node so that legalize doesn't hack it. if (GlobalAddressSDNode *G = dyn_cast(Callee)) { // We should use extra load for direct calls to dllimported functions - if (!((Subtarget->isTargetCygwin() || Subtarget->isTargetWindows()) && - WindowsGVRequiresExtraLoad(G->getGlobal()))) + if (!Subtarget->GVRequiresExtraLoad(G->getGlobal(), true)) Callee = DAG.getTargetGlobalAddress(G->getGlobal(), getPointerTy()); } else if (ExternalSymbolSDNode *S = dyn_cast(Callee)) Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy()); @@ -1707,7 +1702,7 @@ SDOperand X86TargetLowering::LowerFastCCCallTo(SDOperand Op, SelectionDAG &DAG, // Add argument registers to the end of the list so that they are known live // into the call. for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) - Ops.push_back(DAG.getRegister(RegsToPass[i].first, + Ops.push_back(DAG.getRegister(RegsToPass[i].first, RegsToPass[i].second.getValueType())); if (InFlag.Val) @@ -1730,7 +1725,7 @@ SDOperand X86TargetLowering::LowerFastCCCallTo(SDOperand Op, SelectionDAG &DAG, Chain = DAG.getNode(ISD::CALLSEQ_END, NodeTys, &Ops[0], Ops.size()); if (RetVT != MVT::Other) InFlag = Chain.getValue(1); - + std::vector ResultVals; NodeTys.clear(); switch (RetVT) { @@ -1821,7 +1816,7 @@ SDOperand X86TargetLowering::LowerFastCCCallTo(SDOperand Op, SelectionDAG &DAG, // If the function returns void, just return the chain. if (ResultVals.empty()) return Chain; - + // Otherwise, merge everything together with a MERGE_VALUES node. NodeTys.push_back(MVT::Other); ResultVals.push_back(Chain); @@ -1888,7 +1883,7 @@ SDOperand X86TargetLowering::LowerStdCallCCArguments(SDOperand Op, } ArgValues.push_back(Root); - + // If the function takes variable number of arguments, make a frame index for // the start of the first vararg value... for expansion of llvm.va_start. bool isVarArg = cast(Op.getOperand(2))->getValue() != 0; @@ -1904,7 +1899,7 @@ SDOperand X86TargetLowering::LowerStdCallCCArguments(SDOperand Op, ReturnAddrIndex = 0; // No return address slot generated yet. MF.getInfo()->setBytesToPopOnReturn(BytesToPopOnReturn); - + // Return the new list of results. std::vector RetVTs(Op.Val->value_begin(), Op.Val->value_end()); @@ -1919,8 +1914,8 @@ SDOperand X86TargetLowering::LowerStdCallCCCallTo(SDOperand Op, bool isTailCall = cast(Op.getOperand(3))->getValue() != 0; SDOperand Callee = Op.getOperand(4); MVT::ValueType RetVT= Op.Val->getValueType(0); - unsigned NumOps = (Op.getNumOperands() - 5) / 2; - + unsigned NumOps = (Op.getNumOperands() - 5) / 2; + // Count how many bytes are to be pushed on the stack. unsigned NumBytes = 0; for (unsigned i = 0; i != NumOps; ++i) { @@ -1940,7 +1935,7 @@ SDOperand X86TargetLowering::LowerStdCallCCCallTo(SDOperand Op, break; } } - + Chain = DAG.getCALLSEQ_START(Chain,DAG.getConstant(NumBytes, getPointerTy())); // Arguments go on the stack in reverse order, as specified by the ABI. @@ -1990,8 +1985,7 @@ SDOperand X86TargetLowering::LowerStdCallCCCallTo(SDOperand Op, // turn it into a TargetGlobalAddress node so that legalize doesn't hack it. if (GlobalAddressSDNode *G = dyn_cast(Callee)) { // We should use extra load for direct calls to dllimported functions - if (!((Subtarget->isTargetCygwin() || Subtarget->isTargetWindows()) && - WindowsGVRequiresExtraLoad(G->getGlobal()))) + if (!Subtarget->GVRequiresExtraLoad(G->getGlobal(), true)) Callee = DAG.getTargetGlobalAddress(G->getGlobal(), getPointerTy()); } else if (ExternalSymbolSDNode *S = dyn_cast(Callee)) Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy()); @@ -2009,7 +2003,7 @@ SDOperand X86TargetLowering::LowerStdCallCCCallTo(SDOperand Op, // Create the CALLSEQ_END node. unsigned NumBytesForCalleeToPush; - + if (isVarArg) { NumBytesForCalleeToPush = 0; } else { @@ -2028,7 +2022,7 @@ SDOperand X86TargetLowering::LowerStdCallCCCallTo(SDOperand Op, Chain = DAG.getNode(ISD::CALLSEQ_END, NodeTys, &Ops[0], Ops.size()); if (RetVT != MVT::Other) InFlag = Chain.getValue(1); - + std::vector ResultVals; NodeTys.clear(); switch (RetVT) { @@ -2067,7 +2061,7 @@ SDOperand X86TargetLowering::LowerStdCallCCCallTo(SDOperand Op, std::vector Ops; Ops.push_back(Chain); Ops.push_back(InFlag); - SDOperand RetVal = DAG.getNode(X86ISD::FP_GET_RESULT, Tys, + SDOperand RetVal = DAG.getNode(X86ISD::FP_GET_RESULT, Tys, &Ops[0], Ops.size()); Chain = RetVal.getValue(1); InFlag = RetVal.getValue(2); @@ -2104,7 +2098,7 @@ SDOperand X86TargetLowering::LowerStdCallCCCallTo(SDOperand Op, // If the function returns void, just return the chain. if (ResultVals.empty()) return Chain; - + // Otherwise, merge everything together with a MERGE_VALUES node. NodeTys.push_back(MVT::Other); ResultVals.push_back(Chain); @@ -2240,7 +2234,7 @@ X86TargetLowering::LowerFastCallCCArguments(SDOperand Op, SelectionDAG &DAG) { } break; } - + NumIntRegs += ObjIntRegs; } @@ -2357,7 +2351,7 @@ static bool translateX86CC(ISD::CondCode SetCCOpcode, bool isFP, return true; } } - + switch (SetCCOpcode) { default: break; case ISD::SETEQ: X86CC = X86::COND_E; break; @@ -2426,25 +2420,6 @@ static bool hasFPCMov(unsigned X86CC) { } } -/// DarwinGVRequiresExtraLoad - true if accessing the GV requires an extra -/// load. For Darwin, external and weak symbols are indirect, loading the value -/// at address GV rather then the value of GV itself. This means that the -/// GlobalAddress must be in the base or index register of the address, not the -/// GV offset field. -static bool DarwinGVRequiresExtraLoad(GlobalValue *GV) { - return (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() || - (GV->isExternal() && !GV->hasNotBeenReadFromBytecode())); -} - -/// WindowsGVRequiresExtraLoad - true if accessing the GV requires an extra -/// load. For Windows, dllimported symbols are indirect, loading the value at -/// address GV rather then the value of GV itself. This means that the -/// GlobalAddress must be in the base or index register of the address, not the -/// GV offset field. -static bool WindowsGVRequiresExtraLoad(GlobalValue *GV) { - return (GV->hasDLLImportLinkage()); -} - /// isUndefOrInRange - Op is either an undef node or a ConstantSDNode. Return /// true if Op is undef or if its value falls within the specified range (L, H]. static bool isUndefOrInRange(SDOperand Op, unsigned Low, unsigned Hi) { @@ -2904,7 +2879,7 @@ bool X86::isSplatMask(SDNode *N) { bool X86::isSplatLoMask(SDNode *N) { assert(N->getOpcode() == ISD::BUILD_VECTOR); - for (unsigned i = 0, e = N->getNumOperands(); i < e; ++i) + for (unsigned i = 0, e = N->getNumOperands(); i < e; ++i) if (!isUndefOrEqual(N->getOperand(i), 0)) return false; return true; @@ -3034,7 +3009,7 @@ static SDOperand CommuteVectorShuffle(SDOperand Op, SDOperand &V1, /// ShouldXformToMOVHLPS - Return true if the node should be transformed to /// match movhlps. The lower half elements should come from upper half of /// V1 (and in order), and the upper half elements should come from the upper -/// half of V2 (and in order). +/// half of V2 (and in order). static bool ShouldXformToMOVHLPS(SDNode *Mask) { unsigned NumElems = Mask->getNumOperands(); if (NumElems != 4) @@ -3431,7 +3406,7 @@ X86TargetLowering::LowerBUILD_VECTOR(SDOperand Op, SelectionDAG &DAG) { } // Take advantage of the fact GR32 to VR128 scalar_to_vector (i.e. movd) - // clears the upper bits. + // clears the upper bits. // FIXME: we can do the same for v4f32 case when we know both parts of // the lower half come from scalar_to_vector (loadf32). We should do // that in post legalizer dag combiner with target specific hooks. @@ -3502,7 +3477,7 @@ X86TargetLowering::LowerVECTOR_SHUFFLE(SDOperand Op, SelectionDAG &DAG) { if (X86::isMOVLMask(PermMask.Val)) return (V1IsUndef) ? V2 : Op; - + if (X86::isMOVSHDUPMask(PermMask.Val) || X86::isMOVSLDUPMask(PermMask.Val) || X86::isMOVHLPSMask(PermMask.Val) || @@ -3545,7 +3520,7 @@ X86TargetLowering::LowerVECTOR_SHUFFLE(SDOperand Op, SelectionDAG &DAG) { if (V2IsSplat) { // Normalize mask so all entries that point to V2 points to its first - // element then try to match unpck{h|l} again. If match, return a + // element then try to match unpck{h|l} again. If match, return a // new vector_shuffle with the corrected mask. SDOperand NewMask = NormalizeMask(PermMask, DAG); if (NewMask.Val != PermMask.Val) { @@ -3703,7 +3678,7 @@ X86TargetLowering::LowerVECTOR_SHUFFLE(SDOperand Op, SelectionDAG &DAG) { DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, V2, DAG.getNode(ISD::BUILD_VECTOR, MaskVT, &LoMask[0], LoMask.size())); - SDOperand HiShuffle = + SDOperand HiShuffle = DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, V2, DAG.getNode(ISD::BUILD_VECTOR, MaskVT, &HiMask[0], HiMask.size())); @@ -3845,7 +3820,7 @@ X86TargetLowering::LowerSCALAR_TO_VECTOR(SDOperand Op, SelectionDAG &DAG) { return DAG.getNode(X86ISD::S2VEC, Op.getValueType(), AnyExt); } -// ConstantPool, JumpTable, GlobalAddress, and ExternalSymbol are lowered as +// ConstantPool, JumpTable, GlobalAddress, and ExternalSymbol are lowered as // their target countpart wrapped in the X86ISD::Wrapper node. Suppose N is // one of the above mentioned nodes. It has to be wrapped because otherwise // Select(N) returns N. So the raw TargetGlobalAddress nodes, etc. can only @@ -3888,14 +3863,11 @@ X86TargetLowering::LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG) { // the GlobalAddress must be in the base or index register of the address, // not the GV offset field. if (getTargetMachine().getRelocationModel() != Reloc::Static && - DarwinGVRequiresExtraLoad(GV)) - Result = DAG.getLoad(getPointerTy(), DAG.getEntryNode(), Result, NULL, 0); - } else if (Subtarget->isTargetCygwin() || Subtarget->isTargetWindows()) { - // FIXME: What about PIC? - if (WindowsGVRequiresExtraLoad(GV)) + Subtarget->GVRequiresExtraLoad(GV, false)) Result = DAG.getLoad(getPointerTy(), DAG.getEntryNode(), Result, NULL, 0); + } else if (Subtarget->GVRequiresExtraLoad(GV, false)) { + Result = DAG.getLoad(getPointerTy(), DAG.getEntryNode(), Result, NULL, 0); } - return Result; } @@ -4149,7 +4121,7 @@ SDOperand X86TargetLowering::LowerSETCC(SDOperand Op, SelectionDAG &DAG, bool isFP = MVT::isFloatingPoint(Op.getOperand(1).getValueType()); unsigned X86CC; - if (translateX86CC(cast(CC)->get(), isFP, X86CC, + if (translateX86CC(cast(CC)->get(), isFP, X86CC, Op0, Op1, DAG)) { SDOperand Ops1[] = { Chain, Op0, Op1 }; Cond = DAG.getNode(X86ISD::CMP, VTs1, 2, Ops1, 3).getValue(1); @@ -4281,7 +4253,7 @@ SDOperand X86TargetLowering::LowerJumpTable(SDOperand Op, SelectionDAG &DAG) { getTargetMachine().getRelocationModel() == Reloc::PIC_) Result = DAG.getNode(ISD::ADD, getPointerTy(), DAG.getNode(X86ISD::GlobalBaseReg, getPointerTy()), - Result); + Result); } return Result; @@ -4289,13 +4261,13 @@ SDOperand X86TargetLowering::LowerJumpTable(SDOperand Op, SelectionDAG &DAG) { SDOperand X86TargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) { unsigned CallingConv= cast(Op.getOperand(1))->getValue(); - + if (Subtarget->is64Bit()) return LowerX86_64CCCCallTo(Op, DAG); else switch (CallingConv) { default: - assert(0 && "Unsupported calling convention"); + assert(0 && "Unsupported calling convention"); case CallingConv::Fast: if (EnableFastCC) { return LowerFastCCCallTo(Op, DAG, false); @@ -4304,7 +4276,7 @@ SDOperand X86TargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) { case CallingConv::C: case CallingConv::CSRet: return LowerCCCCallTo(Op, DAG); - case CallingConv::X86_StdCall: + case CallingConv::X86_StdCall: return LowerStdCallCCCallTo(Op, DAG); case CallingConv::X86_FastCall: return LowerFastCCCallTo(Op, DAG, true); @@ -4313,7 +4285,7 @@ SDOperand X86TargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) { SDOperand X86TargetLowering::LowerRET(SDOperand Op, SelectionDAG &DAG) { SDOperand Copy; - + switch(Op.getNumOperands()) { default: assert(0 && "Do not know how to return this many arguments!"); @@ -4323,7 +4295,7 @@ SDOperand X86TargetLowering::LowerRET(SDOperand Op, SelectionDAG &DAG) { DAG.getConstant(getBytesToPopOnReturn(), MVT::i16)); case 3: { MVT::ValueType ArgVT = Op.getOperand(1).getValueType(); - + if (MVT::isVector(ArgVT) || (Subtarget->is64Bit() && MVT::isFloatingPoint(ArgVT))) { // Integer or FP vector result -> XMM0. @@ -4403,7 +4375,7 @@ SDOperand X86TargetLowering::LowerRET(SDOperand Op, SelectionDAG &DAG) { DAG.getMachineFunction().addLiveOut(Reg2); } - Copy = DAG.getCopyToReg(Op.getOperand(0), Reg2, Op.getOperand(3), + Copy = DAG.getCopyToReg(Op.getOperand(0), Reg2, Op.getOperand(3), SDOperand()); Copy = DAG.getCopyToReg(Copy, Reg1, Op.getOperand(1), Copy.getValue(1)); break; @@ -4757,7 +4729,7 @@ X86TargetLowering::LowerREADCYCLCECOUNTER(SDOperand Op, SelectionDAG &DAG) { SDOperand rd = DAG.getNode(X86ISD::RDTSC_DAG, Tys, &Ops[0], Ops.size()); Ops.clear(); Ops.push_back(DAG.getCopyFromReg(rd, X86::EAX, MVT::i32, rd.getValue(1))); - Ops.push_back(DAG.getCopyFromReg(Ops[0].getValue(1), X86::EDX, + Ops.push_back(DAG.getCopyFromReg(Ops[0].getValue(1), X86::EDX, MVT::i32, Ops[0].getValue(2))); Ops.push_back(Ops[1].getValue(1)); Tys[0] = Tys[1] = MVT::i32; @@ -4849,8 +4821,8 @@ X86TargetLowering::LowerINTRINSIC_WO_CHAIN(SDOperand Op, SelectionDAG &DAG) { ISD::CondCode CC = ISD::SETCC_INVALID; switch (IntNo) { default: break; - case Intrinsic::x86_sse_comieq_ss: - case Intrinsic::x86_sse2_comieq_sd: + case Intrinsic::x86_sse_comieq_ss: + case Intrinsic::x86_sse2_comieq_sd: Opc = X86ISD::COMI; CC = ISD::SETEQ; break; @@ -5020,7 +4992,7 @@ bool X86TargetLowering::isLegalAddressImmediate(GlobalValue *GV) const { if (RModel == Reloc::Static) return true; else if (RModel == Reloc::DynamicNoPIC) - return !DarwinGVRequiresExtraLoad(GV); + return !(Subtarget->GVRequiresExtraLoad(GV, false)); else return false; } else @@ -5078,7 +5050,7 @@ X86TargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI, const BasicBlock *LLVM_BB = BB->getBasicBlock(); ilist::iterator It = BB; ++It; - + // thisMBB: // ... // TrueVal = ... @@ -5088,7 +5060,7 @@ X86TargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI, MachineBasicBlock *thisMBB = BB; MachineBasicBlock *copy0MBB = new MachineBasicBlock(LLVM_BB); MachineBasicBlock *sinkMBB = new MachineBasicBlock(LLVM_BB); - unsigned Opc = + unsigned Opc = X86::GetCondBranchFromCond((X86::CondCode)MI->getOperand(3).getImm()); BuildMI(BB, Opc, 1).addMBB(sinkMBB); MachineFunction *F = BB->getParent(); @@ -5096,7 +5068,7 @@ X86TargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI, F->getBasicBlockList().insert(It, sinkMBB); // Update machine-CFG edges by first adding all successors of the current // block to the new block which will contain the Phi node for the select. - for(MachineBasicBlock::succ_iterator i = BB->succ_begin(), + for(MachineBasicBlock::succ_iterator i = BB->succ_begin(), e = BB->succ_end(); i != e; ++i) sinkMBB->addSuccessor(*i); // Next, remove all successors of the current block, and add the true @@ -5105,15 +5077,15 @@ X86TargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI, BB->removeSuccessor(BB->succ_begin()); BB->addSuccessor(copy0MBB); BB->addSuccessor(sinkMBB); - + // copy0MBB: // %FalseValue = ... // # fallthrough to sinkMBB BB = copy0MBB; - + // Update machine-CFG edges BB->addSuccessor(sinkMBB); - + // sinkMBB: // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ] // ... @@ -5196,7 +5168,7 @@ X86TargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI, void X86TargetLowering::computeMaskedBitsForTargetNode(const SDOperand Op, uint64_t Mask, - uint64_t &KnownZero, + uint64_t &KnownZero, uint64_t &KnownOne, unsigned Depth) const { unsigned Opc = Op.getOpcode(); @@ -5210,7 +5182,7 @@ void X86TargetLowering::computeMaskedBitsForTargetNode(const SDOperand Op, KnownZero = KnownOne = 0; // Don't know anything. switch (Opc) { default: break; - case X86ISD::SETCC: + case X86ISD::SETCC: KnownZero |= (MVT::getIntVTBitMask(Op.getValueType()) ^ 1ULL); break; } @@ -5369,7 +5341,7 @@ static SDOperand PerformShuffleCombine(SDNode *N, SelectionDAG &DAG, static SDOperand PerformSELECTCombine(SDNode *N, SelectionDAG &DAG, const X86Subtarget *Subtarget) { SDOperand Cond = N->getOperand(0); - + // If we have SSE[12] support, try to form min/max nodes. if (Subtarget->hasSSE2() && (N->getValueType(0) == MVT::f32 || N->getValueType(0) == MVT::f64)) { @@ -5378,7 +5350,7 @@ static SDOperand PerformSELECTCombine(SDNode *N, SelectionDAG &DAG, SDOperand LHS = N->getOperand(1); SDOperand RHS = N->getOperand(2); ISD::CondCode CC = cast(Cond.getOperand(2))->get(); - + unsigned Opcode = 0; if (LHS == Cond.getOperand(0) && RHS == Cond.getOperand(1)) { switch (CC) { @@ -5392,7 +5364,7 @@ static SDOperand PerformSELECTCombine(SDNode *N, SelectionDAG &DAG, case ISD::SETLT: Opcode = X86ISD::FMIN; break; - + case ISD::SETOGT: // (X > Y) ? X : Y -> max case ISD::SETUGT: case ISD::SETGT: @@ -5415,7 +5387,7 @@ static SDOperand PerformSELECTCombine(SDNode *N, SelectionDAG &DAG, case ISD::SETGE: Opcode = X86ISD::FMIN; break; - + case ISD::SETOLE: // (X <= Y) ? Y : X -> max case ISD::SETULE: case ISD::SETLE: @@ -5427,18 +5399,18 @@ static SDOperand PerformSELECTCombine(SDNode *N, SelectionDAG &DAG, break; } } - + if (Opcode) return DAG.getNode(Opcode, N->getValueType(0), LHS, RHS); } - + } return SDOperand(); } -SDOperand X86TargetLowering::PerformDAGCombine(SDNode *N, +SDOperand X86TargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const { SelectionDAG &DAG = DCI.DAG; switch (N->getOpcode()) { @@ -5484,19 +5456,19 @@ isOperandValidForConstraint(SDOperand Op, char Constraint, SelectionDAG &DAG) { case 'i': // Literal immediates are always ok. if (isa(Op)) return Op; - + // If we are in non-pic codegen mode, we allow the address of a global to // be used with 'i'. if (GlobalAddressSDNode *GA = dyn_cast(Op)) { if (getTargetMachine().getRelocationModel() == Reloc::PIC_) return SDOperand(0, 0); - + if (GA->getOpcode() != ISD::TargetGlobalAddress) Op = DAG.getTargetGlobalAddress(GA->getGlobal(), GA->getValueType(0), GA->getOffset()); return Op; } - + // Otherwise, not valid for this mode. return SDOperand(0, 0); } @@ -5522,7 +5494,7 @@ getRegClassForInlineAsmConstraint(const std::string &Constraint, return make_vector(X86::EAX, X86::EDX, X86::ECX, X86::EBX, X86::ESI, X86::EDI, X86::EBP, X86::ESP, 0); else if (VT == MVT::i16) - return make_vector(X86::AX, X86::DX, X86::CX, X86::BX, + return make_vector(X86::AX, X86::DX, X86::CX, X86::BX, X86::SI, X86::DI, X86::BP, X86::SP, 0); else if (VT == MVT::i8) return make_vector(X86::AL, X86::DL, X86::CL, X86::DL, 0); @@ -5532,7 +5504,7 @@ getRegClassForInlineAsmConstraint(const std::string &Constraint, return make_vector(X86::EAX, X86::EDX, X86::ECX, X86::EBX, X86::ESI, X86::EDI, X86::EBP, 0); else if (VT == MVT::i16) - return make_vector(X86::AX, X86::DX, X86::CX, X86::BX, + return make_vector(X86::AX, X86::DX, X86::CX, X86::BX, X86::SI, X86::DI, X86::BP, 0); else if (VT == MVT::i8) return make_vector(X86::AL, X86::DL, X86::CL, X86::DL, 0); @@ -5560,11 +5532,11 @@ getRegClassForInlineAsmConstraint(const std::string &Constraint, return std::vector(); } } - + return std::vector(); } -std::pair +std::pair X86TargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint, MVT::ValueType VT) const { // Use the default implementation in TargetLowering to convert the register @@ -5579,23 +5551,23 @@ X86TargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint, Res.first = X86::ST0; Res.second = X86::RSTRegisterClass; } - + return Res; } - + // Otherwise, check to see if this is a register class of the wrong value // type. For example, we want to map "{ax},i32" -> {eax}, we don't want it to // turn into {ax},{dx}. if (Res.second->hasType(VT)) return Res; // Correct type already, nothing to do. - + // All of the single-register GCC register classes map their values onto // 16-bit register pieces "ax","dx","cx","bx","si","di","bp","sp". If we // really want an 8-bit or 32-bit register, map to the appropriate register // class and return the appropriate register. if (Res.second != X86::GR16RegisterClass) return Res; - + if (VT == MVT::i8) { unsigned DestReg = 0; switch (Res.first) { @@ -5644,7 +5616,6 @@ X86TargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint, Res.second = Res.second = X86::GR64RegisterClass; } } - + return Res; } - diff --git a/lib/Target/X86/X86Subtarget.h b/lib/Target/X86/X86Subtarget.h index 423e2cb743e..c52979711da 100644 --- a/lib/Target/X86/X86Subtarget.h +++ b/lib/Target/X86/X86Subtarget.h @@ -14,6 +14,7 @@ #ifndef X86SUBTARGET_H #define X86SUBTARGET_H +#include "llvm/GlobalValue.h" #include "llvm/Target/TargetSubtarget.h" #include @@ -64,7 +65,7 @@ public: enum { isELF, isCygwin, isDarwin, isWindows } TargetType; - + /// This constructor initializes the data members to match that /// of the specified module. /// @@ -80,8 +81,8 @@ public: /// instruction. This is only used if the src / dst alignment is not DWORD /// aligned. unsigned getMinRepStrSizeThreshold() const { return MinRepStrSizeThreshold; } - - /// ParseSubtargetFeatures - Parses features string setting specified + + /// ParseSubtargetFeatures - Parses features string setting specified /// subtarget options. Definition of function is auto generated by tblgen. void ParseSubtargetFeatures(const std::string &FS, const std::string &CPU); @@ -97,14 +98,31 @@ public: bool hasSSE3() const { return X86SSELevel >= SSE3; } bool has3DNow() const { return X863DNowLevel >= ThreeDNow; } bool has3DNowA() const { return X863DNowLevel >= ThreeDNowA; } - + bool isFlavorAtt() const { return AsmFlavor == att; } bool isFlavorIntel() const { return AsmFlavor == intel; } bool isTargetDarwin() const { return TargetType == isDarwin; } bool isTargetELF() const { return TargetType == isELF; } bool isTargetWindows() const { return TargetType == isWindows; } - bool isTargetCygwin() const { return TargetType == isCygwin; } + bool isTargetCygwin() const { return TargetType == isCygwin; } + + /// True if accessing the GV requires an extra load. For Windows, dllimported + /// symbols are indirect, loading the value at address GV rather then the + /// value of GV itself. This means that the GlobalAddress must be in the base + /// or index register of the address, not the GV offset field. + bool GVRequiresExtraLoad(const GlobalValue* GV, bool isDirectCall) const + { + if (isTargetDarwin()) { + return (!isDirectCall && + (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() || + (GV->isExternal() && !GV->hasNotBeenReadFromBytecode()))); + } else if (isTargetCygwin() || isTargetWindows()) { + return (GV->hasDLLImportLinkage()); + } + + return false; + } }; namespace X86 {