- Use a different wrapper node for RIP-relative GV, etc.

- Proper support for both small static and PIC modes under X86-64
- Some (non-optimal) support for medium modes.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@32046 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng 2006-11-30 21:55:46 +00:00
parent 2bbff6d173
commit 0085a28d13
5 changed files with 81 additions and 62 deletions

View File

@ -590,63 +590,19 @@ bool X86DAGToDAGISel::MatchAddress(SDOperand N, X86ISelAddressMode &AM,
break;
}
case ISD::TargetConstantPool:
if (AM.BaseType == X86ISelAddressMode::RegBase &&
AM.Base.Reg.Val == 0 &&
AM.CP == 0) {
ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(N);
AM.CP = CP->getConstVal();
AM.Align = CP->getAlignment();
AM.Disp += CP->getOffset();
return false;
}
break;
case ISD::TargetGlobalAddress:
if (AM.BaseType == X86ISelAddressMode::RegBase &&
AM.Base.Reg.Val == 0 &&
AM.GV == 0) {
GlobalAddressSDNode *G = cast<GlobalAddressSDNode>(N);
AM.GV = G->getGlobal();
AM.Disp += G->getOffset();
return false;
}
break;
case ISD::TargetExternalSymbol:
if (isRoot &&
AM.BaseType == X86ISelAddressMode::RegBase &&
AM.Base.Reg.Val == 0) {
ExternalSymbolSDNode *S = cast<ExternalSymbolSDNode>(N.getOperand(0));
AM.ES = S->getSymbol();
return false;
}
break;
case ISD::TargetJumpTable:
if (isRoot &&
AM.BaseType == X86ISelAddressMode::RegBase &&
AM.Base.Reg.Val == 0) {
JumpTableSDNode *J = cast<JumpTableSDNode>(N.getOperand(0));
AM.JT = J->getIndex();
return false;
}
break;
case X86ISD::Wrapper:
case X86ISD::WrapperRIP: {
bool isRIP = N.getOpcode() == X86ISD::WrapperRIP;
// Under X86-64 non-small code model, GV (and friends) are 64-bits.
if (!isRIP && Subtarget->is64Bit() && TM.getCodeModel() != CodeModel::Small)
break;
// If value is available in a register both base and index components have
// been picked, we can't fit the result available in the register in the
// addressing mode. Duplicate GlobalAddress or ConstantPool as displacement.
// Can't fit GV or CP in addressing mode for X86-64 medium or large code
// model since the displacement field is 32-bit. Ok for small code model.
// For X86-64 PIC code, only allow GV / CP + displacement so we can use RIP
// relative addressing mode.
if (Subtarget->is64Bit() && TM.getCodeModel() != CodeModel::Small)
break;
if (!Available || (AM.Base.Reg.Val && AM.IndexReg.Val)) {
bool isRIP = Subtarget->is64Bit();
// For X86-64 PIC code, only allow GV / CP + displacement so we can use
// RIP relative addressing mode.
if (isRIP &&
(AM.Base.Reg.Val || AM.Scale > 1 || AM.IndexReg.Val ||
AM.BaseType == X86ISelAddressMode::FrameIndexBase))
@ -683,6 +639,7 @@ bool X86DAGToDAGISel::MatchAddress(SDOperand N, X86ISelAddressMode &AM,
}
}
break;
}
case ISD::FrameIndex:
if (AM.BaseType == X86ISelAddressMode::RegBase && AM.Base.Reg.Val == 0) {
@ -1040,7 +997,8 @@ SDNode *X86DAGToDAGISel::Select(SDOperand N) {
SDOperand N0 = N.getOperand(0);
SDOperand N1 = N.getOperand(1);
if (N.Val->getValueType(0) == PtrVT &&
N0.getOpcode() == X86ISD::Wrapper &&
(N0.getOpcode() == X86ISD::Wrapper
|| N0.getOpcode() == X86ISD::WrapperRIP) &&
N1.getOpcode() == ISD::Constant) {
unsigned Offset = (unsigned)cast<ConstantSDNode>(N1)->getValue();
SDOperand C(0, 0);

View File

@ -3832,8 +3832,15 @@ X86TargetLowering::LowerConstantPool(SDOperand Op, SelectionDAG &DAG) {
SDOperand Result = DAG.getTargetConstantPool(CP->getConstVal(),
getPointerTy(),
CP->getAlignment());
// Use X86ISD::WrapperRIP if we are in X86-64 small / medium PIC mode.
TargetMachine &tm = getTargetMachine();
unsigned WrapperOpcode = (Subtarget->is64Bit() &&
(tm.getCodeModel() == CodeModel::Small ||
tm.getCodeModel() == CodeModel::Medium) &&
tm.getRelocationModel() == Reloc::PIC_)
? X86ISD::WrapperRIP : X86ISD::Wrapper;
Result = DAG.getNode(WrapperOpcode, getPointerTy(), Result);
if (Subtarget->isTargetDarwin()) {
Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(), Result);
// With PIC, the address is actually $g + Offset.
if (!Subtarget->is64Bit() &&
getTargetMachine().getRelocationModel() == Reloc::PIC_)
@ -3848,8 +3855,15 @@ SDOperand
X86TargetLowering::LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG) {
GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
SDOperand Result = DAG.getTargetGlobalAddress(GV, getPointerTy());
// Use X86ISD::WrapperRIP if we are in X86-64 small / medium PIC mode.
TargetMachine &tm = getTargetMachine();
unsigned WrapperOpcode = (Subtarget->is64Bit() &&
(tm.getCodeModel() == CodeModel::Small ||
tm.getCodeModel() == CodeModel::Medium) &&
tm.getRelocationModel() == Reloc::PIC_)
? X86ISD::WrapperRIP : X86ISD::Wrapper;
Result = DAG.getNode(WrapperOpcode, getPointerTy(), Result);
if (Subtarget->isTargetDarwin()) {
Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(), Result);
// With PIC, the address is actually $g + Offset.
if (!Subtarget->is64Bit() &&
getTargetMachine().getRelocationModel() == Reloc::PIC_)
@ -3865,7 +3879,6 @@ X86TargetLowering::LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG) {
Subtarget->GVRequiresExtraLoad(GV, false))
Result = DAG.getLoad(getPointerTy(), DAG.getEntryNode(), Result, NULL, 0);
} else if (Subtarget->GVRequiresExtraLoad(GV, false)) {
Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(), Result);
Result = DAG.getLoad(getPointerTy(), DAG.getEntryNode(), Result, NULL, 0);
}
@ -3876,8 +3889,15 @@ SDOperand
X86TargetLowering::LowerExternalSymbol(SDOperand Op, SelectionDAG &DAG) {
const char *Sym = cast<ExternalSymbolSDNode>(Op)->getSymbol();
SDOperand Result = DAG.getTargetExternalSymbol(Sym, getPointerTy());
// Use X86ISD::WrapperRIP if we are in X86-64 small / medium PIC mode.
TargetMachine &tm = getTargetMachine();
unsigned WrapperOpcode = (Subtarget->is64Bit() &&
(tm.getCodeModel() == CodeModel::Small ||
tm.getCodeModel() == CodeModel::Medium) &&
tm.getRelocationModel() == Reloc::PIC_)
? X86ISD::WrapperRIP : X86ISD::Wrapper;
Result = DAG.getNode(WrapperOpcode, getPointerTy(), Result);
if (Subtarget->isTargetDarwin()) {
Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(), Result);
// With PIC, the address is actually $g + Offset.
if (!Subtarget->is64Bit() &&
getTargetMachine().getRelocationModel() == Reloc::PIC_)
@ -4244,8 +4264,15 @@ SDOperand X86TargetLowering::LowerBRCOND(SDOperand Op, SelectionDAG &DAG) {
SDOperand X86TargetLowering::LowerJumpTable(SDOperand Op, SelectionDAG &DAG) {
JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
SDOperand Result = DAG.getTargetJumpTable(JT->getIndex(), getPointerTy());
// Use X86ISD::WrapperRIP if we are in X86-64 small / medium PIC mode.
TargetMachine &tm = getTargetMachine();
unsigned WrapperOpcode = (Subtarget->is64Bit() &&
(tm.getCodeModel() == CodeModel::Small ||
tm.getCodeModel() == CodeModel::Medium) &&
tm.getRelocationModel() == Reloc::PIC_)
? X86ISD::WrapperRIP : X86ISD::Wrapper;
Result = DAG.getNode(WrapperOpcode, getPointerTy(), Result);
if (Subtarget->isTargetDarwin()) {
Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(), Result);
// With PIC, the address is actually $g + Offset.
if (!Subtarget->is64Bit() &&
getTargetMachine().getRelocationModel() == Reloc::PIC_)
@ -4978,6 +5005,7 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const {
case X86ISD::LOAD_UA: return "X86ISD::LOAD_UA";
case X86ISD::GlobalBaseReg: return "X86ISD::GlobalBaseReg";
case X86ISD::Wrapper: return "X86ISD::Wrapper";
case X86ISD::WrapperRIP: return "X86ISD::WrapperRIP";
case X86ISD::S2VEC: return "X86ISD::S2VEC";
case X86ISD::PEXTRW: return "X86ISD::PEXTRW";
case X86ISD::PINSRW: return "X86ISD::PINSRW";
@ -5220,12 +5248,13 @@ static SDOperand getShuffleScalarElt(SDNode *N, unsigned i, SelectionDAG &DAG) {
/// isGAPlusOffset - Returns true (and the GlobalValue and the offset) if the
/// node is a GlobalAddress + an offset.
static bool isGAPlusOffset(SDNode *N, GlobalValue* &GA, int64_t &Offset) {
if (N->getOpcode() == X86ISD::Wrapper) {
unsigned Opc = N->getOpcode();
if (Opc == X86ISD::Wrapper || Opc == X86ISD::WrapperRIP) {
if (dyn_cast<GlobalAddressSDNode>(N->getOperand(0))) {
GA = cast<GlobalAddressSDNode>(N->getOperand(0))->getGlobal();
return true;
}
} else if (N->getOpcode() == ISD::ADD) {
} else if (Opc == ISD::ADD) {
SDOperand N1 = N->getOperand(0);
SDOperand N2 = N->getOperand(1);
if (isGAPlusOffset(N1.Val, GA, Offset)) {

View File

@ -150,6 +150,10 @@ namespace llvm {
/// TargetExternalSymbol, and TargetGlobalAddress.
Wrapper,
/// WrapperRIP - Special wrapper used under X86-64 PIC mode for RIP
/// relative displacements.
WrapperRIP,
/// S2VEC - X86 version of SCALAR_TO_VECTOR. The destination base does not
/// have to match the operand type.
S2VEC,

View File

@ -84,7 +84,8 @@ def X86rep_movs: SDNode<"X86ISD::REP_MOVS", SDTX86RepStr,
def X86rdtsc : SDNode<"X86ISD::RDTSC_DAG",SDTX86RdTsc,
[SDNPHasChain, SDNPOutFlag]>;
def X86Wrapper : SDNode<"X86ISD::Wrapper", SDTX86Wrapper>;
def X86Wrapper : SDNode<"X86ISD::Wrapper", SDTX86Wrapper>;
def X86WrapperRIP : SDNode<"X86ISD::WrapperRIP", SDTX86Wrapper>;
//===----------------------------------------------------------------------===//
// X86 Operand Definitions.
@ -169,6 +170,8 @@ def HasSSE3 : Predicate<"Subtarget->hasSSE3()">;
def FPStack : Predicate<"!Subtarget->hasSSE2()">;
def In32BitMode : Predicate<"!Subtarget->is64Bit()">;
def In64BitMode : Predicate<"Subtarget->is64Bit()">;
def SmallCode : Predicate<"TM.getCodeModel() == CodeModel::Small">;
def NotSmallCode :Predicate<"TM.getCodeModel() != CodeModel::Small">;
//===----------------------------------------------------------------------===//
// X86 specific pattern fragments.

View File

@ -36,7 +36,8 @@ def lea64_32mem : Operand<i32> {
// Complex Pattern Definitions...
//
def lea64addr : ComplexPattern<i64, 4, "SelectLEAAddr",
[add, mul, shl, or, frameindex, X86Wrapper], []>;
[add, mul, shl, or, frameindex, X86WrapperRIP],
[]>;
//===----------------------------------------------------------------------===//
// Instruction templates...
@ -1020,6 +1021,30 @@ def MOV64ri64i32 : Ii32<0xB8, AddRegFrm, (ops GR64:$dst, i64i32imm:$src),
// Non-Instruction Patterns
//===----------------------------------------------------------------------===//
// ConstantPool GlobalAddress, ExternalSymbol, and JumpTable
def : Pat<(i64 (X86Wrapper tconstpool :$dst)),
(MOV64ri32 tconstpool :$dst)>, Requires<[SmallCode]>;
def : Pat<(i64 (X86Wrapper tjumptable :$dst)),
(MOV64ri32 tjumptable :$dst)>, Requires<[SmallCode]>;
def : Pat<(i64 (X86Wrapper tglobaladdr :$dst)),
(MOV64ri32 tglobaladdr :$dst)>, Requires<[SmallCode]>;
def : Pat<(i64 (X86Wrapper texternalsym:$dst)),
(MOV64ri32 texternalsym:$dst)>, Requires<[SmallCode]>;
def : Pat<(i64 (X86Wrapper tconstpool :$dst)),
(MOV64ri tconstpool :$dst)>, Requires<[NotSmallCode]>;
def : Pat<(i64 (X86Wrapper tjumptable :$dst)),
(MOV64ri tjumptable :$dst)>, Requires<[NotSmallCode]>;
def : Pat<(i64 (X86Wrapper tglobaladdr :$dst)),
(MOV64ri tglobaladdr :$dst)>, Requires<[NotSmallCode]>;
def : Pat<(i64 (X86Wrapper texternalsym:$dst)),
(MOV64ri texternalsym:$dst)>, Requires<[NotSmallCode]>;
def : Pat<(store (i64 (X86Wrapper tglobaladdr:$src)), addr:$dst),
(MOV64mi32 addr:$dst, tglobaladdr:$src)>, Requires<[SmallCode]>;
def : Pat<(store (i64 (X86Wrapper texternalsym:$src)), addr:$dst),
(MOV64mi32 addr:$dst, texternalsym:$src)>, Requires<[SmallCode]>;
// Calls
// Direct PC relative function call for small code model. 32-bit displacement
// sign extended to 64-bit.