aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Target/X86/X86ISelDAGToDAG.cpp71
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp31
-rw-r--r--lib/Target/X86/X86ISelLowering.h6
-rw-r--r--lib/Target/X86/X86InstrInfo.td10
4 files changed, 81 insertions, 37 deletions
diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp
index 1ff4415dac..3cd87c0b10 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<ConstantPoolSDNode>(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<GlobalAddressSDNode>(N)->getGlobal();
return false;
}
break;
- case X86ISD::TGAWrapper:
- if (AM.GV == 0) {
- AM.GV = cast<GlobalAddressSDNode>(N.getOperand(0))->getGlobal();
- return false;
+ case X86ISD::Wrapper:
+ if (ConstantPoolSDNode *CP =
+ dyn_cast<ConstantPoolSDNode>(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<GlobalAddressSDNode>(N.getOperand(0))) {
+ if (AM.GV == 0) {
+ AM.GV = cast<GlobalAddressSDNode>(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<GlobalAddressSDNode>(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 <xxx> 0
+ // 0xa59e740: i32 = X86ISD::Wrapper 0xa59e4a0
+ // ...
+ // 0xa59e880: i32 = add 0xa59e740, 0xa59e800
+ // ...
+ // 0xa59e880: <multiple use>
+ // 0xa59e970: i32 = add 0xa59e880, 0xa59e910
+ // ...
+ // 0xa59ea60: i32,ch = load 0xa589780, 0xa59e970, 0xa59ea00
+ // ...
+ // 0xa59e880: <multiple use>
+ // 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 b7a315a8ad..e2f22ae0a3 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<ConstantPoolSDNode>(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<X86Subtarget>().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<GlobalAddressSDNode>(Op)->getGlobal();
+ SDOperand Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(),
+ DAG.getTargetGlobalAddress(GV, getPointerTy()));
if (getTargetMachine().
getSubtarget<X86Subtarget>().isTargetDarwin()) {
- GlobalValue *GV = cast<GlobalAddressSDNode>(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<ExternalSymbolSDNode>(Op)->getSymbol();
+ SDOperand Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(),
+ DAG.getTargetExternalSymbol(Sym, getPointerTy()));
+ if (getTargetMachine().
+ getSubtarget<X86Subtarget>().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 de9948cf3f..414a07086a 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 0782f75566..1e8d222fc0 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<OtherVT>;
// Define X86 specific addressing mode.
def addr : ComplexPattern<i32, 4, "SelectAddr", []>;
def leaaddr : ComplexPattern<i32, 4, "SelectLEAAddr",
- [add, frameindex, constpool]>;
+ [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)>;