* Promote all 1 bit entities to 8 bit.

* Handling extload (1 bit -> 8 bit) and remove C++ code that handle 1 bit
zextload.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24726 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng 2005-12-15 19:49:23 +00:00
parent d0f6d18aa8
commit cb17bac3a3
4 changed files with 9 additions and 114 deletions

View File

@ -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),

View File

@ -22,7 +22,6 @@
#include "llvm/Target/TargetMachine.h"
#include "llvm/Support/Debug.h"
#include "llvm/ADT/Statistic.h"
#include <set>
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<SDNode*> &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<ConstantPoolSDNode>(Op.getOperand(1)))
return false;
} else if (FloatPromoteOk && Op.getOpcode() == ISD::EXTLOAD &&
cast<VTSDNode>(Op.getOperand(3))->getVT() == MVT::f32) {
// FIXME: currently can't fold constant pool indexes.
if (isa<ConstantPoolSDNode>(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<SDNode*> 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();

View File

@ -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);

View File

@ -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)
//===----------------------------------------------------------------------===//