From 5a457de4b20d38f62e5906b39a53b5591253f642 Mon Sep 17 00:00:00 2001 From: Richard Osborne Date: Wed, 10 Mar 2010 17:10:35 +0000 Subject: [PATCH] Extract recognition of patterns such as add(add(mul(x,y),a),b) into a seperate function. llvm-svn: 98162 --- llvm/lib/Target/XCore/XCoreISelLowering.cpp | 114 +++++++++++--------- 1 file changed, 66 insertions(+), 48 deletions(-) diff --git a/llvm/lib/Target/XCore/XCoreISelLowering.cpp b/llvm/lib/Target/XCore/XCoreISelLowering.cpp index 90d29871d8e2..7dc0274f2685 100644 --- a/llvm/lib/Target/XCore/XCoreISelLowering.cpp +++ b/llvm/lib/Target/XCore/XCoreISelLowering.cpp @@ -583,6 +583,64 @@ LowerUMUL_LOHI(SDValue Op, SelectionDAG &DAG) return DAG.getMergeValues(Ops, 2, dl); } +/// isADDADDMUL - Return whether Op is in a form that is equivalent to +/// add(add(mul(x,y),a),b). If requireIntermediatesHaveOneUse is true then +/// each intermediate result in the calculation must also have a single use. +/// If the Op is in the correct form the constituent parts are written to Mul0, +/// Mul1, Addend0 and Addend1. +static bool +isADDADDMUL(SDValue Op, SDValue &Mul0, SDValue &Mul1, SDValue &Addend0, + SDValue &Addend1, bool requireIntermediatesHaveOneUse) +{ + if (Op.getOpcode() != ISD::ADD) + return false; + SDValue N0 = Op.getOperand(0); + SDValue N1 = Op.getOperand(1); + SDValue AddOp; + SDValue OtherOp; + if (N0.getOpcode() == ISD::ADD) { + AddOp = N0; + OtherOp = N1; + } else if (N1.getOpcode() == ISD::ADD) { + AddOp = N1; + OtherOp = N0; + } else { + return false; + } + if (OtherOp.getOpcode() == ISD::MUL) { + // add(add(a,b),mul(x,y)) + if (requireIntermediatesHaveOneUse && + (!OtherOp.hasOneUse() || !AddOp.hasOneUse())) + return false; + Mul0 = OtherOp.getOperand(0); + Mul1 = OtherOp.getOperand(1); + Addend0 = AddOp.getOperand(0); + Addend1 = AddOp.getOperand(1); + return true; + } + if (AddOp.getOperand(0).getOpcode() == ISD::MUL) { + // add(add(mul(x,y),a),b) + if (requireIntermediatesHaveOneUse && !AddOp.getOperand(0).hasOneUse()) + return false; + Mul0 = AddOp.getOperand(0).getOperand(0); + Mul1 = AddOp.getOperand(0).getOperand(1); + Addend0 = AddOp.getOperand(1); + Addend1 = OtherOp; + return true; + } + if (AddOp.getOperand(1).getOpcode() == ISD::MUL) { + // add(add(a,mul(x,y)),b) + if (requireIntermediatesHaveOneUse && !AddOp.getOperand(1).hasOneUse()) + return false; + Mul0 = AddOp.getOperand(1).getOperand(0); + Mul1 = AddOp.getOperand(1).getOperand(1); + Addend0 = AddOp.getOperand(0); + Addend1 = OtherOp; + return true; + } + return false; +} + SDValue XCoreTargetLowering:: TryExpandADDWithMul(SDNode *N, SelectionDAG &DAG) { @@ -1286,55 +1344,15 @@ SDValue XCoreTargetLowering::PerformDAGCombine(SDNode *N, // Fold expressions such as add(add(mul(x,y),a),b) -> lmul(x, y, a, b). // This is only profitable if the intermediate results are unused // elsewhere. - SDValue N0 = N->getOperand(0); - SDValue N1 = N->getOperand(1); - SDValue AddOp; - SDValue OtherOp; - if (N0.getOpcode() == ISD::ADD) { - AddOp = N0; - OtherOp = N1; - } else if (N1.getOpcode() == ISD::ADD) { - AddOp = N1; - OtherOp = N0; - } else { - break; + SDValue Mul0, Mul1, Addend0, Addend1; + if (isADDADDMUL(SDValue(N, 0), Mul0, Mul1, Addend0, Addend1, true)) { + SDValue Zero = DAG.getConstant(0, MVT::i32); + SDValue Ignored = DAG.getNode(XCoreISD::LMUL, dl, + DAG.getVTList(MVT::i32, MVT::i32), Mul0, + Mul1, Addend0, Addend1); + SDValue Result(Ignored.getNode(), 1); + return Result; } - SDValue Addend0, Addend1; - SDValue Mul0; - SDValue Mul1; - if (OtherOp.getOpcode() == ISD::MUL) { - // add(add(a,b),mul(x,y)) - if (!OtherOp.hasOneUse() || !AddOp.hasOneUse()) - break; - Mul0 = OtherOp.getOperand(0); - Mul1 = OtherOp.getOperand(1); - Addend0 = AddOp.getOperand(0); - Addend1 = AddOp.getOperand(1); - } else if (AddOp.getOperand(0).getOpcode() == ISD::MUL) { - // add(add(mul(x,y),a),b) - if (!AddOp.getOperand(0).hasOneUse()) - break; - Mul0 = AddOp.getOperand(0).getOperand(0); - Mul1 = AddOp.getOperand(0).getOperand(1); - Addend0 = AddOp.getOperand(1); - Addend1 = OtherOp; - } else if (AddOp.getOperand(1).getOpcode() == ISD::MUL) { - // add(add(a,mul(x,y)),b) - if (!AddOp.getOperand(1).hasOneUse()) - break; - Mul0 = AddOp.getOperand(1).getOperand(0); - Mul1 = AddOp.getOperand(1).getOperand(1); - Addend0 = AddOp.getOperand(0); - Addend1 = OtherOp; - } else { - break; - } - SDValue Zero = DAG.getConstant(0, MVT::i32); - SDValue Ignored = DAG.getNode(XCoreISD::LMUL, dl, - DAG.getVTList(MVT::i32, MVT::i32), Mul0, - Mul1, Addend0, Addend1); - SDValue Result(Ignored.getNode(), 1); - return Result; } break; case ISD::STORE: {