diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h b/llvm/include/llvm/CodeGen/SelectionDAG.h index 355053d7723f..f19437027075 100644 --- a/llvm/include/llvm/CodeGen/SelectionDAG.h +++ b/llvm/include/llvm/CodeGen/SelectionDAG.h @@ -178,21 +178,14 @@ public: SDOperand getNode(unsigned Opcode, std::vector &ResultTys, std::vector &Ops); - // getNode - These versions take an extra value type for extending and - // 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); - /// getLoad - Loads are not normal binary operators: their result type is not /// determined by their operands, and they produce a value AND a token chain. /// SDOperand getLoad(MVT::ValueType VT, SDOperand Chain, SDOperand Ptr, SDOperand SV); + SDOperand getExtLoad(unsigned Opcode, MVT::ValueType VT, SDOperand Chain, + SDOperand Ptr, SDOperand SV, MVT::ValueType EVT); // getSrcValue - construct a node to track a Value* through the backend SDOperand getSrcValue(const Value* I, int offset = 0); @@ -227,6 +220,7 @@ private: std::map ConstantPoolIndices; std::map BBNodes; std::vector ValueTypeNodes; + std::map ExternalSymbols; std::map > >, SDNode*> OneResultNodes; @@ -234,23 +228,6 @@ private: std::pair, std::vector > >, SDNode*> ArbitraryNodes; - - std::map ExternalSymbols; - struct EVTStruct { - unsigned Opcode; - MVT::ValueType VT, EVT; - std::vector Ops; - bool operator<(const EVTStruct &RHS) const { - if (Opcode < RHS.Opcode) return true; - if (Opcode > RHS.Opcode) return false; - if (VT < RHS.VT) return true; - if (VT > RHS.VT) return false; - if (EVT < RHS.EVT) return true; - if (EVT > RHS.EVT) return false; - return Ops < RHS.Ops; - } - }; - std::map MVTSDNodes; }; template <> struct GraphTraits : public GraphTraits { diff --git a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h index 65287661640e..9cbbfe24683b 100644 --- a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h @@ -180,11 +180,11 @@ namespace ISD { // SRCVALUE node that provides alias analysis information. LOAD, STORE, - // EXTLOAD, SEXTLOAD, ZEXTLOAD - These three operators are instances of the - // MVTSDNode. All of these load a value from memory and extend them to a - // larger value (e.g. load a byte into a word register). All three of these - // have two operands, a chain and a pointer to load from. The extra value - // type is the source type being loaded. + // EXTLOAD, SEXTLOAD, ZEXTLOAD - These three operators all load a value from + // memory and extend them to a larger value (e.g. load a byte into a word + // register). All three of these have four operands, a token chain, a + // pointer to load from, a SRCVALUE for alias analysis, and a VALUETYPE node + // indicating the type to load. // // SEXTLOAD loads the integer operand and sign extends it to a larger // integer result type. @@ -863,34 +863,6 @@ public: }; -/// MVTSDNode - This class is used for operators that require an extra -/// value-type to be kept with the node. -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, SDOperand Op2, MVT::ValueType EVT) - : SDNode(Opc, Op0, Op1, Op2), ExtraValueType(EVT) { - setValueTypes(VT1, VT2); - } -public: - - MVT::ValueType getExtraValueType() const { return ExtraValueType; } - - static bool classof(const MVTSDNode *) { return true; } - static bool classof(const SDNode *N) { - return - N->getOpcode() == ISD::EXTLOAD || - N->getOpcode() == ISD::SEXTLOAD || - N->getOpcode() == ISD::ZEXTLOAD; - } -}; - class SDNodeIterator : public forward_iterator { SDNode *Node; unsigned Operand; diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index c42c0e031a73..0fc06c0560ed 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -317,8 +317,8 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { SDOperand CPIdx = DAG.getConstantPool(CP->getConstantPoolIndex(LLVMC), TLI.getPointerTy()); if (Extend) { - Result = DAG.getNode(ISD::EXTLOAD, MVT::f64, DAG.getEntryNode(), CPIdx, - DAG.getSrcValue(NULL), MVT::f32); + Result = DAG.getExtLoad(ISD::EXTLOAD, MVT::f64, DAG.getEntryNode(), + CPIdx, DAG.getSrcValue(NULL), MVT::f32); } else { Result = DAG.getLoad(VT, DAG.getEntryNode(), CPIdx, DAG.getSrcValue(NULL)); @@ -495,13 +495,13 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the pointer. - MVT::ValueType SrcVT = cast(Node)->getExtraValueType(); + MVT::ValueType SrcVT = cast(Node->getOperand(3))->getVT(); switch (TLI.getOperationAction(Node->getOpcode(), SrcVT)) { default: assert(0 && "This action is not supported yet!"); case TargetLowering::Promote: assert(SrcVT == MVT::i1 && "Can only promote EXTLOAD from i1 -> i8!"); - Result = DAG.getNode(Node->getOpcode(), Node->getValueType(0), - Tmp1, Tmp2, Node->getOperand(2), MVT::i8); + Result = DAG.getExtLoad(Node->getOpcode(), Node->getValueType(0), + Tmp1, Tmp2, Node->getOperand(2), MVT::i8); // Since loads produce two values, make sure to remember that we legalized // both of them. AddLegalizedOperand(SDOperand(Node, 0), Result); @@ -511,8 +511,8 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { case TargetLowering::Legal: if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1)) - Result = DAG.getNode(Node->getOpcode(), Node->getValueType(0), - Tmp1, Tmp2, Node->getOperand(2), SrcVT); + Result = DAG.getExtLoad(Node->getOpcode(), Node->getValueType(0), + Tmp1, Tmp2, Node->getOperand(2), SrcVT); else Result = SDOperand(Node, 0); @@ -534,8 +534,8 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { "EXTLOAD should always be supported!"); // Turn the unsupported load into an EXTLOAD followed by an explicit // zero/sign extend inreg. - Result = DAG.getNode(ISD::EXTLOAD, Node->getValueType(0), - Tmp1, Tmp2, Node->getOperand(2), SrcVT); + Result = DAG.getExtLoad(ISD::EXTLOAD, Node->getValueType(0), + Tmp1, Tmp2, Node->getOperand(2), SrcVT); SDOperand ValRes; if (Node->getOpcode() == ISD::SEXTLOAD) ValRes = DAG.getNode(ISD::SIGN_EXTEND_INREG, Result.getValueType(), @@ -1362,8 +1362,9 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { else { assert(Node->getValueType(0) == MVT::f64 && "Unexpected conversion"); FudgeInReg = - LegalizeOp(DAG.getNode(ISD::EXTLOAD, MVT::f64, DAG.getEntryNode(), - CPIdx, DAG.getSrcValue(NULL), MVT::f32)); + LegalizeOp(DAG.getExtLoad(ISD::EXTLOAD, MVT::f64, + DAG.getEntryNode(), CPIdx, + DAG.getSrcValue(NULL), MVT::f32)); } Result = DAG.getNode(ISD::ADD, Node->getValueType(0), Tmp1, FudgeInReg); break; @@ -1451,7 +1452,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { case TargetLowering::Legal: if (Tmp1 != Node->getOperand(0)) Result = DAG.getNode(Node->getOpcode(), Node->getValueType(0), Tmp1, - ExtraVT); + DAG.getValueType(ExtraVT)); break; case TargetLowering::Expand: // If this is an integer extend and shifts are supported, do that. @@ -1482,8 +1483,9 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { Result = DAG.getNode(ISD::TRUNCSTORE, MVT::Other, DAG.getEntryNode(), Node->getOperand(0), StackSlot, DAG.getSrcValue(NULL), DAG.getValueType(ExtraVT)); - Result = DAG.getNode(ISD::EXTLOAD, Node->getValueType(0), - Result, StackSlot, DAG.getSrcValue(NULL), ExtraVT); + Result = DAG.getExtLoad(ISD::EXTLOAD, Node->getValueType(0), + Result, StackSlot, DAG.getSrcValue(NULL), + ExtraVT); } else { assert(0 && "Unknown op"); } @@ -1768,11 +1770,11 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) { Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the pointer. // FIXME: When the DAG combiner exists, change this to use EXTLOAD! if (MVT::isInteger(NVT)) - Result = DAG.getNode(ISD::ZEXTLOAD, NVT, Tmp1, Tmp2, Node->getOperand(2), - VT); + Result = DAG.getExtLoad(ISD::ZEXTLOAD, NVT, Tmp1, Tmp2, + Node->getOperand(2), VT); else - Result = DAG.getNode(ISD::EXTLOAD, NVT, Tmp1, Tmp2, Node->getOperand(2), - VT); + Result = DAG.getExtLoad(ISD::EXTLOAD, NVT, Tmp1, Tmp2, + Node->getOperand(2), VT); // Remember that we legalized the chain. AddLegalizedOperand(Op.getValue(1), Result.getValue(1)); @@ -2277,8 +2279,8 @@ ExpandIntToFP(bool isSigned, MVT::ValueType DestTy, SDOperand Source) { DAG.getSrcValue(NULL)); else { assert(DestTy == MVT::f64 && "Unexpected conversion"); - FudgeInReg = DAG.getNode(ISD::EXTLOAD, MVT::f64, DAG.getEntryNode(), - CPIdx, DAG.getSrcValue(NULL), MVT::f32); + FudgeInReg = DAG.getExtLoad(ISD::EXTLOAD, MVT::f64, DAG.getEntryNode(), + CPIdx, DAG.getSrcValue(NULL), MVT::f32); } return DAG.getNode(ISD::ADD, DestTy, SignedConv, FudgeInReg); } diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 8ae96f8d4da7..91fbf98ab5d1 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -235,18 +235,6 @@ void SelectionDAG::DeleteNodeIfDead(SDNode *N, void *NodeSet) { cast(N)->getCondition(), N->getValueType(0)))); break; - case ISD::EXTLOAD: - case ISD::SEXTLOAD: - case ISD::ZEXTLOAD: { - EVTStruct NN; - NN.Opcode = N->getOpcode(); - NN.VT = N->getValueType(0); - NN.EVT = cast(N)->getExtraValueType(); - for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) - NN.Ops.push_back(N->getOperand(i)); - MVTSDNodes.erase(NN); - break; - } default: if (N->getNumOperands() == 1) UnaryOps.erase(std::make_pair(N->getOpcode(), @@ -795,7 +783,7 @@ static bool MaskedValueIsZero(const SDOperand &Op, uint64_t Mask, TLI.getSetCCResultContents() == TargetLowering::ZeroOrOneSetCCResult; case ISD::ZEXTLOAD: - SrcBits = MVT::getSizeInBits(cast(Op)->getExtraValueType()); + SrcBits = MVT::getSizeInBits(cast(Op.getOperand(3))->getVT()); return (Mask & ((1ULL << SrcBits)-1)) == 0; // Returning only the zext bits. case ISD::ZERO_EXTEND: SrcBits = MVT::getSizeInBits(Op.getOperand(0).getValueType()); @@ -1248,7 +1236,7 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT, // If we are sign extending a sextload, return just the load. if (N1.getOpcode() == ISD::SEXTLOAD) - if (cast(N1)->getExtraValueType() <= EVT) + if (cast(N1.getOperand(3))->getVT() <= EVT) return N1; // If we are extending the result of a setcc, and we already know the @@ -1335,6 +1323,22 @@ SDOperand SelectionDAG::getLoad(MVT::ValueType VT, return SDOperand(N, 0); } + +SDOperand SelectionDAG::getExtLoad(unsigned Opcode, MVT::ValueType VT, + SDOperand Chain, SDOperand Ptr, SDOperand SV, + MVT::ValueType EVT) { + std::vector Ops; + Ops.reserve(4); + Ops.push_back(Chain); + Ops.push_back(Ptr); + Ops.push_back(SV); + Ops.push_back(getValueType(EVT)); + std::vector VTs; + VTs.reserve(2); + VTs.push_back(VT); VTs.push_back(MVT::Other); // Add token chain. + return getNode(Opcode, VTs, Ops); +} + SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT, SDOperand N1, SDOperand N2, SDOperand N3) { // Perform various simplifications. @@ -1547,11 +1551,29 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, if (ResultTys.size() == 1) return getNode(Opcode, ResultTys[0], Ops); + switch (Opcode) { + case ISD::EXTLOAD: + case ISD::SEXTLOAD: + case ISD::ZEXTLOAD: { + MVT::ValueType EVT = cast(Ops[3])->getVT(); + assert(Ops.size() == 4 && ResultTys.size() == 2 && "Bad *EXTLOAD!"); + // If they are asking for an extending load from/to the same thing, return a + // normal load. + if (ResultTys[0] == EVT) + return getLoad(ResultTys[0], Ops[0], Ops[1], Ops[2]); + assert(EVT < ResultTys[0] && + "Should only be an extending load, not truncating!"); + assert((Opcode == ISD::EXTLOAD || MVT::isInteger(ResultTys[0])) && + "Cannot sign/zero extend a FP load!"); + assert(MVT::isInteger(ResultTys[0]) == MVT::isInteger(EVT) && + "Cannot convert from FP to Int or Int -> FP!"); + break; + } + // FIXME: figure out how to safely handle things like // int foo(int x) { return 1 << (x & 255); } // int bar() { return foo(256); } #if 0 - switch (Opcode) { case ISD::SRA_PARTS: case ISD::SRL_PARTS: case ISD::SHL_PARTS: @@ -1567,8 +1589,8 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, return getNode(Opcode, VT, N1, N2, N3.getOperand(0)); } break; - } #endif + } // Memoize the node. SDNode *&N = ArbitraryNodes[std::make_pair(Opcode, std::make_pair(ResultTys, @@ -1580,56 +1602,6 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, return SDOperand(N, 0); } - -SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,SDOperand N1, - MVT::ValueType EVT) { - 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, SDOperand N3, MVT::ValueType EVT) { - switch (Opcode) { - default: assert(0 && "Bad opcode for this accessor!"); - case ISD::EXTLOAD: - case ISD::SEXTLOAD: - case ISD::ZEXTLOAD: - // If they are asking for an extending load from/to the same thing, return a - // normal load. - if (VT == EVT) - return getLoad(VT, N1, N2, N3); - assert(EVT < VT && "Should only be an extending load, not truncating!"); - assert((Opcode == ISD::EXTLOAD || MVT::isInteger(VT)) && - "Cannot sign/zero extend a FP load!"); - assert(MVT::isInteger(VT) == MVT::isInteger(EVT) && - "Cannot convert from FP to Int or Int -> FP!"); - break; - } - - EVTStruct NN; - NN.Opcode = Opcode; - NN.VT = VT; - NN.EVT = EVT; - NN.Ops.push_back(N1); - NN.Ops.push_back(N2); - NN.Ops.push_back(N3); - - SDNode *&N = MVTSDNodes[NN]; - if (N) return SDOperand(N, 0); - N = new MVTSDNode(Opcode, VT, MVT::Other, N1, N2, N3, EVT); - AllNodes.push_back(N); - return SDOperand(N, 0); -} - /// hasNUsesOfValue - Return true if there are exactly NUSES uses of the /// indicated value. This method ignores uses of other values defined by this /// operation. @@ -1836,8 +1808,6 @@ void SDNode::dump() const { } else if (const ExternalSymbolSDNode *ES = dyn_cast(this)) { std::cerr << "'" << ES->getSymbol() << "'"; - } else if (const MVTSDNode *M = dyn_cast(this)) { - std::cerr << " - Ty = " << MVT::getValueTypeString(M->getExtraValueType()); } else if (const SrcValueSDNode *M = dyn_cast(this)) { if (M->getValue()) std::cerr << "<" << M->getValue() << ":" << M->getOffset() << ">"; diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp index 8d8e1fd3662a..d4c1dcd3b8a3 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp @@ -88,8 +88,6 @@ std::string DOTGraphTraits::getNodeLabel(const SDNode *Node, } else if (const ExternalSymbolSDNode *ES = dyn_cast(Node)) { Op += "'" + std::string(ES->getSymbol()) + "'"; - } else if (const MVTSDNode *M = dyn_cast(Node)) { - Op = Op + " ty=" + MVT::getValueTypeString(M->getExtraValueType()); } else if (const SrcValueSDNode *M = dyn_cast(Node)) { if (M->getValue()) Op += "<" + M->getValue()->getName() + ":" + itostr(M->getOffset()) + ">";