forked from OSchip/llvm-project
- Clean up the lowering and selection code of ConstantPool, GlobalAddress,
and ExternalSymbol. - Use C++ code (rather than tblgen'd selection code) to match the above mentioned leaf nodes. Do not mutate and nodes and do not record the selection in CodeGenMap. These nodes should be safe to duplicate. This is a performance win. llvm-svn: 26335
This commit is contained in:
parent
e7c0ffb3a0
commit
e0ed6ec13f
|
@ -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:
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)>;
|
||||
|
|
Loading…
Reference in New Issue