From d5d0f9bd20d9df07d6b4d41b7e8ed6d33b6a649d Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 16 Aug 2005 21:55:35 +0000 Subject: [PATCH] Eliminate the RegSDNode class, which 3 nodes (CopyFromReg/CopyToReg/ImplicitDef) used to tack a register number onto the node. Instead of doing this, make a new node, RegisterSDNode, which is a leaf containing a register number. These three operations just become normal DAG nodes now, instead of requiring special handling. Note that with this change, it is no longer correct to make illegal CopyFromReg/CopyToReg nodes. The legalizer will not touch them, and this is bad, so don't do it. :) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22806 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/SelectionDAG.h | 34 +++++----- include/llvm/CodeGen/SelectionDAGNodes.h | 30 ++++----- lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 63 +++++-------------- lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 22 ++++++- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 47 ++++++++++++-- .../SelectionDAG/SelectionDAGPrinter.cpp | 4 +- 6 files changed, 108 insertions(+), 92 deletions(-) diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index 8ec9bcd2ed0..755cbfd3c5d 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -101,30 +101,25 @@ public: SDOperand getBasicBlock(MachineBasicBlock *MBB); SDOperand getExternalSymbol(const char *Sym, MVT::ValueType VT); SDOperand getValueType(MVT::ValueType); + SDOperand getRegister(unsigned Reg, MVT::ValueType VT); - SDOperand getCopyToReg(SDOperand Chain, SDOperand N, unsigned Reg) { - // Note: these are auto-CSE'd because the caller doesn't make requests that - // could cause duplicates to occur. - SDNode *NN = new RegSDNode(ISD::CopyToReg, Chain, N, Reg); - NN->setValueTypes(MVT::Other); - AllNodes.push_back(NN); - return SDOperand(NN, 0); + SDOperand getCopyToReg(SDOperand Chain, unsigned Reg, SDOperand N) { + return getNode(ISD::CopyToReg, MVT::Other, Chain, + getRegister(Reg, N.getValueType()), N); } - SDOperand getCopyFromReg(unsigned Reg, MVT::ValueType VT, SDOperand Chain) { - // Note: These nodes are auto-CSE'd by the caller of this method. - SDNode *NN = new RegSDNode(ISD::CopyFromReg, Chain, Reg); - NN->setValueTypes(VT, MVT::Other); - AllNodes.push_back(NN); - return SDOperand(NN, 0); + SDOperand getCopyFromReg(SDOperand Chain, unsigned Reg, MVT::ValueType VT) { + std::vector ResultTys; + ResultTys.push_back(VT); + ResultTys.push_back(MVT::Other); + std::vector Ops; + Ops.push_back(Chain); + Ops.push_back(getRegister(Reg, VT)); + return getNode(ISD::CopyFromReg, ResultTys, Ops); } - SDOperand getImplicitDef(SDOperand Chain, unsigned Reg) { - // Note: These nodes are auto-CSE'd by the caller of this method. - SDNode *NN = new RegSDNode(ISD::ImplicitDef, Chain, Reg); - NN->setValueTypes(MVT::Other); - AllNodes.push_back(NN); - return SDOperand(NN, 0); + SDOperand getImplicitDef(SDOperand Chain, unsigned Reg, MVT::ValueType VT) { + return getNode(ISD::ImplicitDef, MVT::Other, Chain, getRegister(Reg, VT)); } /// getCall - Note that this destroys the vector of RetVals passed in. @@ -255,6 +250,7 @@ private: std::map >, SDNode *> BinaryOps; + std::vector RegNodes; std::vector CondCodeNodes; std::map >, diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index d1c1a344397..4eecb0a6b73 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -55,12 +55,10 @@ namespace ISD { // Various leaf nodes. Constant, ConstantFP, GlobalAddress, FrameIndex, ConstantPool, - BasicBlock, ExternalSymbol, VALUETYPE, CONDCODE, + BasicBlock, ExternalSymbol, VALUETYPE, CONDCODE, Register, - // CopyToReg - This node has chain and child nodes, and an associated - // register number. The instruction selector must guarantee that the value - // of the value node is available in the register stored in the RegSDNode - // object. + // CopyToReg - This node has three operands: a chain, a register number to + // set to this value, and a value. CopyToReg, // CopyFromReg - This node indicates that the input value is a virtual or @@ -69,10 +67,9 @@ namespace ISD { CopyFromReg, // ImplicitDef - This node indicates that the specified register is - // implicitly defined by some operation (e.g. its a live-in argument). This - // register is indicated in the RegSDNode object. The only operand to this - // is the token chain coming in, the only result is the token chain going - // out. + // implicitly defined by some operation (e.g. its a live-in argument). The + // two operands to this are the token chain coming in and the register. + // The only result is the token chain going out. ImplicitDef, // UNDEF - An undefined node @@ -830,24 +827,19 @@ public: }; -class RegSDNode : public SDNode { +class RegisterSDNode : public SDNode { unsigned Reg; protected: friend class SelectionDAG; - RegSDNode(unsigned Opc, SDOperand Chain, SDOperand Src, unsigned reg) - : SDNode(Opc, Chain, Src), Reg(reg) { - } - RegSDNode(unsigned Opc, SDOperand Chain, unsigned reg) - : SDNode(Opc, Chain), Reg(reg) {} + RegisterSDNode(unsigned reg, MVT::ValueType VT) + : SDNode(ISD::Register, VT), Reg(reg) {} public: unsigned getReg() const { return Reg; } - static bool classof(const RegSDNode *) { return true; } + static bool classof(const RegisterSDNode *) { return true; } static bool classof(const SDNode *N) { - return N->getOpcode() == ISD::CopyToReg || - N->getOpcode() == ISD::CopyFromReg || - N->getOpcode() == ISD::ImplicitDef; + return N->getOpcode() == ISD::Register; } }; diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 38e0d424ede..7bb4ce2565c 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -405,8 +405,9 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { case ISD::CopyFromReg: Tmp1 = LegalizeOp(Node->getOperand(0)); if (Tmp1 != Node->getOperand(0)) - Result = DAG.getCopyFromReg(cast(Node)->getReg(), - Node->getValueType(0), Tmp1); + Result = DAG.getCopyFromReg(Tmp1, + cast(Node->getOperand(1))->getReg(), + Node->getValueType(0)); else Result = Op.getValue(0); @@ -418,7 +419,8 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { case ISD::ImplicitDef: Tmp1 = LegalizeOp(Node->getOperand(0)); if (Tmp1 != Node->getOperand(0)) - Result = DAG.getImplicitDef(Tmp1, cast(Node)->getReg()); + Result = DAG.getNode(ISD::ImplicitDef, MVT::Other, + Tmp1, Node->getOperand(1)); break; case ISD::UNDEF: { MVT::ValueType VT = Op.getValueType(); @@ -844,29 +846,13 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { case ISD::CopyToReg: Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. - switch (getTypeAction(Node->getOperand(1).getValueType())) { - case Legal: - // Legalize the incoming value (must be legal). - Tmp2 = LegalizeOp(Node->getOperand(1)); - if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1)) - Result = DAG.getCopyToReg(Tmp1, Tmp2, cast(Node)->getReg()); - break; - case Promote: - Tmp2 = PromoteOp(Node->getOperand(1)); - Result = DAG.getCopyToReg(Tmp1, Tmp2, cast(Node)->getReg()); - break; - case Expand: - SDOperand Lo, Hi; - ExpandOp(Node->getOperand(1), Lo, Hi); - unsigned Reg = cast(Node)->getReg(); - Lo = DAG.getCopyToReg(Tmp1, Lo, Reg); - Hi = DAG.getCopyToReg(Tmp1, Hi, Reg+1); - // Note that the copytoreg nodes are independent of each other. - Result = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi); - assert(isTypeLegal(Result.getValueType()) && - "Cannot expand multiple times yet (i64 -> i16)"); - break; - } + assert(getTypeAction(Node->getOperand(2).getValueType()) == Legal && + "Register type must be legal!"); + // Legalize the incoming value (must be legal). + Tmp2 = LegalizeOp(Node->getOperand(2)); + if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(2)) + Result = DAG.getNode(ISD::CopyToReg, MVT::Other, Tmp1, + Node->getOperand(1), Tmp2); break; case ISD::RET: @@ -1913,6 +1899,8 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) { NeedsAnotherIteration = true; switch (Node->getOpcode()) { + case ISD::CopyFromReg: + assert(0 && "CopyFromReg must be legal!"); default: std::cerr << "NODE: "; Node->dump(); std::cerr << "\n"; assert(0 && "Do not know how to promote this operator!"); @@ -1928,12 +1916,6 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) { Result = DAG.getNode(ISD::FP_EXTEND, NVT, Op); assert(isa(Result) && "Didn't constant fold fp_extend?"); break; - case ISD::CopyFromReg: - Result = DAG.getCopyFromReg(cast(Node)->getReg(), NVT, - Node->getOperand(0)); - // Remember that we legalized the chain. - AddLegalizedOperand(Op.getValue(1), Result.getValue(1)); - break; case ISD::SETCC: assert(getTypeAction(TLI.getSetCCResultTy()) == Legal && @@ -2770,7 +2752,9 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){ NeedsAnotherIteration = true; switch (Node->getOpcode()) { - default: + case ISD::CopyFromReg: + assert(0 && "CopyFromReg must be legal!"); + default: std::cerr << "NODE: "; Node->dump(); std::cerr << "\n"; assert(0 && "Do not know how to expand this operator!"); abort(); @@ -2785,19 +2769,6 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){ break; } - case ISD::CopyFromReg: { - unsigned Reg = cast(Node)->getReg(); - // Aggregate register values are always in consequtive pairs. - Lo = DAG.getCopyFromReg(Reg, NVT, Node->getOperand(0)); - Hi = DAG.getCopyFromReg(Reg+1, NVT, Lo.getValue(1)); - - // Remember that we legalized the chain. - AddLegalizedOperand(Op.getValue(1), Hi.getValue(1)); - - assert(isTypeLegal(NVT) && "Cannot expand this multiple times yet!"); - break; - } - case ISD::BUILD_PAIR: // Legalize both operands. FIXME: in the future we should handle the case // where the two elements are not legal. diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 7a790c8df92..dae19b9768f 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -250,6 +250,9 @@ void SelectionDAG::RemoveNodeFromCSEMaps(SDNode *N) { case ISD::VALUETYPE: ValueTypeNodes[cast(N)->getVT()] = 0; break; + case ISD::Register: + RegNodes[cast(N)->getReg()] = 0; + break; case ISD::SRCVALUE: { SrcValueSDNode *SVN = cast(N); ValueNodes.erase(std::make_pair(SVN->getValue(), SVN->getOffset())); @@ -398,6 +401,20 @@ SDOperand SelectionDAG::getCondCode(ISD::CondCode Cond) { return SDOperand(CondCodeNodes[Cond], 0); } +SDOperand SelectionDAG::getRegister(unsigned Reg, MVT::ValueType VT) { + if (Reg >= RegNodes.size()) + RegNodes.resize(Reg+1); + RegisterSDNode *&Result = RegNodes[Reg]; + if (Result) { + assert(Result->getValueType(0) == VT && + "Inconsistent value types for machine registers"); + } else { + Result = new RegisterSDNode(Reg, VT); + AllNodes.push_back(Result); + } + return SDOperand(Result, 0); +} + SDOperand SelectionDAG::SimplifySetCC(MVT::ValueType VT, SDOperand N1, SDOperand N2, ISD::CondCode Cond) { // These setcc operations always fold. @@ -1779,6 +1796,7 @@ const char *SDNode::getOperationName(const SelectionDAG *G) const { case ISD::GlobalAddress: return "GlobalAddress"; case ISD::FrameIndex: return "FrameIndex"; case ISD::BasicBlock: return "BasicBlock"; + case ISD::Register: return "Register"; case ISD::ExternalSymbol: return "ExternalSymbol"; case ISD::ConstantPool: return "ConstantPoolIndex"; case ISD::CopyToReg: return "CopyToReg"; @@ -1939,8 +1957,8 @@ void SDNode::dump(const SelectionDAG *G) const { if (LBB) std::cerr << LBB->getName() << " "; std::cerr << (const void*)BBDN->getBasicBlock() << ">"; - } else if (const RegSDNode *C2V = dyn_cast(this)) { - std::cerr << "getReg() << ">"; + } else if (const RegisterSDNode *C2V = dyn_cast(this)) { + std::cerr << " #" << C2V->getReg(); } else if (const ExternalSymbolSDNode *ES = dyn_cast(this)) { std::cerr << "'" << ES->getSymbol() << "'"; diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 512a62deff8..44553afa3c3 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -296,7 +296,27 @@ public: FuncInfo.ValueMap.find(V); assert(VMI != FuncInfo.ValueMap.end() && "Value not in map!"); - return N = DAG.getCopyFromReg(VMI->second, VT, DAG.getEntryNode()); + unsigned InReg = VMI->second; + + // If this type is not legal, make it so now. + MVT::ValueType DestVT = TLI.getTypeToTransformTo(VT); + + N = DAG.getCopyFromReg(DAG.getEntryNode(), InReg, DestVT); + if (DestVT < VT) { + // Source must be expanded. This input value is actually coming from the + // register pair VMI->second and VMI->second+1. + N = DAG.getNode(ISD::BUILD_PAIR, VT, N, + DAG.getCopyFromReg(DAG.getEntryNode(), InReg+1, DestVT)); + } else { + if (DestVT > VT) { // Promotion case + if (MVT::isFloatingPoint(VT)) + N = DAG.getNode(ISD::FP_ROUND, VT, N); + else + N = DAG.getNode(ISD::TRUNCATE, VT, N); + } + } + + return N; } const SDOperand &setValue(const Value *V, SDOperand NewN) { @@ -957,12 +977,31 @@ bool SelectionDAGISel::runOnFunction(Function &Fn) { SDOperand SelectionDAGISel:: CopyValueToVirtualRegister(SelectionDAGLowering &SDL, Value *V, unsigned Reg) { - SelectionDAG &DAG = SDL.DAG; SDOperand Op = SDL.getValue(V); assert((Op.getOpcode() != ISD::CopyFromReg || - cast(Op)->getReg() != Reg) && + cast(Op.getOperand(1))->getReg() != Reg) && "Copy from a reg to the same reg!"); - return DAG.getCopyToReg(SDL.getRoot(), Op, Reg); + + // If this type is not legal, we must make sure to not create an invalid + // register use. + MVT::ValueType SrcVT = Op.getValueType(); + MVT::ValueType DestVT = TLI.getTypeToTransformTo(SrcVT); + SelectionDAG &DAG = SDL.DAG; + if (SrcVT == DestVT) { + return DAG.getCopyToReg(SDL.getRoot(), Reg, Op); + } else if (SrcVT < DestVT) { + // The src value is promoted to the register. + Op = DAG.getNode(ISD::ZERO_EXTEND, DestVT, Op); + return DAG.getCopyToReg(SDL.getRoot(), Reg, Op); + } else { + // The src value is expanded into multiple registers. + SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, DestVT, + Op, DAG.getConstant(0, MVT::i32)); + SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, DestVT, + Op, DAG.getConstant(1, MVT::i32)); + Op = DAG.getCopyToReg(SDL.getRoot(), Reg, Lo); + return DAG.getCopyToReg(Op, Reg+1, Hi); + } } /// IsOnlyUsedInOneBasicBlock - If the specified argument is only used in a diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp index a60acc12080..20cec1f11d8 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp @@ -72,8 +72,8 @@ std::string DOTGraphTraits::getNodeLabel(const SDNode *Node, if (LBB) Op += LBB->getName(); //Op += " " + (const void*)BBDN->getBasicBlock(); - } else if (const RegSDNode *C2V = dyn_cast(Node)) { - Op += " #" + utostr(C2V->getReg()); + } else if (const RegisterSDNode *R = dyn_cast(Node)) { + Op += " #" + utostr(R->getReg()); } else if (const ExternalSymbolSDNode *ES = dyn_cast(Node)) { Op += "'" + std::string(ES->getSymbol()) + "'"; -- 2.34.1