Eliminate the RegSDNode class, which 3 nodes (CopyFromReg/CopyToReg/ImplicitDef)
authorChris Lattner <sabre@nondot.org>
Tue, 16 Aug 2005 21:55:35 +0000 (21:55 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 16 Aug 2005 21:55:35 +0000 (21:55 +0000)
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
include/llvm/CodeGen/SelectionDAGNodes.h
lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
lib/CodeGen/SelectionDAG/SelectionDAG.cpp
lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp

index 8ec9bcd2ed07b2a4c413a6fc6d53f9cc127f903b..755cbfd3c5d5fe53ceff3ab963d248ba5557668a 100644 (file)
@@ -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<MVT::ValueType> ResultTys;
+    ResultTys.push_back(VT);
+    ResultTys.push_back(MVT::Other);
+    std::vector<SDOperand> 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<std::pair<unsigned, std::pair<SDOperand, SDOperand> >,
            SDNode *> BinaryOps;
 
+  std::vector<RegisterSDNode*> RegNodes;
   std::vector<CondCodeSDNode*> CondCodeNodes;
 
   std::map<std::pair<SDOperand, std::pair<SDOperand, MVT::ValueType> >,
index d1c1a3443974e862e854f5072a721b60d14b323d..4eecb0a6b7384f850e01a7e96a9c856a4bc5414f 100644 (file)
@@ -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;
   }
 };
 
index 38e0d424edeaca838a7cd3c594b802e95b781422..7bb4ce2565cffe888180e1a3185194e5aac1373e 100644 (file)
@@ -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<RegSDNode>(Node)->getReg(),
-                                  Node->getValueType(0), Tmp1);
+      Result = DAG.getCopyFromReg(Tmp1, 
+                            cast<RegisterSDNode>(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<RegSDNode>(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<RegSDNode>(Node)->getReg());
-      break;
-    case Promote:
-      Tmp2 = PromoteOp(Node->getOperand(1));
-      Result = DAG.getCopyToReg(Tmp1, Tmp2, cast<RegSDNode>(Node)->getReg());
-      break;
-    case Expand:
-      SDOperand Lo, Hi;
-      ExpandOp(Node->getOperand(1), Lo, Hi);
-      unsigned Reg = cast<RegSDNode>(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<ConstantFPSDNode>(Result) && "Didn't constant fold fp_extend?");
     break;
-  case ISD::CopyFromReg:
-    Result = DAG.getCopyFromReg(cast<RegSDNode>(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<RegSDNode>(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.
index 7a790c8df92e8218fc74a74daad55cca240afe8b..dae19b9768fd14c3772e42acc14555b5c0d05b49 100644 (file)
@@ -250,6 +250,9 @@ void SelectionDAG::RemoveNodeFromCSEMaps(SDNode *N) {
   case ISD::VALUETYPE:
     ValueTypeNodes[cast<VTSDNode>(N)->getVT()] = 0;
     break;
+  case ISD::Register:
+    RegNodes[cast<RegisterSDNode>(N)->getReg()] = 0;
+    break;
   case ISD::SRCVALUE: {
     SrcValueSDNode *SVN = cast<SrcValueSDNode>(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<RegSDNode>(this)) {
-    std::cerr << "<reg #" << C2V->getReg() << ">";
+  } else if (const RegisterSDNode *C2V = dyn_cast<RegisterSDNode>(this)) {
+    std::cerr << " #" << C2V->getReg();
   } else if (const ExternalSymbolSDNode *ES =
              dyn_cast<ExternalSymbolSDNode>(this)) {
     std::cerr << "'" << ES->getSymbol() << "'";
index 512a62deff8a9d7253c8db51b463cf3722141ae3..44553afa3c3626c12ffacf52ce6e2da09f0234b5 100644 (file)
@@ -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<RegSDNode>(Op)->getReg() != Reg) &&
+          cast<RegisterSDNode>(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
index a60acc12080ba3af458dad47b2c3107432b4b4f3..20cec1f11d8ee378940dfedcae00622fe34952c1 100644 (file)
@@ -72,8 +72,8 @@ std::string DOTGraphTraits<SelectionDAG*>::getNodeLabel(const SDNode *Node,
     if (LBB)
       Op += LBB->getName();
     //Op += " " + (const void*)BBDN->getBasicBlock();
-  } else if (const RegSDNode *C2V = dyn_cast<RegSDNode>(Node)) {
-    Op += " #" + utostr(C2V->getReg());
+  } else if (const RegisterSDNode *R = dyn_cast<RegisterSDNode>(Node)) {
+    Op += " #" + utostr(R->getReg());
   } else if (const ExternalSymbolSDNode *ES =
              dyn_cast<ExternalSymbolSDNode>(Node)) {
     Op += "'" + std::string(ES->getSymbol()) + "'";