[llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
Nate Begeman
natebegeman at mac.com
Thu Feb 2 22:47:08 PST 2006
Changes in directory llvm/lib/CodeGen/SelectionDAG:
DAGCombiner.cpp updated: 1.93 -> 1.94
---
Log message:
Add common code for reassociating ops in the dag combiner
---
Diffs of the changes: (+55 -50)
DAGCombiner.cpp | 105 +++++++++++++++++++++++++++++---------------------------
1 files changed, 55 insertions(+), 50 deletions(-)
Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.93 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.94
--- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.93 Thu Feb 2 01:17:31 2006
+++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Fri Feb 3 00:46:56 2006
@@ -33,7 +33,6 @@
// FIXME: divide by zero is currently left unfolded. do we want to turn this
// into an undef?
// FIXME: select ne (select cc, 1, 0), 0, true, false -> select cc, true, false
-// FIXME: reassociate (X+C)+Y into (X+Y)+C if the inner expression has one use
//
//===----------------------------------------------------------------------===//
@@ -179,6 +178,8 @@
SDOperand visitLOCATION(SDNode *N);
SDOperand visitDEBUGLOC(SDNode *N);
+ SDOperand ReassociateOps(unsigned Opc, SDOperand LHS, SDOperand RHS);
+
bool SimplifySelectOps(SDNode *SELECT, SDOperand LHS, SDOperand RHS);
SDOperand SimplifySelect(SDOperand N0, SDOperand N1, SDOperand N2);
SDOperand SimplifySelectCC(SDOperand N0, SDOperand N1, SDOperand N2,
@@ -418,6 +419,37 @@
}
}
+SDOperand DAGCombiner::ReassociateOps(unsigned Opc, SDOperand N0, SDOperand N1){
+ MVT::ValueType VT = N0.getValueType();
+ // reassoc. (op (op x, c1), y) -> (op (op x, y), c1) iff x+c1 has one use
+ // reassoc. (op (op x, c1), c2) -> (op x, (op c1, c2))
+ if (N0.getOpcode() == Opc && isa<ConstantSDNode>(N0.getOperand(1))) {
+ if (isa<ConstantSDNode>(N1)) {
+ SDOperand OpNode = DAG.getNode(Opc, VT, N0.getOperand(1), N1);
+ WorkList.push_back(OpNode.Val);
+ return DAG.getNode(Opc, VT, OpNode, N0.getOperand(0));
+ } else if (N0.hasOneUse()) {
+ SDOperand OpNode = DAG.getNode(Opc, VT, N0.getOperand(0), N1);
+ WorkList.push_back(OpNode.Val);
+ return DAG.getNode(Opc, VT, OpNode, N0.getOperand(1));
+ }
+ }
+ // reassoc. (op y, (op x, c1)) -> (op (op x, y), c1) iff x+c1 has one use
+ // reassoc. (op c2, (op x, c1)) -> (op x, (op c1, c2))
+ if (N1.getOpcode() == Opc && isa<ConstantSDNode>(N1.getOperand(1))) {
+ if (isa<ConstantSDNode>(N0)) {
+ SDOperand OpNode = DAG.getNode(Opc, VT, N1.getOperand(1), N0);
+ WorkList.push_back(OpNode.Val);
+ return DAG.getNode(Opc, VT, OpNode, N1.getOperand(0));
+ } else if (N1.hasOneUse()) {
+ SDOperand OpNode = DAG.getNode(Opc, VT, N1.getOperand(0), N0);
+ WorkList.push_back(OpNode.Val);
+ return DAG.getNode(Opc, VT, OpNode, N1.getOperand(1));
+ }
+ }
+ return SDOperand();
+}
+
void DAGCombiner::Run(bool RunningAfterLegalize) {
// set the instance variable, so that the various visit routines may use it.
AfterLegalize = RunningAfterLegalize;
@@ -587,25 +619,16 @@
// fold (add x, 0) -> x
if (N1C && N1C->isNullValue())
return N0;
- // fold (add (add x, c1), c2) -> (add x, c1+c2)
- if (N1C && N0.getOpcode() == ISD::ADD) {
- ConstantSDNode *N00C = dyn_cast<ConstantSDNode>(N0.getOperand(0));
- ConstantSDNode *N01C = dyn_cast<ConstantSDNode>(N0.getOperand(1));
- if (N00C)
- return DAG.getNode(ISD::ADD, VT, N0.getOperand(1),
- DAG.getConstant(N1C->getValue()+N00C->getValue(), VT));
- if (N01C)
- return DAG.getNode(ISD::ADD, VT, N0.getOperand(0),
- DAG.getConstant(N1C->getValue()+N01C->getValue(), VT));
- }
-
// fold ((c1-A)+c2) -> (c1+c2)-A
if (N1C && N0.getOpcode() == ISD::SUB)
if (ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0.getOperand(0)))
return DAG.getNode(ISD::SUB, VT,
DAG.getConstant(N1C->getValue()+N0C->getValue(), VT),
N0.getOperand(1));
-
+ // reassociate add
+ SDOperand RADD = ReassociateOps(ISD::ADD, N0, N1);
+ if (RADD.Val != 0)
+ return RADD;
// fold ((0-A) + B) -> B-A
if (N0.getOpcode() == ISD::SUB && isa<ConstantSDNode>(N0.getOperand(0)) &&
cast<ConstantSDNode>(N0.getOperand(0))->isNullValue())
@@ -678,19 +701,10 @@
DAG.getConstant(Log2_64(-N1C->getSignExtended()),
TLI.getShiftAmountTy())));
}
-
-
- // fold (mul (mul x, c1), c2) -> (mul x, c1*c2)
- if (N1C && N0.getOpcode() == ISD::MUL) {
- ConstantSDNode *N00C = dyn_cast<ConstantSDNode>(N0.getOperand(0));
- ConstantSDNode *N01C = dyn_cast<ConstantSDNode>(N0.getOperand(1));
- if (N00C)
- return DAG.getNode(ISD::MUL, VT, N0.getOperand(1),
- DAG.getConstant(N1C->getValue()*N00C->getValue(), VT));
- if (N01C)
- return DAG.getNode(ISD::MUL, VT, N0.getOperand(0),
- DAG.getConstant(N1C->getValue()*N01C->getValue(), VT));
- }
+ // reassociate mul
+ SDOperand RMUL = ReassociateOps(ISD::MUL, N0, N1);
+ if (RMUL.Val != 0)
+ return RMUL;
return SDOperand();
}
@@ -866,17 +880,10 @@
if (N1C &&
TLI.MaskedValueIsZero(N0, ~N1C->getValue() & (~0ULL>>(64-OpSizeInBits))))
return N0;
- // fold (and (and x, c1), c2) -> (and x, c1^c2)
- if (N1C && N0.getOpcode() == ISD::AND) {
- ConstantSDNode *N00C = dyn_cast<ConstantSDNode>(N0.getOperand(0));
- ConstantSDNode *N01C = dyn_cast<ConstantSDNode>(N0.getOperand(1));
- if (N00C)
- return DAG.getNode(ISD::AND, VT, N0.getOperand(1),
- DAG.getConstant(N1C->getValue()&N00C->getValue(), VT));
- if (N01C)
- return DAG.getNode(ISD::AND, VT, N0.getOperand(0),
- DAG.getConstant(N1C->getValue()&N01C->getValue(), VT));
- }
+ // reassociate and
+ SDOperand RAND = ReassociateOps(ISD::AND, N0, N1);
+ if (RAND.Val != 0)
+ return RAND;
// fold (and (sign_extend_inreg x, i16 to i32), 1) -> (and x, 1)
if (N1C && N0.getOpcode() == ISD::SIGN_EXTEND_INREG) {
unsigned ExtendBits =
@@ -1031,19 +1038,13 @@
if (N1C &&
TLI.MaskedValueIsZero(N0,~N1C->getValue() & (~0ULL>>(64-OpSizeInBits))))
return N1;
- // fold (or (or x, c1), c2) -> (or x, c1|c2)
- if (N1C && N0.getOpcode() == ISD::OR) {
- ConstantSDNode *N00C = dyn_cast<ConstantSDNode>(N0.getOperand(0));
- ConstantSDNode *N01C = dyn_cast<ConstantSDNode>(N0.getOperand(1));
- if (N00C)
- return DAG.getNode(ISD::OR, VT, N0.getOperand(1),
- DAG.getConstant(N1C->getValue()|N00C->getValue(), VT));
- if (N01C)
- return DAG.getNode(ISD::OR, VT, N0.getOperand(0),
- DAG.getConstant(N1C->getValue()|N01C->getValue(), VT));
- } else if (N1C && N0.getOpcode() == ISD::AND && N0.Val->hasOneUse() &&
+ // reassociate or
+ SDOperand ROR = ReassociateOps(ISD::OR, N0, N1);
+ if (ROR.Val != 0)
+ return ROR;
+ // Canonicalize (or (and X, c1), c2) -> (and (or X, c2), c1|c2)
+ if (N1C && N0.getOpcode() == ISD::AND && N0.Val->hasOneUse() &&
isa<ConstantSDNode>(N0.getOperand(1))) {
- // Canonicalize (or (and X, c1), c2) -> (and (or X, c2), c1|c2)
ConstantSDNode *C1 = cast<ConstantSDNode>(N0.getOperand(1));
return DAG.getNode(ISD::AND, VT, DAG.getNode(ISD::OR, VT, N0.getOperand(0),
N1),
@@ -1160,6 +1161,10 @@
// fold (xor x, 0) -> x
if (N1C && N1C->isNullValue())
return N0;
+ // reassociate xor
+ SDOperand RXOR = ReassociateOps(ISD::XOR, N0, N1);
+ if (RXOR.Val != 0)
+ return RXOR;
// fold !(x cc y) -> (x !cc y)
if (N1C && N1C->getValue() == 1 && isSetCCEquivalent(N0, LHS, RHS, CC)) {
bool isInt = MVT::isInteger(LHS.getValueType());
More information about the llvm-commits
mailing list