1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-24 19:52:54 +01:00

Stub out the rest of the DAG Combiner. Just need to fill in the

select_cc bits and then wrap it in a convenience function for  use with
regular select.

llvm-svn: 23389
This commit is contained in:
Nate Begeman 2005-09-19 22:34:01 +00:00
parent 59dd979162
commit 236df45f1b

View File

@ -20,6 +20,14 @@
// ZERO_EXTEND/SIGN_EXTEND by converting them to an ANY_EXTEND node which // ZERO_EXTEND/SIGN_EXTEND by converting them to an ANY_EXTEND node which
// we don't have yet. // we don't have yet.
// //
// FIXME: select C, 16, 0 -> shr C, 4
// FIXME: select C, pow2, pow2 -> something smart
// FIXME: trunc(select X, Y, Z) -> select X, trunc(Y), trunc(Z)
// FIXME: (select C, load A, load B) -> load (select C, A, B)
// FIXME: store -> load -> forward substitute
// FIXME: Dead stores -> nuke
// FIXME: shr X, (and Y,31) -> shr X, Y
// FIXME: TRUNC (LOAD) -> EXT_LOAD/LOAD(smaller)
// FIXME: mul (x, const) -> shifts + adds // FIXME: mul (x, const) -> shifts + adds
// FIXME: undef values // FIXME: undef values
// FIXME: zero extend when top bits are 0 -> drop it ? // FIXME: zero extend when top bits are 0 -> drop it ?
@ -117,10 +125,13 @@ namespace {
SDOperand visitFNEG(SDNode *N); SDOperand visitFNEG(SDNode *N);
SDOperand visitFABS(SDNode *N); SDOperand visitFABS(SDNode *N);
SDOperand visitBRCOND(SDNode *N); SDOperand visitBRCOND(SDNode *N);
// brcondtwoway SDOperand visitBRCONDTWOWAY(SDNode *N);
// br_cc SDOperand visitBR_CC(SDNode *N);
// brtwoway_cc SDOperand visitBRTWOWAY_CC(SDNode *N);
SDOperand SimplifySelect(SDOperand N0, SDOperand N1, SDOperand N2);
SDOperand SimplifySelectCC(SDOperand N0, SDOperand N1, SDOperand N2,
SDOperand N3, ISD::CondCode CC);
SDOperand SimplifySetCC(MVT::ValueType VT, SDOperand N0, SDOperand N1, SDOperand SimplifySetCC(MVT::ValueType VT, SDOperand N0, SDOperand N1,
ISD::CondCode Cond); ISD::CondCode Cond);
public: public:
@ -339,6 +350,10 @@ SDOperand DAGCombiner::visit(SDNode *N) {
case ISD::FP_EXTEND: return visitFP_EXTEND(N); case ISD::FP_EXTEND: return visitFP_EXTEND(N);
case ISD::FNEG: return visitFNEG(N); case ISD::FNEG: return visitFNEG(N);
case ISD::FABS: return visitFABS(N); case ISD::FABS: return visitFABS(N);
case ISD::BRCOND: return visitBRCOND(N);
case ISD::BRCONDTWOWAY: return visitBRCONDTWOWAY(N);
case ISD::BR_CC: return visitBR_CC(N);
case ISD::BRTWOWAY_CC: return visitBRTWOWAY_CC(N);
} }
return SDOperand(); return SDOperand();
} }
@ -1029,7 +1044,7 @@ SDOperand DAGCombiner::visitSELECT(SDNode *N) {
ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1); ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1);
ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N2); ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N2);
MVT::ValueType VT = N->getValueType(0); MVT::ValueType VT = N->getValueType(0);
// fold select C, X, X -> X // fold select C, X, X -> X
if (N1 == N2) if (N1 == N2)
return N1; return N1;
@ -1040,7 +1055,7 @@ SDOperand DAGCombiner::visitSELECT(SDNode *N) {
if (N0C && N0C->isNullValue()) if (N0C && N0C->isNullValue())
return N2; return N2;
// fold select C, 1, X -> C | X // fold select C, 1, X -> C | X
if (MVT::i1 == VT && N1C && !N1C->isNullValue()) if (MVT::i1 == VT && N1C && N1C->getValue() == 1)
return DAG.getNode(ISD::OR, VT, N0, N2); return DAG.getNode(ISD::OR, VT, N0, N2);
// fold select C, 0, X -> ~C & X // fold select C, 0, X -> ~C & X
// FIXME: this should check for C type == X type, not i1? // FIXME: this should check for C type == X type, not i1?
@ -1050,7 +1065,7 @@ SDOperand DAGCombiner::visitSELECT(SDNode *N) {
return DAG.getNode(ISD::AND, VT, XORNode, N2); return DAG.getNode(ISD::AND, VT, XORNode, N2);
} }
// fold select C, X, 1 -> ~C | X // fold select C, X, 1 -> ~C | X
if (MVT::i1 == VT && N2C && !N2C->isNullValue()) { if (MVT::i1 == VT && N2C && N2C->getValue() == 1) {
SDOperand XORNode = DAG.getNode(ISD::XOR, VT, N0, DAG.getConstant(1, VT)); SDOperand XORNode = DAG.getNode(ISD::XOR, VT, N0, DAG.getConstant(1, VT));
WorkList.push_back(XORNode.Val); WorkList.push_back(XORNode.Val);
return DAG.getNode(ISD::OR, VT, XORNode, N1); return DAG.getNode(ISD::OR, VT, XORNode, N1);
@ -1065,12 +1080,40 @@ SDOperand DAGCombiner::visitSELECT(SDNode *N) {
// fold X ? Y : X --> X ? Y : 0 --> X & Y // fold X ? Y : X --> X ? Y : 0 --> X & Y
if (MVT::i1 == VT && N0 == N2) if (MVT::i1 == VT && N0 == N2)
return DAG.getNode(ISD::AND, VT, N0, N1); return DAG.getNode(ISD::AND, VT, N0, N1);
// fold selects based on a setcc into other things, such as min/max/abs
if (N0.getOpcode() == ISD::SETCC)
return SimplifySelect(N0, N1, N2);
return SDOperand(); return SDOperand();
} }
SDOperand DAGCombiner::visitSELECT_CC(SDNode *N) { SDOperand DAGCombiner::visitSELECT_CC(SDNode *N) {
return SDOperand(); SDOperand N0 = N->getOperand(0);
SDOperand N1 = N->getOperand(1);
SDOperand N2 = N->getOperand(2);
SDOperand N3 = N->getOperand(3);
SDOperand N4 = N->getOperand(4);
ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0);
ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1);
ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N2);
ISD::CondCode CC = cast<CondCodeSDNode>(N4)->get();
// Determine if the condition we're dealing with is constant
SDOperand SCC = SimplifySetCC(TLI.getSetCCResultTy(), N0, N1, CC);
ConstantSDNode *SCCC = dyn_cast<ConstantSDNode>(SCC);
bool constTrue = SCCC && SCCC->getValue() == 1;
bool constFalse = SCCC && SCCC->isNullValue();
// fold select_cc lhs, rhs, x, x, cc -> x
if (N2 == N3)
return N2;
// fold select_cc true, x, y -> x
if (constTrue)
return N2;
// fold select_cc false, x, y -> y
if (constFalse)
return N3;
// fold select_cc into other things, such as min/max/abs
return SimplifySelectCC(N0, N1, N2, N3, CC);
} }
SDOperand DAGCombiner::visitSETCC(SDNode *N) { SDOperand DAGCombiner::visitSETCC(SDNode *N) {
@ -1290,6 +1333,59 @@ SDOperand DAGCombiner::visitFABS(SDNode *N) {
return SDOperand(); return SDOperand();
} }
SDOperand DAGCombiner::visitBRCOND(SDNode *N) {
SDOperand Chain = N->getOperand(0);
SDOperand N1 = N->getOperand(1);
SDOperand N2 = N->getOperand(2);
ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1);
// never taken branch, fold to chain
if (N1C && N1C->isNullValue())
return Chain;
// unconditional branch
if (N1C && !N1C->isNullValue())
return DAG.getNode(ISD::BR, MVT::Other, Chain, N2);
return SDOperand();
}
SDOperand DAGCombiner::visitBRCONDTWOWAY(SDNode *N) {
SDOperand Chain = N->getOperand(0);
SDOperand N1 = N->getOperand(1);
SDOperand N2 = N->getOperand(2);
SDOperand N3 = N->getOperand(3);
ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1);
// unconditional branch to true mbb
if (N1C && N1C->getValue() == 1)
return DAG.getNode(ISD::BR, MVT::Other, Chain, N2);
// unconditional branch to false mbb
if (N1C && N1C->isNullValue())
return DAG.getNode(ISD::BR, MVT::Other, Chain, N3);
return SDOperand();
}
SDOperand DAGCombiner::visitBR_CC(SDNode *N) {
// FIXME: come up with a common way between br_cc, brtwoway_cc, and select_cc
// to canonicalize the condition without calling getnode a bazillion times.
return SDOperand();
}
SDOperand DAGCombiner::visitBRTWOWAY_CC(SDNode *N) {
// FIXME: come up with a common way between br_cc, brtwoway_cc, and select_cc
// to canonicalize the condition without calling getnode a bazillion times.
return SDOperand();
}
SDOperand DAGCombiner::SimplifySelect(SDOperand N0, SDOperand N1, SDOperand N2){
return SDOperand();
}
SDOperand DAGCombiner::SimplifySelectCC(SDOperand N0, SDOperand N1,
SDOperand N2, SDOperand N3,
ISD::CondCode CC) {
return SDOperand();
}
SDOperand DAGCombiner::SimplifySetCC(MVT::ValueType VT, SDOperand N0, SDOperand DAGCombiner::SimplifySetCC(MVT::ValueType VT, SDOperand N0,
SDOperand N1, ISD::CondCode Cond) { SDOperand N1, ISD::CondCode Cond) {
// These setcc operations always fold. // These setcc operations always fold.