X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;ds=sidebyside;f=lib%2FCodeGen%2FSelectionDAG%2FLegalizeIntegerTypes.cpp;h=bde61ad81adbcef191f3cfd4fe271b8aafa53dcd;hb=be1ad4de2900451626c8d4ace07b9ea16099ea1d;hp=bad430be4d2cc6f79b11683f97ed440eed11b5f2;hpb=11ac797f5ed142f11aafde3dd76c28a73d84282e;p=oota-llvm.git diff --git a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp index bad430be4d2..bde61ad81ad 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp @@ -19,7 +19,6 @@ //===----------------------------------------------------------------------===// #include "LegalizeTypes.h" -#include "llvm/Constants.h" using namespace llvm; //===----------------------------------------------------------------------===// @@ -34,6 +33,18 @@ void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) { DEBUG(cerr << "Promote integer result: "; N->dump(&DAG); cerr << "\n"); SDOperand Result = SDOperand(); + // See if the target wants to custom expand this node. + if (TLI.getOperationAction(N->getOpcode(), N->getValueType(ResNo)) == + TargetLowering::Custom) { + // If the target wants to, allow it to lower this itself. + if (SDNode *P = TLI.ReplaceNodeResults(N, DAG)) { + // Everything that once used N now uses P. We are guaranteed that the + // result value types of N and the result value types of P match. + ReplaceNodeWith(N, P); + return; + } + } + switch (N->getOpcode()) { default: #ifndef NDEBUG @@ -49,7 +60,6 @@ void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) { case ISD::SIGN_EXTEND: case ISD::ZERO_EXTEND: case ISD::ANY_EXTEND: Result = PromoteIntRes_INT_EXTEND(N); break; - case ISD::FP_ROUND: Result = PromoteIntRes_FP_ROUND(N); break; case ISD::FP_TO_SINT: case ISD::FP_TO_UINT: Result = PromoteIntRes_FP_TO_XINT(N); break; case ISD::SETCC: Result = PromoteIntRes_SETCC(N); break; @@ -84,6 +94,8 @@ void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) { case ISD::EXTRACT_VECTOR_ELT: Result = PromoteIntRes_EXTRACT_VECTOR_ELT(N); break; + + case ISD::VAARG : Result = PromoteIntRes_VAARG(N); break; } // If Result is null, the sub-method took care of registering the result. @@ -156,15 +168,6 @@ SDOperand DAGTypeLegalizer::PromoteIntRes_INT_EXTEND(SDNode *N) { return DAG.getNode(N->getOpcode(), NVT, N->getOperand(0)); } -SDOperand DAGTypeLegalizer::PromoteIntRes_FP_ROUND(SDNode *N) { - // NOTE: Assumes input is legal. - if (N->getConstantOperandVal(1) == 0) - return DAG.getNode(ISD::FP_ROUND_INREG, N->getOperand(0).getValueType(), - N->getOperand(0), DAG.getValueType(N->getValueType(0))); - // If the precision discard isn't needed, just return the operand unrounded. - return N->getOperand(0); -} - SDOperand DAGTypeLegalizer::PromoteIntRes_FP_TO_XINT(SDNode *N) { unsigned NewOpc = N->getOpcode(); MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); @@ -238,11 +241,11 @@ SDOperand DAGTypeLegalizer::PromoteIntRes_BIT_CONVERT(SDNode *N) { case ExpandInteger: case ExpandFloat: break; - case Scalarize: + case ScalarizeVector: // Convert the element to an integer and promote it by hand. return DAG.getNode(ISD::ANY_EXTEND, OutVT, BitConvertToInteger(GetScalarizedVector(InOp))); - case Split: + case SplitVector: // For example, i32 = BIT_CONVERT v2i16 on alpha. Convert the split // pieces of the input into integers and reassemble in the final type. SDOperand Lo, Hi; @@ -360,9 +363,9 @@ SDOperand DAGTypeLegalizer::PromoteIntRes_CTTZ(SDNode *N) { // The count is the same in the promoted type except if the original // value was zero. This can be handled by setting the bit just off // the top of the original type. - Op = DAG.getNode(ISD::OR, NVT, Op, - // FIXME: Do this using an APINT constant. - DAG.getConstant(1UL << OVT.getSizeInBits(), NVT)); + APInt TopBit(NVT.getSizeInBits(), 0); + TopBit.set(OVT.getSizeInBits()); + Op = DAG.getNode(ISD::OR, NVT, Op, DAG.getConstant(TopBit, NVT)); return DAG.getNode(ISD::CTTZ, NVT, Op); } @@ -411,6 +414,37 @@ SDOperand DAGTypeLegalizer::PromoteIntRes_EXTRACT_VECTOR_ELT(SDNode *N) { return DAG.getNode(ISD::SELECT, NewVT, Odd, Hi, Lo); } +SDOperand DAGTypeLegalizer::PromoteIntRes_VAARG(SDNode *N) { + SDOperand Chain = N->getOperand(0); // Get the chain. + SDOperand Ptr = N->getOperand(1); // Get the pointer. + MVT VT = N->getValueType(0); + + const Value *V = cast(N->getOperand(2))->getValue(); + SDOperand VAList = DAG.getLoad(TLI.getPointerTy(), Chain, Ptr, V, 0); + + // Increment the arg pointer, VAList, to the next vaarg + // FIXME: should the ABI size be used for the increment? Think of + // x86 long double (10 bytes long, but aligned on 4 or 8 bytes) or + // integers of unusual size (such MVT::i1, which gives an increment + // of zero here!). + unsigned Increment = VT.getSizeInBits() / 8; + SDOperand Tmp = DAG.getNode(ISD::ADD, TLI.getPointerTy(), VAList, + DAG.getConstant(Increment, TLI.getPointerTy())); + + // Store the incremented VAList to the pointer. + Tmp = DAG.getStore(VAList.getValue(1), Tmp, Ptr, V, 0); + + // Load the actual argument out of the arg pointer VAList. + Tmp = DAG.getExtLoad(ISD::EXTLOAD, TLI.getTypeToTransformTo(VT), Tmp, + VAList, NULL, 0, VT); + + // Legalized the chain result - switch anything that used the old chain to + // use the new one. + ReplaceValueWith(SDOperand(N, 1), Tmp.getValue(1)); + return Tmp; +} + + //===----------------------------------------------------------------------===// // Integer Operand Promotion //===----------------------------------------------------------------------===// @@ -421,40 +455,48 @@ SDOperand DAGTypeLegalizer::PromoteIntRes_EXTRACT_VECTOR_ELT(SDNode *N) { /// node may need promotion or expansion as well as the specified one. bool DAGTypeLegalizer::PromoteIntegerOperand(SDNode *N, unsigned OpNo) { DEBUG(cerr << "Promote integer operand: "; N->dump(&DAG); cerr << "\n"); - SDOperand Res; - switch (N->getOpcode()) { - default: -#ifndef NDEBUG - cerr << "PromoteIntegerOperand Op #" << OpNo << ": "; - N->dump(&DAG); cerr << "\n"; -#endif - assert(0 && "Do not know how to promote this operator's operand!"); - abort(); + SDOperand Res = SDOperand(); - case ISD::ANY_EXTEND: Res = PromoteIntOp_ANY_EXTEND(N); break; - case ISD::ZERO_EXTEND: Res = PromoteIntOp_ZERO_EXTEND(N); break; - case ISD::SIGN_EXTEND: Res = PromoteIntOp_SIGN_EXTEND(N); break; - case ISD::TRUNCATE: Res = PromoteIntOp_TRUNCATE(N); break; - case ISD::FP_EXTEND: Res = PromoteIntOp_FP_EXTEND(N); break; - case ISD::FP_ROUND: Res = PromoteIntOp_FP_ROUND(N); break; - case ISD::SINT_TO_FP: - case ISD::UINT_TO_FP: Res = PromoteIntOp_INT_TO_FP(N); break; - case ISD::BUILD_PAIR: Res = PromoteIntOp_BUILD_PAIR(N); break; - - case ISD::BRCOND: Res = PromoteIntOp_BRCOND(N, OpNo); break; - case ISD::BR_CC: Res = PromoteIntOp_BR_CC(N, OpNo); break; - case ISD::SELECT: Res = PromoteIntOp_SELECT(N, OpNo); break; - case ISD::SETCC: Res = PromoteIntOp_SETCC(N, OpNo); break; - - case ISD::STORE: Res = PromoteIntOp_STORE(cast(N), - OpNo); break; - - case ISD::BUILD_VECTOR: Res = PromoteIntOp_BUILD_VECTOR(N); break; - case ISD::INSERT_VECTOR_ELT: - Res = PromoteIntOp_INSERT_VECTOR_ELT(N, OpNo); - break; + if (TLI.getOperationAction(N->getOpcode(), N->getOperand(OpNo).getValueType()) + == TargetLowering::Custom) + Res = TLI.LowerOperation(SDOperand(N, OpNo), DAG); + + if (Res.Val == 0) { + switch (N->getOpcode()) { + default: + #ifndef NDEBUG + cerr << "PromoteIntegerOperand Op #" << OpNo << ": "; + N->dump(&DAG); cerr << "\n"; + #endif + assert(0 && "Do not know how to promote this operator's operand!"); + abort(); - case ISD::MEMBARRIER: Res = PromoteIntOp_MEMBARRIER(N); break; + case ISD::ANY_EXTEND: Res = PromoteIntOp_ANY_EXTEND(N); break; + case ISD::ZERO_EXTEND: Res = PromoteIntOp_ZERO_EXTEND(N); break; + case ISD::SIGN_EXTEND: Res = PromoteIntOp_SIGN_EXTEND(N); break; + case ISD::TRUNCATE: Res = PromoteIntOp_TRUNCATE(N); break; + case ISD::FP_EXTEND: Res = PromoteIntOp_FP_EXTEND(N); break; + case ISD::FP_ROUND: Res = PromoteIntOp_FP_ROUND(N); break; + case ISD::SINT_TO_FP: + case ISD::UINT_TO_FP: Res = PromoteIntOp_INT_TO_FP(N); break; + case ISD::BUILD_PAIR: Res = PromoteIntOp_BUILD_PAIR(N); break; + + case ISD::BRCOND: Res = PromoteIntOp_BRCOND(N, OpNo); break; + case ISD::BR_CC: Res = PromoteIntOp_BR_CC(N, OpNo); break; + case ISD::SELECT: Res = PromoteIntOp_SELECT(N, OpNo); break; + case ISD::SELECT_CC: Res = PromoteIntOp_SELECT_CC(N, OpNo); break; + case ISD::SETCC: Res = PromoteIntOp_SETCC(N, OpNo); break; + + case ISD::STORE: Res = PromoteIntOp_STORE(cast(N), + OpNo); break; + + case ISD::BUILD_VECTOR: Res = PromoteIntOp_BUILD_VECTOR(N); break; + case ISD::INSERT_VECTOR_ELT: + Res = PromoteIntOp_INSERT_VECTOR_ELT(N, OpNo); + break; + + case ISD::MEMBARRIER: Res = PromoteIntOp_MEMBARRIER(N); break; + } } // If the result is null, the sub-method took care of registering results etc. @@ -568,7 +610,7 @@ SDOperand DAGTypeLegalizer::PromoteIntOp_BRCOND(SDNode *N, unsigned OpNo) { } SDOperand DAGTypeLegalizer::PromoteIntOp_BR_CC(SDNode *N, unsigned OpNo) { - assert(OpNo == 2 && "Don't know how to promote this operand"); + assert(OpNo == 2 && "Don't know how to promote this operand!"); SDOperand LHS = N->getOperand(2); SDOperand RHS = N->getOperand(3); @@ -580,8 +622,20 @@ SDOperand DAGTypeLegalizer::PromoteIntOp_BR_CC(SDNode *N, unsigned OpNo) { N->getOperand(1), LHS, RHS, N->getOperand(4)); } +SDOperand DAGTypeLegalizer::PromoteIntOp_SELECT_CC(SDNode *N, unsigned OpNo) { + assert(OpNo == 0 && "Don't know how to promote this operand!"); + + SDOperand LHS = N->getOperand(0); + SDOperand RHS = N->getOperand(1); + PromoteSetCCOperands(LHS, RHS, cast(N->getOperand(4))->get()); + + // The CC (#4) and the possible return values (#2 and #3) have legal types. + return DAG.UpdateNodeOperands(SDOperand(N, 0), LHS, RHS, N->getOperand(2), + N->getOperand(3), N->getOperand(4)); +} + SDOperand DAGTypeLegalizer::PromoteIntOp_SETCC(SDNode *N, unsigned OpNo) { - assert(OpNo == 0 && "Don't know how to promote this operand"); + assert(OpNo == 0 && "Don't know how to promote this operand!"); SDOperand LHS = N->getOperand(0); SDOperand RHS = N->getOperand(1); @@ -732,10 +786,10 @@ void DAGTypeLegalizer::ExpandIntegerResult(SDNode *N, unsigned ResNo) { Lo = Hi = SDOperand(); // See if the target wants to custom expand this node. - if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) == - TargetLowering::Custom) { + if (TLI.getOperationAction(N->getOpcode(), N->getValueType(ResNo)) == + TargetLowering::Custom) { // If the target wants to, allow it to lower this itself. - if (SDNode *P = TLI.ExpandOperationResult(N, DAG)) { + if (SDNode *P = TLI.ReplaceNodeResults(N, DAG)) { // Everything that once used N now uses P. We are guaranteed that the // result value types of N and the result value types of P match. ReplaceNodeWith(N, P); @@ -942,7 +996,17 @@ void DAGTypeLegalizer::ExpandIntRes_FP_TO_SINT(SDNode *N, SDOperand &Lo, MVT VT = N->getValueType(0); SDOperand Op = N->getOperand(0); RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; - if (VT == MVT::i64) { + + if (VT == MVT::i32) { + if (Op.getValueType() == MVT::f32) + LC = RTLIB::FPTOSINT_F32_I32; + else if (Op.getValueType() == MVT::f64) + LC = RTLIB::FPTOSINT_F64_I32; + else if (Op.getValueType() == MVT::f80) + LC = RTLIB::FPTOSINT_F80_I32; + else if (Op.getValueType() == MVT::ppcf128) + LC = RTLIB::FPTOSINT_PPCF128_I32; + } else if (VT == MVT::i64) { if (Op.getValueType() == MVT::f32) LC = RTLIB::FPTOSINT_F32_I64; else if (Op.getValueType() == MVT::f64) @@ -960,9 +1024,8 @@ void DAGTypeLegalizer::ExpandIntRes_FP_TO_SINT(SDNode *N, SDOperand &Lo, LC = RTLIB::FPTOSINT_F80_I128; else if (Op.getValueType() == MVT::ppcf128) LC = RTLIB::FPTOSINT_PPCF128_I128; - } else { - assert(0 && "Unexpected fp-to-sint conversion!"); } + assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected fp-to-sint conversion!"); SplitInteger(MakeLibCall(LC, VT, &Op, 1, true/*sign irrelevant*/), Lo, Hi); } @@ -971,7 +1034,16 @@ void DAGTypeLegalizer::ExpandIntRes_FP_TO_UINT(SDNode *N, SDOperand &Lo, MVT VT = N->getValueType(0); SDOperand Op = N->getOperand(0); RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; - if (VT == MVT::i64) { + if (VT == MVT::i32) { + if (Op.getValueType() == MVT::f32) + LC = RTLIB::FPTOUINT_F32_I32; + else if (Op.getValueType() == MVT::f64) + LC = RTLIB::FPTOUINT_F64_I32; + else if (Op.getValueType() == MVT::f80) + LC = RTLIB::FPTOUINT_F80_I32; + else if (Op.getValueType() == MVT::ppcf128) + LC = RTLIB::FPTOUINT_PPCF128_I32; + } else if (VT == MVT::i64) { if (Op.getValueType() == MVT::f32) LC = RTLIB::FPTOUINT_F32_I64; else if (Op.getValueType() == MVT::f64) @@ -989,9 +1061,8 @@ void DAGTypeLegalizer::ExpandIntRes_FP_TO_UINT(SDNode *N, SDOperand &Lo, LC = RTLIB::FPTOUINT_F80_I128; else if (Op.getValueType() == MVT::ppcf128) LC = RTLIB::FPTOUINT_PPCF128_I128; - } else { - assert(0 && "Unexpected fp-to-uint conversion!"); } + assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected fp-to-uint conversion!"); SplitInteger(MakeLibCall(LC, VT, &Op, 1, false/*sign irrelevant*/), Lo, Hi); } @@ -1577,11 +1648,11 @@ ExpandShiftWithKnownAmountBit(SDNode *N, SDOperand &Lo, SDOperand &Hi) { /// node may need promotion or expansion as well as the specified one. bool DAGTypeLegalizer::ExpandIntegerOperand(SDNode *N, unsigned OpNo) { DEBUG(cerr << "Expand integer operand: "; N->dump(&DAG); cerr << "\n"); - SDOperand Res(0, 0); + SDOperand Res = SDOperand(); if (TLI.getOperationAction(N->getOpcode(), N->getOperand(OpNo).getValueType()) == TargetLowering::Custom) - Res = TLI.LowerOperation(SDOperand(N, 0), DAG); + Res = TLI.LowerOperation(SDOperand(N, OpNo), DAG); if (Res.Val == 0) { switch (N->getOpcode()) {