diff options
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 16 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp | 60 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeTypes.h | 3 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp | 7 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 1 |
5 files changed, 68 insertions, 19 deletions
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 4c1710dd81..e1554bf33b 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -1085,8 +1085,7 @@ SDValue DAGCombiner::visitADDC(SDNode *N) { // If the flag result is dead, turn this into an ADD. if (N->hasNUsesOfValue(0, 1)) return CombineTo(N, DAG.getNode(ISD::ADD, N->getDebugLoc(), VT, N1, N0), - DAG.getNode(ISD::CARRY_FALSE, - N->getDebugLoc(), MVT::Flag)); + DAG.getConstant(0, N->getValueType(1))); // canonicalize constant to RHS. if (N0C && !N1C) @@ -1094,10 +1093,9 @@ SDValue DAGCombiner::visitADDC(SDNode *N) { // fold (addc x, 0) -> x + no carry out if (N1C && N1C->isNullValue()) - return CombineTo(N, N0, DAG.getNode(ISD::CARRY_FALSE, - N->getDebugLoc(), MVT::Flag)); + return CombineTo(N, N0, DAG.getConstant(0, N1.getValueType())); - // fold (addc a, b) -> (or a, b), CARRY_FALSE iff a and b share no bits. + // fold (addc a, b) -> (or a, b), 0 iff a and b share no bits. APInt LHSZero, LHSOne; APInt RHSZero, RHSOne; APInt Mask = APInt::getAllOnesValue(VT.getSizeInBits()); @@ -1111,8 +1109,7 @@ SDValue DAGCombiner::visitADDC(SDNode *N) { if ((RHSZero & (~LHSZero & Mask)) == (~LHSZero & Mask) || (LHSZero & (~RHSZero & Mask)) == (~RHSZero & Mask)) return CombineTo(N, DAG.getNode(ISD::OR, N->getDebugLoc(), VT, N0, N1), - DAG.getNode(ISD::CARRY_FALSE, - N->getDebugLoc(), MVT::Flag)); + DAG.getConstant(0, N1.getValueType())); } return SDValue(); @@ -1131,8 +1128,9 @@ SDValue DAGCombiner::visitADDE(SDNode *N) { N1, N0, CarryIn); // fold (adde x, y, false) -> (addc x, y) - if (CarryIn.getOpcode() == ISD::CARRY_FALSE) - return DAG.getNode(ISD::ADDC, N->getDebugLoc(), N->getVTList(), N1, N0); + if (ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(CarryIn)) + if (N2C->getAPIntValue()==0) + return DAG.getNode(ISD::ADDC, N->getDebugLoc(), N->getVTList(), N1, N0); return SDValue(); } diff --git a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp index eb9342cc8b..a8d8b7d9c7 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp @@ -98,6 +98,10 @@ void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) { case ISD::USUBO: Res = PromoteIntRes_UADDSUBO(N, ResNo); break; case ISD::SMULO: case ISD::UMULO: Res = PromoteIntRes_XMULO(N, ResNo); break; + case ISD::ADDC: + case ISD::SUBC: Res = PromoteIntRes_ADDSUBC(N, ResNo); break; + case ISD::ADDE: + case ISD::SUBE: Res = PromoteIntRes_ADDSUBE(N, ResNo); break; case ISD::ATOMIC_LOAD_ADD: case ISD::ATOMIC_LOAD_SUB: @@ -121,6 +125,35 @@ void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) { SetPromotedInteger(SDValue(N, ResNo), Res); } +SDValue DAGTypeLegalizer::PromoteIntRes_ADDSUBC(SDNode *N, unsigned ResNo) { + // Only the carry bit result is expected to be promoted. + assert(ResNo == 1 && "Only carry bit result promotion currently supported!"); + return PromoteIntRes_Overflow(N); +} + +SDValue DAGTypeLegalizer::PromoteIntRes_ADDSUBE(SDNode *N, unsigned ResNo) { + // Only the carry bit result is expected to be promoted. + assert(ResNo == 1 && "Only carry bit result promotion currently supported!"); + // This is a ternary operator, so clone a slightly modified + // PromoteIntRes_Overflow here (this is the only client). + if (ResNo == 1) { + // Simply change the return type of the boolean result. + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(1)); + MVT ValueVTs[] = { N->getValueType(0), NVT }; + SDValue Ops[] = { N->getOperand(0), N->getOperand(1), N->getOperand(2) }; + SDValue Res = DAG.getNode(N->getOpcode(), N->getDebugLoc(), + DAG.getVTList(ValueVTs, 2), Ops, 3); + + // Modified the sum result - switch anything that used the old sum to use + // the new one. + ReplaceValueWith(SDValue(N, 0), Res); + + return SDValue(Res.getNode(), 1); + } + assert(0 && "Do not know how to promote this operator!"); + abort(); +} + SDValue DAGTypeLegalizer::PromoteIntRes_AssertSext(SDNode *N) { // Sign-extend the new bits, and continue the assertion. SDValue Op = SExtPromotedInteger(N->getOperand(0)); @@ -419,7 +452,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_LOAD(LoadSDNode *N) { return Res; } -/// Promote the overflow flag of an overflowing arithmetic node. +/// Promote the overflow or carry result of an overflowing arithmetic node. SDValue DAGTypeLegalizer::PromoteIntRes_Overflow(SDNode *N) { // Simply change the return type of the boolean result. MVT NVT = TLI.getTypeToTransformTo(N->getValueType(1)); @@ -666,6 +699,8 @@ bool DAGTypeLegalizer::PromoteIntegerOperand(SDNode *N, unsigned OpNo) { assert(0 && "Do not know how to promote this operator's operand!"); abort(); + case ISD::ADDE: + case ISD::SUBE: Res = PromoteIntOp_ADDSUBE(N, OpNo); break; case ISD::ANY_EXTEND: Res = PromoteIntOp_ANY_EXTEND(N); break; case ISD::BIT_CONVERT: Res = PromoteIntOp_BIT_CONVERT(N); break; case ISD::BR_CC: Res = PromoteIntOp_BR_CC(N, OpNo); break; @@ -743,6 +778,13 @@ void DAGTypeLegalizer::PromoteSetCCOperands(SDValue &NewLHS,SDValue &NewRHS, } } +SDValue DAGTypeLegalizer::PromoteIntOp_ADDSUBE(SDNode *N, unsigned OpNo) { + assert(OpNo == 2 && "Don't know how to promote this operand!"); + return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0), + N->getOperand(1), + GetPromotedInteger(N->getOperand(2))); +} + SDValue DAGTypeLegalizer::PromoteIntOp_ANY_EXTEND(SDNode *N) { SDValue Op = GetPromotedInteger(N->getOperand(0)); return DAG.getNode(ISD::ANY_EXTEND, N->getDebugLoc(), N->getValueType(0), Op); @@ -1063,7 +1105,7 @@ void DAGTypeLegalizer::ExpandShiftByConstant(SDNode *N, unsigned Amt, TLI.isOperationLegalOrCustom(ISD::ADDC, TLI.getTypeToExpandTo(NVT))) { // Emit this X << 1 as X+X. - SDVTList VTList = DAG.getVTList(NVT, MVT::Flag); + SDVTList VTList = DAG.getVTList(NVT, MVT::i1); SDValue LoOps[2] = { InL, InL }; Lo = DAG.getNode(ISD::ADDC, dl, VTList, LoOps, 2); SDValue HiOps[3] = { InH, InH, Lo.getValue(1) }; @@ -1299,7 +1341,7 @@ void DAGTypeLegalizer::ExpandIntRes_ADDSUB(SDNode *N, TLI.getTypeToExpandTo(NVT)); if (hasCarry) { - SDVTList VTList = DAG.getVTList(NVT, MVT::Flag); + SDVTList VTList = DAG.getVTList(NVT, MVT::i1); if (N->getOpcode() == ISD::ADD) { Lo = DAG.getNode(ISD::ADDC, dl, VTList, LoOps, 2); HiOps[2] = Lo.getValue(1); @@ -1344,7 +1386,7 @@ void DAGTypeLegalizer::ExpandIntRes_ADDSUBC(SDNode *N, DebugLoc dl = N->getDebugLoc(); GetExpandedInteger(N->getOperand(0), LHSL, LHSH); GetExpandedInteger(N->getOperand(1), RHSL, RHSH); - SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Flag); + SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::i1); SDValue LoOps[2] = { LHSL, RHSL }; SDValue HiOps[3] = { LHSH, RHSH }; @@ -1358,8 +1400,8 @@ void DAGTypeLegalizer::ExpandIntRes_ADDSUBC(SDNode *N, Hi = DAG.getNode(ISD::SUBE, dl, VTList, HiOps, 3); } - // Legalized the flag result - switch anything that used the old flag to - // use the new one. + // Legalized the second result (carry bit) - switch anything that used the + // result to use the new one. ReplaceValueWith(SDValue(N, 1), Hi.getValue(1)); } @@ -1370,7 +1412,7 @@ void DAGTypeLegalizer::ExpandIntRes_ADDSUBE(SDNode *N, DebugLoc dl = N->getDebugLoc(); GetExpandedInteger(N->getOperand(0), LHSL, LHSH); GetExpandedInteger(N->getOperand(1), RHSL, RHSH); - SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Flag); + SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::i1); SDValue LoOps[3] = { LHSL, RHSL, N->getOperand(2) }; SDValue HiOps[3] = { LHSH, RHSH }; @@ -1378,8 +1420,8 @@ void DAGTypeLegalizer::ExpandIntRes_ADDSUBE(SDNode *N, HiOps[2] = Lo.getValue(1); Hi = DAG.getNode(N->getOpcode(), dl, VTList, HiOps, 3); - // Legalized the flag result - switch anything that used the old flag to - // use the new one. + // Legalized the second result (carry bit) - switch anything that used the + // result to use the new one. ReplaceValueWith(SDValue(N, 1), Hi.getValue(1)); } diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/lib/CodeGen/SelectionDAG/LegalizeTypes.h index 75c89246a3..9488b49a01 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeTypes.h +++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.h @@ -242,6 +242,8 @@ private: // Integer Result Promotion. void PromoteIntegerResult(SDNode *N, unsigned ResNo); + SDValue PromoteIntRes_ADDSUBC(SDNode *N, unsigned ResNo); + SDValue PromoteIntRes_ADDSUBE(SDNode *N, unsigned ResNo); SDValue PromoteIntRes_AssertSext(SDNode *N); SDValue PromoteIntRes_AssertZext(SDNode *N); SDValue PromoteIntRes_Atomic1(AtomicSDNode *N); @@ -278,6 +280,7 @@ private: // Integer Operand Promotion. bool PromoteIntegerOperand(SDNode *N, unsigned OperandNo); + SDValue PromoteIntOp_ADDSUBE(SDNode *N, unsigned OpNo); SDValue PromoteIntOp_ANY_EXTEND(SDNode *N); SDValue PromoteIntOp_BIT_CONVERT(SDNode *N); SDValue PromoteIntOp_BUILD_PAIR(SDNode *N); diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp index 7aa15bcc68..e509372e9f 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp @@ -268,6 +268,13 @@ unsigned ScheduleDAGSDNodes::ComputeMemOperandsEnd(SDNode *Node) { unsigned N = Node->getNumOperands(); while (N && Node->getOperand(N - 1).getValueType() == MVT::Flag) --N; + // Skip hard registers set as a side effect (i.e. not result 0). + while (N && Node->getOperand(N - 1).getOpcode() == ISD::CopyToReg && + Node->getOperand(N-1).getResNo() != 0 && + !TargetRegisterInfo::isVirtualRegister( + dyn_cast<RegisterSDNode>(Node->getOperand(N-1).getOperand(1)) + ->getReg())) + --N; if (N && Node->getOperand(N - 1).getValueType() == MVT::Other) --N; // Ignore chain if it exists. return N; diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 195896ee89..279c5cae01 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -5257,7 +5257,6 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const { case ISD::EXTRACT_SUBVECTOR: return "extract_subvector"; case ISD::SCALAR_TO_VECTOR: return "scalar_to_vector"; case ISD::VECTOR_SHUFFLE: return "vector_shuffle"; - case ISD::CARRY_FALSE: return "carry_false"; case ISD::ADDC: return "addc"; case ISD::ADDE: return "adde"; case ISD::SADDO: return "saddo"; |