From 859157daee6a4b49e99921832e1dde065167b317 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 15 Jan 2005 06:17:04 +0000 Subject: [PATCH] Add new SIGN_EXTEND_INREG, ZERO_EXTEND_INREG, and FP_ROUND_INREG operators. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@19568 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/SelectionDAG.h | 4 +- include/llvm/CodeGen/SelectionDAGNodes.h | 24 +++++- lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 73 +++++++++++++++---- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 1 - 4 files changed, 83 insertions(+), 19 deletions(-) diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index 4feaf909f2f..12c3c215628 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -145,9 +145,11 @@ public: std::vector &Children); // getNode - These versions take an extra value type for extending and - // truncating loads and stores. + // truncating loads, stores, rounds, extends etc. SDOperand getNode(unsigned Opcode, MVT::ValueType VT, SDOperand N1, SDOperand N2, MVT::ValueType EVT); + SDOperand getNode(unsigned Opcode, MVT::ValueType VT, + SDOperand N, MVT::ValueType EVT); SDOperand getNode(unsigned Opcode, MVT::ValueType VT, SDOperand N1, SDOperand N2, SDOperand N3, MVT::ValueType EVT); diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index b82671e0aee..d872222c8a6 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -126,15 +126,30 @@ namespace ISD { SINT_TO_FP, UINT_TO_FP, + // SIGN_EXTEND_INREG/ZERO_EXTEND_INREG - These operators atomically performs + // a SHL/(SRA|SHL) pair to (sign|zero) extend a small value in a large + // integer register (e.g. sign extending the low 8 bits of a 32-bit register + // to fill the top 24 bits with the 7th bit). The size of the smaller type + // is indicated by the ExtraValueType in the MVTSDNode for the operator. + SIGN_EXTEND_INREG, + ZERO_EXTEND_INREG, + // FP_TO_[US]INT - Convert a floating point value to a signed or unsigned // integer. FP_TO_SINT, FP_TO_UINT, // FP_ROUND - Perform a rounding operation from the current - // precision down to the specified precision. + // precision down to the specified precision (currently always 64->32). FP_ROUND, + // FP_ROUND_INREG - This operator takes a floating point register, and + // rounds it to a floating point value. It then promotes it and returns it + // in a register of the same size. This operation effectively just discards + // excess precision. The type to round down to is specified by the + // ExtraValueType in the MVTSDNode (currently always 64->32->64). + FP_ROUND_INREG, + // FP_EXTEND - Extend a smaller FP type into a larger FP type. FP_EXTEND, @@ -706,6 +721,10 @@ class MVTSDNode : public SDNode { MVT::ValueType ExtraValueType; protected: friend class SelectionDAG; + MVTSDNode(unsigned Opc, MVT::ValueType VT1, SDOperand Op0, MVT::ValueType EVT) + : SDNode(Opc, Op0), ExtraValueType(EVT) { + setValueTypes(VT1); + } MVTSDNode(unsigned Opc, MVT::ValueType VT1, MVT::ValueType VT2, SDOperand Op0, SDOperand Op1, MVT::ValueType EVT) : SDNode(Opc, Op0, Op1), ExtraValueType(EVT) { @@ -723,6 +742,9 @@ public: static bool classof(const MVTSDNode *) { return true; } static bool classof(const SDNode *N) { return + N->getOpcode() == ISD::SIGN_EXTEND_INREG || + N->getOpcode() == ISD::ZERO_EXTEND_INREG || + N->getOpcode() == ISD::FP_ROUND_INREG || N->getOpcode() == ISD::EXTLOAD || N->getOpcode() == ISD::SEXTLOAD || N->getOpcode() == ISD::ZEXTLOAD || diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index e1b52019e96..c18dd40f6dd 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -220,26 +220,19 @@ void SelectionDAG::DeleteNodeIfDead(SDNode *N, void *NodeSet) { N->getOperand(1)), cast(N)->getCondition())); break; - case ISD::TRUNCSTORE: { - EVTStruct NN; - NN.Opcode = ISD::TRUNCSTORE; - NN.VT = N->getValueType(0); - NN.EVT = cast(N)->getExtraValueType(); - NN.Ops.push_back(N->getOperand(0)); - NN.Ops.push_back(N->getOperand(1)); - NN.Ops.push_back(N->getOperand(2)); - MVTSDNodes.erase(NN); - break; - } + case ISD::TRUNCSTORE: + case ISD::SIGN_EXTEND_INREG: + case ISD::ZERO_EXTEND_INREG: + case ISD::FP_ROUND_INREG: case ISD::EXTLOAD: case ISD::SEXTLOAD: case ISD::ZEXTLOAD: { EVTStruct NN; - NN.Opcode = N->getOpcode(); + NN.Opcode = ISD::TRUNCSTORE; NN.VT = N->getValueType(0); NN.EVT = cast(N)->getExtraValueType(); - NN.Ops.push_back(N->getOperand(0)); - NN.Ops.push_back(N->getOperand(1)); + for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) + NN.Ops.push_back(N->getOperand(i)); MVTSDNodes.erase(NN); break; } @@ -856,6 +849,41 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT, } } +SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,SDOperand N1, + MVT::ValueType EVT) { + + switch (Opcode) { + default: assert(0 && "Bad opcode for this accessor!"); + case ISD::FP_ROUND_INREG: + assert(VT == N1.getValueType() && "Not an inreg round!"); + assert(MVT::isFloatingPoint(VT) && MVT::isFloatingPoint(EVT) && + "Cannot FP_ROUND_INREG integer types"); + if (EVT == VT) return N1; // Not actually rounding + assert(EVT < VT && "Not rounding down!"); + break; + case ISD::ZERO_EXTEND_INREG: + case ISD::SIGN_EXTEND_INREG: + assert(VT == N1.getValueType() && "Not an inreg extend!"); + assert(MVT::isInteger(VT) && MVT::isInteger(EVT) && + "Cannot *_EXTEND_INREG FP types"); + if (EVT == VT) return N1; // Not actually extending + assert(EVT < VT && "Not extending!"); + break; + } + + EVTStruct NN; + NN.Opcode = Opcode; + NN.VT = VT; + NN.EVT = EVT; + NN.Ops.push_back(N1); + + SDNode *&N = MVTSDNodes[NN]; + if (N) return SDOperand(N, 0); + N = new MVTSDNode(Opcode, VT, N1, EVT); + AllNodes.push_back(N); + return SDOperand(N, 0); +} + SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,SDOperand N1, SDOperand N2, MVT::ValueType EVT) { switch (Opcode) { @@ -894,10 +922,20 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,SDOperand N1, switch (Opcode) { default: assert(0 && "Bad opcode for this accessor!"); case ISD::TRUNCSTORE: +#if 0 // FIXME: If the target supports EVT natively, convert to a truncate/store + // If this is a truncating store of a constant, convert to the desired type + // and store it instead. + if (isa(N1)) { + SDOperand Op = getNode(ISD::TRUNCATE, EVT, N1); + if (isa(Op)) + N1 = Op; + } + // Also for ConstantFP? +#endif if (N1.getValueType() == EVT) // Normal store? return getNode(ISD::STORE, VT, N1, N2, N3); - assert(N1.getValueType() > EVT && "Not a truncation?"); - assert(MVT::isInteger(N1.getValueType()) == MVT::isInteger(EVT) && + assert(N2.getValueType() > EVT && "Not a truncation?"); + assert(MVT::isInteger(N2.getValueType()) == MVT::isInteger(EVT) && "Can't do FP-INT conversion!"); break; } @@ -988,8 +1026,11 @@ const char *SDNode::getOperationName() const { // Conversion operators. case ISD::SIGN_EXTEND: return "sign_extend"; case ISD::ZERO_EXTEND: return "zero_extend"; + case ISD::SIGN_EXTEND_INREG: return "sign_extend_inreg"; + case ISD::ZERO_EXTEND_INREG: return "zero_extend_inreg"; case ISD::TRUNCATE: return "truncate"; case ISD::FP_ROUND: return "fp_round"; + case ISD::FP_ROUND_INREG: return "fp_round_inreg"; case ISD::FP_EXTEND: return "fp_extend"; case ISD::SINT_TO_FP: return "sint_to_fp"; diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 2d264c0ed2f..3250760acad 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -570,7 +570,6 @@ void SelectionDAGLowering::visitStore(StoreInst &I) { SDOperand Src = getValue(SrcV); SDOperand Ptr = getValue(I.getOperand(1)); DAG.setRoot(DAG.getNode(ISD::STORE, MVT::Other, DAG.getRoot(), Src, Ptr)); - return; } void SelectionDAGLowering::visitCall(CallInst &I) { -- 2.34.1