diff --git a/lib/Target/TargetSelectionDAG.td b/lib/Target/TargetSelectionDAG.td index 89deb72e01f..36f83c168f0 100644 --- a/lib/Target/TargetSelectionDAG.td +++ b/lib/Target/TargetSelectionDAG.td @@ -150,7 +150,7 @@ def SDTStore : SDTypeProfile<0, 2, [ // store SDTCisPtrTy<1> ]>; -def SDTIntExtLoad : SDTypeProfile<1, 3, [ // sextload, zextload +def SDTIntExtLoad : SDTypeProfile<1, 3, [ // sextload, zextload, extload SDTCisInt<0>, SDTCisPtrTy<1>, SDTCisVT<2, OtherVT>, SDTCisVT<3, OtherVT> ]>; @@ -261,6 +261,7 @@ def store : SDNode<"ISD::STORE" , SDTStore, [SDNPHasChain]>; // below) which pass in a dummy srcvalue node which tblgen will skip over. def sextld : SDNode<"ISD::SEXTLOAD" , SDTIntExtLoad, [SDNPHasChain]>; def zextld : SDNode<"ISD::ZEXTLOAD" , SDTIntExtLoad, [SDNPHasChain]>; +def extld : SDNode<"ISD::EXTLOAD" , SDTIntExtLoad, [SDNPHasChain]>; //===----------------------------------------------------------------------===// // Selection DAG Condition Codes @@ -333,6 +334,8 @@ def sextload : PatFrag<(ops node:$ptr, node:$vt), (sextld node:$ptr, srcvalue:$dummy, node:$vt)>; def zextload : PatFrag<(ops node:$ptr, node:$vt), (zextld node:$ptr, srcvalue:$dummy, node:$vt)>; +def extload : PatFrag<(ops node:$ptr, node:$vt), + (extld node:$ptr, srcvalue:$dummy, node:$vt)>; // setcc convenience fragments. def setoeq : PatFrag<(ops node:$lhs, node:$rhs), diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp index 6476d617ca3..2966b19c6e5 100644 --- a/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -22,7 +22,6 @@ #include "llvm/Target/TargetMachine.h" #include "llvm/Support/Debug.h" #include "llvm/ADT/Statistic.h" -#include using namespace llvm; //===----------------------------------------------------------------------===// @@ -96,8 +95,6 @@ namespace { private: SDOperand Select(SDOperand N); - bool isFoldableLoad(SDOperand Op, SDOperand OtherOp, - bool FloatPromoteOk = false); bool MatchAddress(SDOperand N, X86ISelAddressMode &AM); bool SelectAddr(SDOperand N, SDOperand &Base, SDOperand &Scale, SDOperand &Index, SDOperand &Disp); @@ -362,68 +359,6 @@ bool X86DAGToDAGISel::SelectLEAAddr(SDOperand N, SDOperand &Base, SDOperand &Sca return false; } -/// NodeTransitivelyUsesValue - Return true if N or any of its uses uses Op. -/// The DAG cannot have cycles in it, by definition, so the visited set is not -/// needed to prevent infinite loops. The DAG CAN, however, have unbounded -/// reuse, so it prevents exponential cases. -/// -static bool NodeTransitivelyUsesValue(SDOperand N, SDOperand Op, - std::set &Visited) { - if (N == Op) return true; // Found it. - SDNode *Node = N.Val; - if (Node->getNumOperands() == 0 || // Leaf? - Node->getNodeDepth() <= Op.getNodeDepth()) return false; // Can't find it? - if (!Visited.insert(Node).second) return false; // Already visited? - - // Recurse for the first N-1 operands. - for (unsigned i = 1, e = Node->getNumOperands(); i != e; ++i) - if (NodeTransitivelyUsesValue(Node->getOperand(i), Op, Visited)) - return true; - - // Tail recurse for the last operand. - return NodeTransitivelyUsesValue(Node->getOperand(0), Op, Visited); -} - -/// isFoldableLoad - Return true if this is a load instruction that can safely -/// be folded into an operation that uses it. -bool X86DAGToDAGISel::isFoldableLoad(SDOperand Op, SDOperand OtherOp, - bool FloatPromoteOk) { - if (Op.getOpcode() == ISD::LOAD) { - // FIXME: currently can't fold constant pool indexes. - if (isa(Op.getOperand(1))) - return false; - } else if (FloatPromoteOk && Op.getOpcode() == ISD::EXTLOAD && - cast(Op.getOperand(3))->getVT() == MVT::f32) { - // FIXME: currently can't fold constant pool indexes. - if (isa(Op.getOperand(1))) - return false; - } else { - return false; - } - - // If this load has already been emitted, we clearly can't fold it. - assert(Op.ResNo == 0 && "Not a use of the value of the load?"); - if (CodeGenMap.count(Op.getValue(1))) return false; - assert(!CodeGenMap.count(Op.getValue(0)) && - "Value in map but not token chain?"); - assert(!CodeGenMap.count(Op.getValue(1)) && - "Token lowered but value not in map?"); - - // If there is not just one use of its value, we cannot fold. - if (!Op.Val->hasNUsesOfValue(1, 0)) return false; - - // Finally, we cannot fold the load into the operation if this would induce a - // cycle into the resultant dag. To check for this, see if OtherOp (the other - // operand of the operation we are folding the load into) can possible use the - // chain node defined by the load. - if (OtherOp.Val && !Op.Val->hasNUsesOfValue(0, 1)) { // Has uses of chain? - std::set Visited; - if (NodeTransitivelyUsesValue(OtherOp, Op.getValue(1), Visited)) - return false; - } - return true; -} - SDOperand X86DAGToDAGISel::Select(SDOperand N) { SDNode *Node = N.Val; MVT::ValueType NVT = Node->getValueType(0); @@ -455,48 +390,6 @@ SDOperand X86DAGToDAGISel::Select(SDOperand N) { } break; - case ISD::ANY_EXTEND: // treat any extend like zext - case ISD::ZERO_EXTEND: { - SDOperand N0 = N.getOperand(0); - if (N0.getValueType() == MVT::i1) { - // FIXME: This hack is here for zero extension casts from bool to i8. - // This would not be needed if bools were promoted by Legalize. - if (NVT == MVT::i8) { - Opc = X86::MOV8rr; - } else if (!isFoldableLoad(N0, SDOperand())) { - switch (NVT) { - default: assert(0 && "Cannot zero extend to this type!"); - case MVT::i16: Opc = X86::MOVZX16rr8; break; - case MVT::i32: Opc = X86::MOVZX32rr8; break; - } - } else { - switch (NVT) { - default: assert(0 && "Cannot zero extend to this type!"); - case MVT::i16: Opc = X86::MOVZX16rm8; break; - case MVT::i32: Opc = X86::MOVZX32rm8; break; - } - - SDOperand Chain = Select(N0.getOperand(0)); - SDOperand Base, Scale, Index, Disp; - (void) SelectAddr(N0.getOperand(1), Base, Scale, Index, Disp); - SDOperand Result = CurDAG->getTargetNode(Opc, NVT, - MVT::Other, Base, Scale, - Index, Disp, Chain); - CodeGenMap[N.getValue(0)] = Result; - Chain = CodeGenMap[N.getValue(1)] = Result.getValue(1); - return (N.ResNo) ? Chain : Result.getValue(0); - } - - SDOperand Tmp0 = Select(Node->getOperand(0)); - if (Node->hasOneUse()) - return CurDAG->SelectNodeTo(Node, Opc, NVT, Tmp0); - else - return CodeGenMap[N] = CurDAG->getTargetNode(Opc, NVT, Tmp0); - } - // Other cases are autogenerated. - break; - } - case ISD::RET: { SDOperand Chain = Node->getOperand(0); // Token chain. unsigned NumOps = Node->getNumOperands(); diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 7f3aa499bcd..292f00af373 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -41,9 +41,6 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM) setShiftAmountFlavor(Mask); // shl X, 32 == shl X, 0 // Set up the register classes. - // FIXME: Eliminate these two classes when legalize can handle promotions - // well. - addRegisterClass(MVT::i1, X86::R8RegisterClass); addRegisterClass(MVT::i8, X86::R8RegisterClass); addRegisterClass(MVT::i16, X86::R16RegisterClass); addRegisterClass(MVT::i32, X86::R32RegisterClass); diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td index 10c9d487ef3..2eb77756f9f 100644 --- a/lib/Target/X86/X86InstrInfo.td +++ b/lib/Target/X86/X86InstrInfo.td @@ -180,6 +180,8 @@ def zextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (zextload node:$ptr, i8))>; def zextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (zextload node:$ptr, i8))>; def zextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (zextload node:$ptr, i16))>; +def extloadi8i1 : PatFrag<(ops node:$ptr), (i8 (extload node:$ptr, i1))>; + //===----------------------------------------------------------------------===// // Instruction templates... @@ -432,9 +434,6 @@ def MOV32mr : I<0x89, MRMDestMem, (ops i32mem:$dst, R32:$src), "mov{l} {$src, $dst|$dst, $src}", [(store R32:$src, addr:$dst)]>; -// Handling 1 bit load -def : Pat<(i1 (load addr:$src)), (MOV8rm addr:$src)>; - //===----------------------------------------------------------------------===// // Fixed-Register Multiplication and Division Instructions... // @@ -1720,6 +1719,9 @@ def : Pat<(sextloadi32i1 addr:$src), (MOVSX32rm8 addr:$src)>; def : Pat<(zextloadi16i1 addr:$src), (MOVZX16rm8 addr:$src)>; def : Pat<(zextloadi32i1 addr:$src), (MOVZX32rm8 addr:$src)>; +// Handling 1 bit extload +def : Pat<(extloadi8i1 addr:$src), (MOV8rm addr:$src)>; + //===----------------------------------------------------------------------===// // XMM Floating point support (requires SSE2) //===----------------------------------------------------------------------===//