diff --git a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp index caa92b51ef7..2a0b408fc8d 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp @@ -726,44 +726,10 @@ SDValue DAGTypeLegalizer::PromoteIntOp_BR_CC(SDNode *N, unsigned OpNo) { SDValue DAGTypeLegalizer::PromoteIntOp_BRCOND(SDNode *N, unsigned OpNo) { assert(OpNo == 1 && "only know how to promote condition"); - SDValue Cond = GetPromotedInteger(N->getOperand(1)); // Promote condition. - // Promote all the way up to SVT, the canonical SetCC type. + // Promote all the way up to the canonical SetCC type. MVT SVT = TLI.getSetCCResultType(MVT::Other); - assert(isTypeLegal(SVT) && "Illegal SetCC type!"); - assert(Cond.getValueType().bitsLE(SVT) && "Unexpected SetCC type!"); - - // Make sure the extra bits conform to getBooleanContents. There are - // two sets of extra bits: those in Cond, which come from type promotion, - // and those we need to add to have the final type be SVT (for most targets - // this last set of bits is empty). - unsigned CondBits = Cond.getValueSizeInBits(); - ISD::NodeType ExtendCode; - switch (TLI.getBooleanContents()) { - default: - assert(false && "Unknown BooleanContent!"); - case TargetLowering::UndefinedBooleanContent: - // Extend to SVT by adding rubbish. - ExtendCode = ISD::ANY_EXTEND; - break; - case TargetLowering::ZeroOrOneBooleanContent: - ExtendCode = ISD::ZERO_EXTEND; - if (!DAG.MaskedValueIsZero(Cond,APInt::getHighBitsSet(CondBits,CondBits-1))) - // All extra bits need to be cleared. Do this by zero extending the - // original condition value all the way to SVT. - Cond = N->getOperand(1); - break; - case TargetLowering::ZeroOrNegativeOneBooleanContent: { - ExtendCode = ISD::SIGN_EXTEND; - unsigned SignBits = DAG.ComputeNumSignBits(Cond); - if (SignBits != CondBits) - // All extra bits need to be sign extended. Do this by sign extending the - // original condition value all the way to SVT. - Cond = N->getOperand(1); - break; - } - } - Cond = DAG.getNode(ExtendCode, SVT, Cond); + SDValue Cond = PromoteTargetBoolean(N->getOperand(1), SVT); // The chain (Op#0) and basic block destination (Op#2) are always legal types. return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0), Cond, @@ -865,44 +831,10 @@ SDValue DAGTypeLegalizer::PromoteIntOp_MEMBARRIER(SDNode *N) { SDValue DAGTypeLegalizer::PromoteIntOp_SELECT(SDNode *N, unsigned OpNo) { assert(OpNo == 0 && "Only know how to promote condition"); - SDValue Cond = GetPromotedInteger(N->getOperand(0)); - // Promote all the way up to SVT, the canonical SetCC type. + // Promote all the way up to the canonical SetCC type. MVT SVT = TLI.getSetCCResultType(N->getOperand(1).getValueType()); - assert(isTypeLegal(SVT) && "Illegal SetCC type!"); - assert(Cond.getValueType().bitsLE(SVT) && "Unexpected SetCC type!"); - - // Make sure the extra bits conform to getBooleanContents. There are - // two sets of extra bits: those in Cond, which come from type promotion, - // and those we need to add to have the final type be SVT (for most targets - // this last set of bits is empty). - unsigned CondBits = Cond.getValueSizeInBits(); - ISD::NodeType ExtendCode; - switch (TLI.getBooleanContents()) { - default: - assert(false && "Unknown BooleanContent!"); - case TargetLowering::UndefinedBooleanContent: - // Extend to SVT by adding rubbish. - ExtendCode = ISD::ANY_EXTEND; - break; - case TargetLowering::ZeroOrOneBooleanContent: - ExtendCode = ISD::ZERO_EXTEND; - if (!DAG.MaskedValueIsZero(Cond,APInt::getHighBitsSet(CondBits,CondBits-1))) - // All extra bits need to be cleared. Do this by zero extending the - // original condition value all the way to SVT. - Cond = N->getOperand(0); - break; - case TargetLowering::ZeroOrNegativeOneBooleanContent: { - ExtendCode = ISD::SIGN_EXTEND; - unsigned SignBits = DAG.ComputeNumSignBits(Cond); - if (SignBits != CondBits) - // All extra bits need to be sign extended. Do this by sign extending the - // original condition value all the way to SVT. - Cond = N->getOperand(0); - break; - } - } - Cond = DAG.getNode(ExtendCode, SVT, Cond); + SDValue Cond = PromoteTargetBoolean(N->getOperand(0), SVT); return DAG.UpdateNodeOperands(SDValue(N, 0), Cond, N->getOperand(1), N->getOperand(2)); diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp index 704c537bb45..7045d7dd556 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp @@ -869,6 +869,42 @@ bool DAGTypeLegalizer::CustomLowerResults(SDNode *N, unsigned ResNo) { return true; } +/// GetSplitDestVTs - Compute the VTs needed for the low/hi parts of a type +/// which is split into two not necessarily identical pieces. +void DAGTypeLegalizer::GetSplitDestVTs(MVT InVT, MVT &LoVT, MVT &HiVT) { + if (!InVT.isVector()) { + LoVT = HiVT = TLI.getTypeToTransformTo(InVT); + } else { + MVT NewEltVT = InVT.getVectorElementType(); + unsigned NumElements = InVT.getVectorNumElements(); + if ((NumElements & (NumElements-1)) == 0) { // Simple power of two vector. + NumElements >>= 1; + LoVT = HiVT = MVT::getVectorVT(NewEltVT, NumElements); + } else { // Non-power-of-two vectors. + unsigned NewNumElts_Lo = 1 << Log2_32(NumElements); + unsigned NewNumElts_Hi = NumElements - NewNumElts_Lo; + LoVT = MVT::getVectorVT(NewEltVT, NewNumElts_Lo); + HiVT = MVT::getVectorVT(NewEltVT, NewNumElts_Hi); + } + } +} + +SDValue DAGTypeLegalizer::GetVectorElementPointer(SDValue VecPtr, MVT EltVT, + SDValue Index) { + // Make sure the index type is big enough to compute in. + if (Index.getValueType().bitsGT(TLI.getPointerTy())) + Index = DAG.getNode(ISD::TRUNCATE, TLI.getPointerTy(), Index); + else + Index = DAG.getNode(ISD::ZERO_EXTEND, TLI.getPointerTy(), Index); + + // Calculate the element offset and add it to the pointer. + unsigned EltSize = EltVT.getSizeInBits() / 8; // FIXME: should be ABI size. + + Index = DAG.getNode(ISD::MUL, Index.getValueType(), Index, + DAG.getConstant(EltSize, Index.getValueType())); + return DAG.getNode(ISD::ADD, Index.getValueType(), Index, VecPtr); +} + /// JoinIntegers - Build an integer with low bits Lo and high bits Hi. SDValue DAGTypeLegalizer::JoinIntegers(SDValue Lo, SDValue Hi) { MVT LVT = Lo.getValueType(); @@ -882,26 +918,24 @@ SDValue DAGTypeLegalizer::JoinIntegers(SDValue Lo, SDValue Hi) { return DAG.getNode(ISD::OR, NVT, Lo, Hi); } -/// SplitInteger - Return the lower LoVT bits of Op in Lo and the upper HiVT -/// bits in Hi. -void DAGTypeLegalizer::SplitInteger(SDValue Op, - MVT LoVT, MVT HiVT, - SDValue &Lo, SDValue &Hi) { - assert(LoVT.getSizeInBits() + HiVT.getSizeInBits() == - Op.getValueType().getSizeInBits() && "Invalid integer splitting!"); - Lo = DAG.getNode(ISD::TRUNCATE, LoVT, Op); - Hi = DAG.getNode(ISD::SRL, Op.getValueType(), Op, - DAG.getConstant(LoVT.getSizeInBits(), - TLI.getShiftAmountTy())); - Hi = DAG.getNode(ISD::TRUNCATE, HiVT, Hi); -} +/// LibCallify - Convert the node into a libcall with the same prototype. +SDValue DAGTypeLegalizer::LibCallify(RTLIB::Libcall LC, SDNode *N, + bool isSigned) { + unsigned NumOps = N->getNumOperands(); + if (NumOps == 0) { + return MakeLibCall(LC, N->getValueType(0), 0, 0, isSigned); + } else if (NumOps == 1) { + SDValue Op = N->getOperand(0); + return MakeLibCall(LC, N->getValueType(0), &Op, 1, isSigned); + } else if (NumOps == 2) { + SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; + return MakeLibCall(LC, N->getValueType(0), Ops, 2, isSigned); + } + SmallVector Ops(NumOps); + for (unsigned i = 0; i < NumOps; ++i) + Ops[i] = N->getOperand(i); -/// SplitInteger - Return the lower and upper halves of Op's bits in a value -/// type half the size of Op's. -void DAGTypeLegalizer::SplitInteger(SDValue Op, - SDValue &Lo, SDValue &Hi) { - MVT HalfVT = MVT::getIntegerVT(Op.getValueType().getSizeInBits()/2); - SplitInteger(Op, HalfVT, HalfVT, Lo, Hi); + return MakeLibCall(LC, N->getValueType(0), &Ops[0], NumOps, isSigned); } /// MakeLibCall - Generate a libcall taking the given operands as arguments and @@ -930,60 +964,51 @@ SDValue DAGTypeLegalizer::MakeLibCall(RTLIB::Libcall LC, MVT RetVT, return CallInfo.first; } -/// LibCallify - Convert the node into a libcall with the same prototype. -SDValue DAGTypeLegalizer::LibCallify(RTLIB::Libcall LC, SDNode *N, - bool isSigned) { - unsigned NumOps = N->getNumOperands(); - if (NumOps == 0) { - return MakeLibCall(LC, N->getValueType(0), 0, 0, isSigned); - } else if (NumOps == 1) { - SDValue Op = N->getOperand(0); - return MakeLibCall(LC, N->getValueType(0), &Op, 1, isSigned); - } else if (NumOps == 2) { - SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; - return MakeLibCall(LC, N->getValueType(0), Ops, 2, isSigned); +/// PromoteTargetBoolean - Promote the given target boolean to a target boolean +/// of the given type. A target boolean is an integer value, not necessarily of +/// type i1, the bits of which conform to getBooleanContents. +SDValue DAGTypeLegalizer::PromoteTargetBoolean(SDValue Bool, MVT VT) { + ISD::NodeType ExtendCode; + switch (TLI.getBooleanContents()) { + default: + assert(false && "Unknown BooleanContent!"); + case TargetLowering::UndefinedBooleanContent: + // Extend to VT by adding rubbish bits. + ExtendCode = ISD::ANY_EXTEND; + break; + case TargetLowering::ZeroOrOneBooleanContent: + // Extend to VT by adding zero bits. + ExtendCode = ISD::ZERO_EXTEND; + break; + case TargetLowering::ZeroOrNegativeOneBooleanContent: { + // Extend to VT by copying the sign bit. + ExtendCode = ISD::SIGN_EXTEND; + break; } - SmallVector Ops(NumOps); - for (unsigned i = 0; i < NumOps; ++i) - Ops[i] = N->getOperand(i); - - return MakeLibCall(LC, N->getValueType(0), &Ops[0], NumOps, isSigned); + } + return DAG.getNode(ExtendCode, VT, Bool); } -SDValue DAGTypeLegalizer::GetVectorElementPointer(SDValue VecPtr, MVT EltVT, - SDValue Index) { - // Make sure the index type is big enough to compute in. - if (Index.getValueType().bitsGT(TLI.getPointerTy())) - Index = DAG.getNode(ISD::TRUNCATE, TLI.getPointerTy(), Index); - else - Index = DAG.getNode(ISD::ZERO_EXTEND, TLI.getPointerTy(), Index); - - // Calculate the element offset and add it to the pointer. - unsigned EltSize = EltVT.getSizeInBits() / 8; // FIXME: should be ABI size. - - Index = DAG.getNode(ISD::MUL, Index.getValueType(), Index, - DAG.getConstant(EltSize, Index.getValueType())); - return DAG.getNode(ISD::ADD, Index.getValueType(), Index, VecPtr); +/// SplitInteger - Return the lower LoVT bits of Op in Lo and the upper HiVT +/// bits in Hi. +void DAGTypeLegalizer::SplitInteger(SDValue Op, + MVT LoVT, MVT HiVT, + SDValue &Lo, SDValue &Hi) { + assert(LoVT.getSizeInBits() + HiVT.getSizeInBits() == + Op.getValueType().getSizeInBits() && "Invalid integer splitting!"); + Lo = DAG.getNode(ISD::TRUNCATE, LoVT, Op); + Hi = DAG.getNode(ISD::SRL, Op.getValueType(), Op, + DAG.getConstant(LoVT.getSizeInBits(), + TLI.getShiftAmountTy())); + Hi = DAG.getNode(ISD::TRUNCATE, HiVT, Hi); } -/// GetSplitDestVTs - Compute the VTs needed for the low/hi parts of a type -/// which is split into two not necessarily identical pieces. -void DAGTypeLegalizer::GetSplitDestVTs(MVT InVT, MVT &LoVT, MVT &HiVT) { - if (!InVT.isVector()) { - LoVT = HiVT = TLI.getTypeToTransformTo(InVT); - } else { - MVT NewEltVT = InVT.getVectorElementType(); - unsigned NumElements = InVT.getVectorNumElements(); - if ((NumElements & (NumElements-1)) == 0) { // Simple power of two vector. - NumElements >>= 1; - LoVT = HiVT = MVT::getVectorVT(NewEltVT, NumElements); - } else { // Non-power-of-two vectors. - unsigned NewNumElts_Lo = 1 << Log2_32(NumElements); - unsigned NewNumElts_Hi = NumElements - NewNumElts_Lo; - LoVT = MVT::getVectorVT(NewEltVT, NewNumElts_Lo); - HiVT = MVT::getVectorVT(NewEltVT, NewNumElts_Hi); - } - } +/// SplitInteger - Return the lower and upper halves of Op's bits in a value +/// type half the size of Op's. +void DAGTypeLegalizer::SplitInteger(SDValue Op, + SDValue &Lo, SDValue &Hi) { + MVT HalfVT = MVT::getIntegerVT(Op.getValueType().getSizeInBits()/2); + SplitInteger(Op, HalfVT, HalfVT, Lo, Hi); } diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/lib/CodeGen/SelectionDAG/LegalizeTypes.h index e98837cb270..9439d17f02d 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeTypes.h +++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.h @@ -191,25 +191,21 @@ private: void RemapValue(SDValue &N); // Common routines. - void ReplaceValueWith(SDValue From, SDValue To); - - bool CustomLowerResults(SDNode *N, unsigned ResNo); - + SDValue BitConvertToInteger(SDValue Op); SDValue CreateStackStoreLoad(SDValue Op, MVT DestVT); + bool CustomLowerResults(SDNode *N, unsigned ResNo); + SDValue GetVectorElementPointer(SDValue VecPtr, MVT EltVT, SDValue Index); + SDValue JoinIntegers(SDValue Lo, SDValue Hi); + SDValue LibCallify(RTLIB::Libcall LC, SDNode *N, bool isSigned); SDValue MakeLibCall(RTLIB::Libcall LC, MVT RetVT, const SDValue *Ops, unsigned NumOps, bool isSigned); - SDValue LibCallify(RTLIB::Libcall LC, SDNode *N, bool isSigned); - - SDValue BitConvertToInteger(SDValue Op); - SDValue JoinIntegers(SDValue Lo, SDValue Hi); + SDValue PromoteTargetBoolean(SDValue Bool, MVT VT); + void ReplaceValueWith(SDValue From, SDValue To); + void SetIgnoredNodeResult(SDNode* N); void SplitInteger(SDValue Op, SDValue &Lo, SDValue &Hi); void SplitInteger(SDValue Op, MVT LoVT, MVT HiVT, SDValue &Lo, SDValue &Hi); - SDValue GetVectorElementPointer(SDValue VecPtr, MVT EltVT, SDValue Index); - - void SetIgnoredNodeResult(SDNode* N); - //===--------------------------------------------------------------------===// // Integer Promotion Support: LegalizeIntegerTypes.cpp //===--------------------------------------------------------------------===//