[llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
Nate Begeman
natebegeman at mac.com
Mon Sep 19 15:34:12 PDT 2005
Changes in directory llvm/lib/CodeGen/SelectionDAG:
DAGCombiner.cpp updated: 1.12 -> 1.13
---
Log message:
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.
---
Diffs of the changes: (+105 -9)
DAGCombiner.cpp | 114 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 105 insertions(+), 9 deletions(-)
Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.12 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.13
--- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.12 Thu Sep 15 19:54:12 2005
+++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Mon Sep 19 17:34:01 2005
@@ -20,6 +20,14 @@
// ZERO_EXTEND/SIGN_EXTEND by converting them to an ANY_EXTEND node which
// 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: undef values
// FIXME: zero extend when top bits are 0 -> drop it ?
@@ -117,10 +125,13 @@
SDOperand visitFNEG(SDNode *N);
SDOperand visitFABS(SDNode *N);
SDOperand visitBRCOND(SDNode *N);
- // brcondtwoway
- // br_cc
- // brtwoway_cc
-
+ SDOperand visitBRCONDTWOWAY(SDNode *N);
+ SDOperand visitBR_CC(SDNode *N);
+ 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,
ISD::CondCode Cond);
public:
@@ -339,6 +350,10 @@
case ISD::FP_EXTEND: return visitFP_EXTEND(N);
case ISD::FNEG: return visitFNEG(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();
}
@@ -1029,7 +1044,7 @@
ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1);
ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N2);
MVT::ValueType VT = N->getValueType(0);
-
+
// fold select C, X, X -> X
if (N1 == N2)
return N1;
@@ -1040,7 +1055,7 @@
if (N0C && N0C->isNullValue())
return N2;
// 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);
// fold select C, 0, X -> ~C & X
// FIXME: this should check for C type == X type, not i1?
@@ -1050,7 +1065,7 @@
return DAG.getNode(ISD::AND, VT, XORNode, N2);
}
// 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));
WorkList.push_back(XORNode.Val);
return DAG.getNode(ISD::OR, VT, XORNode, N1);
@@ -1065,12 +1080,40 @@
// fold X ? Y : X --> X ? Y : 0 --> X & Y
if (MVT::i1 == VT && N0 == N2)
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();
}
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) {
@@ -1290,6 +1333,59 @@
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 N1, ISD::CondCode Cond) {
// These setcc operations always fold.
More information about the llvm-commits
mailing list