diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp index 1ff4415dac1..3cd87c0b101 100644 --- a/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -295,7 +295,6 @@ bool X86DAGToDAGISel::MatchAddress(SDOperand N, X86ISelAddressMode &AM, break; case ISD::ConstantPool: - case ISD::TargetConstantPool: if (AM.BaseType == X86ISelAddressMode::RegBase && AM.Base.Reg.Val == 0) { if (ConstantPoolSDNode *CP = dyn_cast(N)) { AM.BaseType = X86ISelAddressMode::ConstantPoolBase; @@ -307,17 +306,27 @@ bool X86DAGToDAGISel::MatchAddress(SDOperand N, X86ISelAddressMode &AM, break; case ISD::GlobalAddress: - case ISD::TargetGlobalAddress: if (AM.GV == 0) { AM.GV = cast(N)->getGlobal(); return false; } break; - case X86ISD::TGAWrapper: - if (AM.GV == 0) { - AM.GV = cast(N.getOperand(0))->getGlobal(); - return false; + case X86ISD::Wrapper: + if (ConstantPoolSDNode *CP = + dyn_cast(N.getOperand(0))) { + if (AM.BaseType == X86ISelAddressMode::RegBase && AM.Base.Reg.Val == 0) { + AM.BaseType = X86ISelAddressMode::ConstantPoolBase; + AM.Base.Reg = CurDAG->getTargetConstantPool(CP->get(), MVT::i32, + CP->getAlignment()); + return false; + } + } else if (GlobalAddressSDNode *G = + dyn_cast(N.getOperand(0))) { + if (AM.GV == 0) { + AM.GV = cast(N.getOperand(0))->getGlobal(); + return false; + } } break; @@ -484,9 +493,11 @@ bool X86DAGToDAGISel::SelectLEAAddr(SDOperand N, SDOperand &Base, Complexity++; if (SelectIndex) Complexity++; - if (AM.GV) + if (AM.GV) { Complexity++; - else if (AM.Disp > 1) + if (AM.Disp) + Complexity++; + } else if (AM.Disp > 1) Complexity++; // Suppose base == %eax and it has multiple uses, then instead of // movl %eax, %ecx @@ -574,13 +585,43 @@ void X86DAGToDAGISel::Select(SDOperand &Result, SDOperand N) { switch (Opcode) { default: break; - case X86ISD::TGAWrapper: { - GlobalValue *GV = cast(N.getOperand(0))->getGlobal(); - SDOperand TGA = CurDAG->getTargetGlobalAddress(GV, MVT::i32); - Result = CodeGenMap[N] = - SDOperand(CurDAG->getTargetNode(X86::MOV32ri, MVT::i32, TGA), 0); + case X86ISD::GlobalBaseReg: + Result = getGlobalBaseReg(); + return; + + case X86ISD::Wrapper: { + // It's beneficial to manully select the wrapper nodes here rather + // then using tablgen'd code to match this. We do not want to mutate the + // node to MOV32ri and we do not want to record this in CodeGenMap. + // We want to allow the wrapped leaf nodes be duplicated so they can + // be used in addressing modes. + // e.g. + // 0xa59e4a0: i32 = TargetGlobalAddress 0 + // 0xa59e740: i32 = X86ISD::Wrapper 0xa59e4a0 + // ... + // 0xa59e880: i32 = add 0xa59e740, 0xa59e800 + // ... + // 0xa59e880: + // 0xa59e970: i32 = add 0xa59e880, 0xa59e910 + // ... + // 0xa59ea60: i32,ch = load 0xa589780, 0xa59e970, 0xa59ea00 + // ... + // 0xa59e880: + // 0xa59eb60: ch = CopyToReg 0xa59ea60:1, 0xa59eaf0, 0xa59e880 + // By allowing the TargetGlobalAddress to be duplicated, it can appear + // in the load address as well as an operand of the add. + Result = SDOperand(CurDAG->getTargetNode(X86::MOV32ri, MVT::i32, + N.getOperand(0)), 0); +#ifndef NDEBUG + DEBUG(std::cerr << std::string(Indent-2, ' ')); + DEBUG(std::cerr << "== "); + DEBUG(Result.Val->dump(CurDAG)); + DEBUG(std::cerr << "\n"); + Indent -= 2; +#endif return; } + case ISD::MULHU: case ISD::MULHS: { if (Opcode == ISD::MULHU) @@ -666,10 +707,6 @@ void X86DAGToDAGISel::Select(SDOperand &Result, SDOperand N) { return; } - case X86ISD::GlobalBaseReg: - Result = getGlobalBaseReg(); - return; - case ISD::SDIV: case ISD::UDIV: case ISD::SREM: diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index b7a315a8ad8..e2f22ae0a3e 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -165,6 +165,7 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM) // Darwin ABI issue. setOperationAction(ISD::ConstantPool , MVT::i32 , Custom); setOperationAction(ISD::GlobalAddress , MVT::i32 , Custom); + setOperationAction(ISD::ExternalSymbol , MVT::i32 , Custom); // 64-bit addm sub, shl, sra, srl (iff 32-bit x86) setOperationAction(ISD::SHL_PARTS , MVT::i32 , Custom); setOperationAction(ISD::SRA_PARTS , MVT::i32 , Custom); @@ -1830,9 +1831,9 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { } case ISD::ConstantPool: { ConstantPoolSDNode *CP = cast(Op); - SDOperand Result = - DAG.getTargetConstantPool(CP->get(), getPointerTy(), CP->getAlignment()); - // Only lower ConstantPool on Darwin. + SDOperand Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(), + DAG.getTargetConstantPool(CP->get(), getPointerTy(), + CP->getAlignment())); if (getTargetMachine().getSubtarget().isTargetDarwin()) { // With PIC, the address is actually $g + Offset. if (getTargetMachine().getRelocationModel() == Reloc::PIC) @@ -1843,13 +1844,11 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { return Result; } case ISD::GlobalAddress: { - SDOperand Result; - // Only lower GlobalAddress on Darwin. + GlobalValue *GV = cast(Op)->getGlobal(); + SDOperand Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(), + DAG.getTargetGlobalAddress(GV, getPointerTy())); if (getTargetMachine(). getSubtarget().isTargetDarwin()) { - GlobalValue *GV = cast(Op)->getGlobal(); - Result = DAG.getNode(X86ISD::TGAWrapper, getPointerTy(), - DAG.getTargetGlobalAddress(GV, getPointerTy())); // With PIC, the address is actually $g + Offset. if (getTargetMachine().getRelocationModel() == Reloc::PIC) Result = DAG.getNode(ISD::ADD, getPointerTy(), @@ -1868,6 +1867,20 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { return Result; } + case ISD::ExternalSymbol: { + const char *Sym = cast(Op)->getSymbol(); + SDOperand Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(), + DAG.getTargetExternalSymbol(Sym, getPointerTy())); + if (getTargetMachine(). + getSubtarget().isTargetDarwin()) { + // With PIC, the address is actually $g + Offset. + if (getTargetMachine().getRelocationModel() == Reloc::PIC) + Result = DAG.getNode(ISD::ADD, getPointerTy(), + DAG.getNode(X86ISD::GlobalBaseReg, getPointerTy()), Result); + } + + return Result; + } case ISD::VASTART: { // vastart just stores the address of the VarArgsFrameIndex slot into the // memory location argument. @@ -1977,7 +1990,7 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const { case X86ISD::REP_MOVS: return "X86ISD::RET_MOVS"; case X86ISD::LOAD_PACK: return "X86ISD::LOAD_PACK"; case X86ISD::GlobalBaseReg: return "X86ISD::GlobalBaseReg"; - case X86ISD::TGAWrapper: return "X86ISD::TGAWrapper"; + case X86ISD::Wrapper: return "X86ISD::Wrapper"; } } diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h index de9948cf3fb..414a07086a4 100644 --- a/lib/Target/X86/X86ISelLowering.h +++ b/lib/Target/X86/X86ISelLowering.h @@ -142,9 +142,9 @@ namespace llvm { /// at function entry, used for PIC code. GlobalBaseReg, - /// TGAWrapper - A wrapper node for TargetGlobalAddress, only used on - /// Darwin. - TGAWrapper, + /// TCPWrapper - A wrapper node for TargetConstantPool, + /// TargetExternalSymbol, and TargetGlobalAddress. + Wrapper, }; // X86 specific condition code. These correspond to X86_*_COND in diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td index 0782f75566f..1e8d222fc0b 100644 --- a/lib/Target/X86/X86InstrInfo.td +++ b/lib/Target/X86/X86InstrInfo.td @@ -117,11 +117,9 @@ def X86rep_movs: SDNode<"X86ISD::REP_MOVS", SDTX86RepStr, def X86rdtsc : SDNode<"X86ISD::RDTSC_DAG",SDTX86RdTsc, [SDNPHasChain, SDNPOutFlag]>; -def X86loadp : SDNode<"X86ISD::LOAD_PACK", SDTLoad, +def X86loadp : SDNode<"X86ISD::LOAD_PACK", SDTLoad, [SDNPHasChain]>; -def X86TGAWrapper : SDNode<"X86ISD::TGAWrapper", SDTIntUnaryOp>; - //===----------------------------------------------------------------------===// // X86 Operand Definitions. // @@ -167,7 +165,7 @@ def brtarget : Operand; // Define X86 specific addressing mode. def addr : ComplexPattern; def leaaddr : ComplexPattern; + [add, frameindex]>; //===----------------------------------------------------------------------===// // X86 Instruction Format Definitions. @@ -2354,10 +2352,6 @@ def MOV32r0 : I<0x31, MRMInitReg, (ops R32:$dst), // Non-Instruction Patterns //===----------------------------------------------------------------------===// -// GlobalAddress and ExternalSymbol -def : Pat<(i32 globaladdr:$dst), (MOV32ri tglobaladdr:$dst)>; -def : Pat<(i32 externalsym:$dst), (MOV32ri texternalsym:$dst)>; - // Calls def : Pat<(X86call tglobaladdr:$dst), (CALLpcrel32 tglobaladdr:$dst)>;