[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp X86InstrInfo.td
Evan Cheng
evan.cheng at apple.com
Wed Dec 7 18:01:47 PST 2005
Changes in directory llvm/lib/Target/X86:
X86ISelDAGToDAG.cpp updated: 1.6 -> 1.7
X86InstrInfo.td updated: 1.148 -> 1.149
---
Log message:
* Added intelligence to X86 LEA addressing mode matching routine so it returns
false if the match is not profitable. e.g. leal 1(%eax), %eax.
* Added patterns for X86 integer loads and LEA32.
---
Diffs of the changes: (+103 -84)
X86ISelDAGToDAG.cpp | 158 +++++++++++++++++++++++++++-------------------------
X86InstrInfo.td | 29 +++++----
2 files changed, 103 insertions(+), 84 deletions(-)
Index: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
diff -u llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.6 llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.7
--- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.6 Wed Nov 30 18:43:55 2005
+++ llvm/lib/Target/X86/X86ISelDAGToDAG.cpp Wed Dec 7 20:01:35 2005
@@ -36,6 +36,7 @@
enum {
RegBase,
FrameIndexBase,
+ ConstantPoolBase
} BaseType;
struct { // This is really a union, discriminated by BaseType!
@@ -94,8 +95,11 @@
private:
SDOperand Select(SDOperand N);
- void SelectAddress(SDOperand N, X86ISelAddressMode &AM);
bool MatchAddress(SDOperand N, X86ISelAddressMode &AM);
+ bool SelectAddr(SDOperand N, SDOperand &Base, SDOperand &Scale,
+ SDOperand &Index, SDOperand &Disp);
+ bool SelectLEAAddr(SDOperand N, SDOperand &Base, SDOperand &Scale,
+ SDOperand &Index, SDOperand &Disp);
/// getI8Imm - Return a target constant with the specified value, of type
/// i8.
@@ -130,23 +134,6 @@
ScheduleAndEmitDAG(DAG);
}
-/// SelectAddress - Pattern match the maximal addressing mode for this node.
-void X86DAGToDAGISel::SelectAddress(SDOperand N, X86ISelAddressMode &AM) {
- MatchAddress(N, AM);
-
- if (AM.BaseType == X86ISelAddressMode::RegBase) {
- if (AM.Base.Reg.Val)
- AM.Base.Reg = Select(AM.Base.Reg);
- else
- AM.Base.Reg = CurDAG->getRegister(0, MVT::i32);
- }
- if (!AM.IndexReg.Val) {
- AM.IndexReg = CurDAG->getRegister(0, MVT::i32);
- } else {
- AM.IndexReg = Select(AM.IndexReg);
- }
-}
-
/// FIXME: copied from X86ISelPattern.cpp
/// MatchAddress - Add the specified node to the specified addressing mode,
/// returning true if it cannot be done. This just pattern matches for the
@@ -161,6 +148,17 @@
return false;
}
break;
+
+ case ISD::ConstantPool:
+ if (AM.BaseType == X86ISelAddressMode::RegBase && AM.Base.Reg.Val == 0) {
+ if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(N)) {
+ AM.BaseType = X86ISelAddressMode::ConstantPoolBase;
+ AM.Base.Reg = CurDAG->getTargetConstantPool(CP->get(), MVT::i32);
+ return false;
+ }
+ }
+ break;
+
case ISD::GlobalAddress:
if (AM.GV == 0) {
GlobalValue *GV = cast<GlobalAddressSDNode>(N)->getGlobal();
@@ -177,9 +175,11 @@
}
}
break;
+
case ISD::Constant:
AM.Disp += cast<ConstantSDNode>(N)->getValue();
return false;
+
case ISD::SHL:
if (AM.IndexReg.Val == 0 && AM.Scale == 1)
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.Val->getOperand(1))) {
@@ -204,6 +204,7 @@
}
}
break;
+
case ISD::MUL:
// X*[3,5,9] -> X+X*[2,4,8]
if (AM.IndexReg.Val == 0 && AM.BaseType == X86ISelAddressMode::RegBase &&
@@ -266,6 +267,67 @@
return false;
}
+/// SelectAddr - returns true if it is able pattern match an addressing mode.
+/// It returns the operands which make up the maximal addressing mode it can
+/// match by reference.
+bool X86DAGToDAGISel::SelectAddr(SDOperand N, SDOperand &Base, SDOperand &Scale,
+ SDOperand &Index, SDOperand &Disp) {
+ X86ISelAddressMode AM;
+ if (!MatchAddress(N, AM)) {
+ if (AM.BaseType == X86ISelAddressMode::RegBase) {
+ if (AM.Base.Reg.Val)
+ AM.Base.Reg = Select(AM.Base.Reg);
+ else
+ AM.Base.Reg = CurDAG->getRegister(0, MVT::i32);
+ }
+ if (AM.IndexReg.Val)
+ AM.IndexReg = Select(AM.IndexReg);
+ else
+ AM.IndexReg = CurDAG->getRegister(0, MVT::i32);
+
+ Base = (AM.BaseType == X86ISelAddressMode::FrameIndexBase) ?
+ CurDAG->getTargetFrameIndex(AM.Base.FrameIndex, MVT::i32) : AM.Base.Reg;
+ Scale = getI8Imm (AM.Scale);
+ Index = AM.IndexReg;
+ Disp = AM.GV ? CurDAG->getTargetGlobalAddress(AM.GV, MVT::i32, AM.Disp)
+ : getI32Imm(AM.Disp);
+ return true;
+ }
+ return false;
+}
+
+static bool isRegister0(SDOperand Op)
+{
+ if (RegisterSDNode *R = dyn_cast<RegisterSDNode>(Op))
+ return (R->getReg() == 0);
+ return false;
+}
+
+/// SelectLEAAddr - it calls SelectAddr and determines if the maximal addressing
+/// mode it matches can be cost effectively emitted as an LEA instruction.
+/// For X86, it always is unless it's just a (Reg + const).
+bool X86DAGToDAGISel::SelectLEAAddr(SDOperand N, SDOperand &Base, SDOperand &Scale,
+ SDOperand &Index, SDOperand &Disp) {
+ if (SelectAddr(N, Base, Scale, Index, Disp)) {
+ if (!isRegister0(Base)) {
+ unsigned Complexity = 0;
+ if ((unsigned)cast<ConstantSDNode>(Scale)->getValue() > 1)
+ Complexity++;
+ if (!isRegister0(Index))
+ Complexity++;
+ if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Disp)) {
+ if (!CN->isNullValue()) Complexity++;
+ } else {
+ Complexity++;
+ }
+ return (Complexity > 1);
+ }
+ return true;
+ } else {
+ return false;
+ }
+}
+
SDOperand X86DAGToDAGISel::Select(SDOperand Op) {
SDNode *N = Op.Val;
MVT::ValueType OpVT = N->getValueType(0);
@@ -326,51 +388,9 @@
Chain);
}
- case ISD::LOAD: {
- switch (OpVT) {
- default: assert(0 && "Cannot load this type!");
- case MVT::i1:
- case MVT::i8: Opc = X86::MOV8rm; break;
- case MVT::i16: Opc = X86::MOV16rm; break;
- case MVT::i32: Opc = X86::MOV32rm; break;
- case MVT::f32: Opc = X86::MOVSSrm; break;
- case MVT::f64: Opc = X86::FLD64m; ContainsFPCode = true; break;
- }
-
- if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(N->getOperand(1))){
- unsigned CPIdx = BB->getParent()->getConstantPool()->
- getConstantPoolIndex(CP->get());
- // ???
- assert(0 && "Can't handle load from constant pool!");
- } else {
- X86ISelAddressMode AM;
- SDOperand Chain = Select(N->getOperand(0)); // Token chain.
-
- SelectAddress(N->getOperand(1), AM);
- SDOperand Scale = getI8Imm (AM.Scale);
- SDOperand Disp = AM.GV
- ? CurDAG->getTargetGlobalAddress(AM.GV, MVT::i32, AM.Disp)
- : getI32Imm(AM.Disp);
- if (AM.BaseType == X86ISelAddressMode::RegBase) {
- return CurDAG->SelectNodeTo(N, Opc, OpVT, MVT::Other,
- AM.Base.Reg, Scale, AM.IndexReg, Disp,
- Chain)
- .getValue(Op.ResNo);
- } else {
- SDOperand Base = CurDAG->getFrameIndex(AM.Base.FrameIndex, MVT::i32);
- return CurDAG->SelectNodeTo(N, Opc, OpVT, MVT::Other,
- Base, Scale, AM.IndexReg, Disp, Chain)
- .getValue(Op.ResNo);
- }
- }
- }
-
case ISD::STORE: {
SDOperand Chain = Select(N->getOperand(0)); // Token chain.
SDOperand Tmp1 = Select(N->getOperand(1));
- X86ISelAddressMode AM;
- SelectAddress(N->getOperand(2), AM);
-
Opc = 0;
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N->getOperand(1))) {
switch (CN->getValueType(0)) {
@@ -394,19 +414,11 @@
}
}
- SDOperand Scale = getI8Imm (AM.Scale);
- SDOperand Disp = AM.GV
- ? CurDAG->getTargetGlobalAddress(AM.GV, MVT::i32, AM.Disp)
- : getI32Imm(AM.Disp);
- if (AM.BaseType == X86ISelAddressMode::RegBase) {
- return CurDAG->SelectNodeTo(N, Opc, MVT::Other,
- AM.Base.Reg, Scale, AM.IndexReg, Disp, Tmp1,
- Chain);
- } else {
- SDOperand Base = CurDAG->getFrameIndex(AM.Base.FrameIndex, MVT::i32);
- return CurDAG->SelectNodeTo(N, Opc, MVT::Other,
- Base, Scale, AM.IndexReg, Disp, Tmp1, Chain);
- }
+ SDOperand Base, Scale, Index, Disp;
+ SelectAddr(N->getOperand(2), Base, Scale, Index, Disp);
+ return CurDAG->SelectNodeTo(N, Opc, MVT::Other,
+ Base, Scale, Index, Disp, Tmp1, Chain)
+ .getValue(Op.ResNo);
}
}
Index: llvm/lib/Target/X86/X86InstrInfo.td
diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.148 llvm/lib/Target/X86/X86InstrInfo.td:1.149
--- llvm/lib/Target/X86/X86InstrInfo.td:1.148 Mon Dec 5 17:09:43 2005
+++ llvm/lib/Target/X86/X86InstrInfo.td Wed Dec 7 20:01:35 2005
@@ -21,13 +21,13 @@
let MIOperandInfo = (ops R32, i8imm, R32, i32imm);
}
-def i8mem : X86MemOperand<i8, "printi8mem">;
-def i16mem : X86MemOperand<i16, "printi16mem">;
+def i8mem : X86MemOperand<i32, "printi8mem">;
+def i16mem : X86MemOperand<i32, "printi16mem">;
def i32mem : X86MemOperand<i32, "printi32mem">;
-def i64mem : X86MemOperand<i64, "printi64mem">;
-def f32mem : X86MemOperand<f32, "printf32mem">;
-def f64mem : X86MemOperand<f64, "printf64mem">;
-def f80mem : X86MemOperand<f80, "printf80mem">;
+def i64mem : X86MemOperand<i32, "printi64mem">;
+def f32mem : X86MemOperand<i32, "printf32mem">;
+def f64mem : X86MemOperand<i32, "printf64mem">;
+def f80mem : X86MemOperand<i32, "printf80mem">;
def SSECC : Operand<i8> {
let PrintMethod = "printSSECC";
@@ -46,6 +46,10 @@
// Branch targets have OtherVT type.
def brtarget : Operand<OtherVT>;
+// Define X86 specific addressing mode.
+def addr : ComplexPattern<4, "SelectAddr", []>;
+def leaaddr : ComplexPattern<4, "SelectLEAAddr", [add]>;
+
// Format specifies the encoding used by the instruction. This is part of the
// ad-hoc solution used to emit machine instruction encodings by our machine
// code emitter.
@@ -151,7 +155,6 @@
return (unsigned)N->getValue() == (unsigned char)N->getValue();
}]>;
-
//===----------------------------------------------------------------------===//
// Instruction templates...
@@ -297,7 +300,8 @@
"lea{w} {$src|$dst}, {$dst|$src}", []>, OpSize;
def LEA32r : I<0x8D, MRMSrcMem,
(ops R32:$dst, i32mem:$src),
- "lea{l} {$src|$dst}, {$dst|$src}", []>;
+ "lea{l} {$src|$dst}, {$dst|$src}",
+ [(set R32:$dst, leaaddr:$src)]>;
def REP_MOVSB : I<0xA4, RawFrm, (ops), "{rep;movsb|rep movsb}", []>,
@@ -381,11 +385,14 @@
"mov{l} {$src, $dst|$dst, $src}", []>;
def MOV8rm : I<0x8A, MRMSrcMem, (ops R8 :$dst, i8mem :$src),
- "mov{b} {$src, $dst|$dst, $src}", []>;
+ "mov{b} {$src, $dst|$dst, $src}",
+ [(set R8:$dst, (load addr:$src))]>;
def MOV16rm : I<0x8B, MRMSrcMem, (ops R16:$dst, i16mem:$src),
- "mov{w} {$src, $dst|$dst, $src}", []>, OpSize;
+ "mov{w} {$src, $dst|$dst, $src}",
+ [(set R16:$dst, (load addr:$src))]>, OpSize;
def MOV32rm : I<0x8B, MRMSrcMem, (ops R32:$dst, i32mem:$src),
- "mov{l} {$src, $dst|$dst, $src}", []>;
+ "mov{l} {$src, $dst|$dst, $src}",
+ [(set R32:$dst, (load addr:$src))]>;
def MOV8mr : I<0x88, MRMDestMem, (ops i8mem :$dst, R8 :$src),
"mov{b} {$src, $dst|$dst, $src}", []>;
More information about the llvm-commits
mailing list