Split ISD::LABEL into ISD::DBG_LABEL and ISD::EH_LABEL, eliminating
the need for a flavor operand, and add a new SDNode subclass,
LabelSDNode, for use with them to eliminate the need for a label id
operand.

Change instruction selection to let these label nodes through
unmodified instead of creating copies of them. Teach the MachineInstr
emitter how to emit a MachineInstr directly from an ISD label node.

This avoids the need for allocating SDNodes for the label id and
flavor value, as well as SDNodes for each of the post-isel label,
label id, and label flavor.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@52943 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 3665ee0..4548894 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -1084,28 +1084,26 @@
     case TargetLowering::Expand: {
       MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
       bool useDEBUG_LOC = TLI.isOperationLegal(ISD::DEBUG_LOC, MVT::Other);
-      bool useLABEL = TLI.isOperationLegal(ISD::LABEL, MVT::Other);
+      bool useLABEL = TLI.isOperationLegal(ISD::DBG_LABEL, MVT::Other);
       
       const DbgStopPointSDNode *DSP = cast<DbgStopPointSDNode>(Node);
       if (MMI && (useDEBUG_LOC || useLABEL)) {
         const CompileUnitDesc *CompileUnit = DSP->getCompileUnit();
         unsigned SrcFile = MMI->RecordSource(CompileUnit);
 
-        SmallVector<SDOperand, 8> Ops;
-        Ops.push_back(Tmp1);  // chain
         unsigned Line = DSP->getLine();
         unsigned Col = DSP->getColumn();
         
         if (useDEBUG_LOC) {
+          SmallVector<SDOperand, 8> Ops;
+          Ops.push_back(Tmp1);  // chain
           Ops.push_back(DAG.getConstant(Line, MVT::i32));  // line #
           Ops.push_back(DAG.getConstant(Col, MVT::i32));   // col #
           Ops.push_back(DAG.getConstant(SrcFile, MVT::i32));  // source file id
           Result = DAG.getNode(ISD::DEBUG_LOC, MVT::Other, &Ops[0], Ops.size());
         } else {
           unsigned ID = MMI->RecordSourceLine(Line, Col, SrcFile);
-          Ops.push_back(DAG.getConstant(ID, MVT::i32));
-          Ops.push_back(DAG.getConstant(0, MVT::i32)); // a debug label
-          Result = DAG.getNode(ISD::LABEL, MVT::Other, &Ops[0], Ops.size());
+          Result = DAG.getLabel(ISD::DBG_LABEL, Tmp1, ID);
         }
       } else {
         Result = Tmp1;  // chain
@@ -1163,15 +1161,14 @@
     }
     break;    
 
-  case ISD::LABEL:
-    assert(Node->getNumOperands() == 3 && "Invalid LABEL node!");
-    switch (TLI.getOperationAction(ISD::LABEL, MVT::Other)) {
+  case ISD::DBG_LABEL:
+  case ISD::EH_LABEL:
+    assert(Node->getNumOperands() == 1 && "Invalid LABEL node!");
+    switch (TLI.getOperationAction(Node->getOpcode(), MVT::Other)) {
     default: assert(0 && "This action is not supported yet!");
     case TargetLowering::Legal:
       Tmp1 = LegalizeOp(Node->getOperand(0));  // Legalize the chain.
-      Tmp2 = LegalizeOp(Node->getOperand(1));  // Legalize the label id.
-      Tmp3 = LegalizeOp(Node->getOperand(2));  // Legalize the "flavor" operand.
-      Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3);
+      Result = DAG.UpdateNodeOperands(Result, Tmp1);
       break;
     case TargetLowering::Expand:
       Result = LegalizeOp(Node->getOperand(0));
diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp
index 7194ed0..de2c1bc 100644
--- a/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp
@@ -879,10 +879,17 @@
       assert(0 && "EntryToken should have been excluded from the schedule!");
       break;
     case ISD::TokenFactor: // fall thru
-    case ISD::LABEL:
     case ISD::DECLARE:
     case ISD::SRCVALUE:
       break;
+    case ISD::DBG_LABEL:
+      BB->push_back(BuildMI(TII->get(TargetInstrInfo::DBG_LABEL))
+                      .addImm(cast<LabelSDNode>(Node)->getLabelID()));
+      break;
+    case ISD::EH_LABEL:
+      BB->push_back(BuildMI(TII->get(TargetInstrInfo::EH_LABEL))
+                      .addImm(cast<LabelSDNode>(Node)->getLabelID()));
+      break;
     case ISD::CopyToReg: {
       unsigned SrcReg;
       SDOperand SrcVal = Node->getOperand(2);
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index c364e1f..17a5fa7 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -192,19 +192,15 @@
 
 
 /// isDebugLabel - Return true if the specified node represents a debug
-/// label (i.e. ISD::LABEL or TargetInstrInfo::LABEL node and third operand
-/// is 0).
+/// label (i.e. ISD::DBG_LABEL or TargetInstrInfo::DBG_LABEL node).
 bool ISD::isDebugLabel(const SDNode *N) {
   SDOperand Zero;
-  if (N->getOpcode() == ISD::LABEL)
-    Zero = N->getOperand(2);
-  else if (N->isTargetOpcode() &&
-           N->getTargetOpcode() == TargetInstrInfo::LABEL)
-    // Chain moved to last operand.
-    Zero = N->getOperand(1);
-  else
-    return false;
-  return isa<ConstantSDNode>(Zero) && cast<ConstantSDNode>(Zero)->isNullValue();
+  if (N->getOpcode() == ISD::DBG_LABEL)
+    return true;
+  if (N->isTargetOpcode() &&
+      N->getTargetOpcode() == TargetInstrInfo::DBG_LABEL)
+    return true;
+  return false;
 }
 
 /// getSetCCSwappedOperands - Return the operation corresponding to (Y op X)
@@ -389,6 +385,10 @@
     ID.AddPointer(DSP->getCompileUnit());
     break;
   }
+  case ISD::DBG_LABEL:
+  case ISD::EH_LABEL:
+    ID.AddInteger(cast<LabelSDNode>(N)->getLabelID());
+    break;
   case ISD::SRCVALUE:
     ID.AddPointer(cast<SrcValueSDNode>(N)->getValue());
     break;
@@ -1018,6 +1018,22 @@
   return SDOperand(N, 0);
 }
 
+SDOperand SelectionDAG::getLabel(unsigned Opcode,
+                                 SDOperand Root,
+                                 unsigned LabelID) {
+  FoldingSetNodeID ID;
+  SDOperand Ops[] = { Root };
+  AddNodeIDNode(ID, Opcode, getVTList(MVT::Other), &Ops[0], 1);
+  ID.AddInteger(LabelID);
+  void *IP = 0;
+  if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
+    return SDOperand(E, 0);
+  SDNode *N = new LabelSDNode(Opcode, Root, LabelID);
+  CSEMap.InsertNode(N, IP);
+  AllNodes.push_back(N);
+  return SDOperand(N, 0);
+}
+
 SDOperand SelectionDAG::getSrcValue(const Value *V) {
   assert((!V || isa<PointerType>(V->getType())) &&
          "SrcValue is not a pointer?");
@@ -4202,6 +4218,7 @@
 void MemOperandSDNode::ANCHOR() {}
 void RegisterSDNode::ANCHOR() {}
 void DbgStopPointSDNode::ANCHOR() {}
+void LabelSDNode::ANCHOR() {}
 void ExternalSymbolSDNode::ANCHOR() {}
 void CondCodeSDNode::ANCHOR() {}
 void ARG_FLAGSSDNode::ANCHOR() {}
@@ -4521,7 +4538,8 @@
   case ISD::UNDEF:         return "undef";
   case ISD::MERGE_VALUES:  return "merge_values";
   case ISD::INLINEASM:     return "inlineasm";
-  case ISD::LABEL:         return "label";
+  case ISD::DBG_LABEL:     return "dbg_label";
+  case ISD::EH_LABEL:      return "eh_label";
   case ISD::DECLARE:       return "declare";
   case ISD::HANDLENODE:    return "handlenode";
   case ISD::FORMAL_ARGUMENTS: return "formal_arguments";
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index dc4dcc9..8751c9a 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -3179,9 +3179,7 @@
     DbgRegionStartInst &RSI = cast<DbgRegionStartInst>(I);
     if (MMI && RSI.getContext() && MMI->Verify(RSI.getContext())) {
       unsigned LabelID = MMI->RecordRegionStart(RSI.getContext());
-      DAG.setRoot(DAG.getNode(ISD::LABEL, MVT::Other, getRoot(),
-                              DAG.getConstant(LabelID, MVT::i32),
-                              DAG.getConstant(0, MVT::i32)));
+      DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getRoot(), LabelID));
     }
 
     return 0;
@@ -3191,9 +3189,7 @@
     DbgRegionEndInst &REI = cast<DbgRegionEndInst>(I);
     if (MMI && REI.getContext() && MMI->Verify(REI.getContext())) {
       unsigned LabelID = MMI->RecordRegionEnd(REI.getContext());
-      DAG.setRoot(DAG.getNode(ISD::LABEL, MVT::Other, getRoot(),
-                              DAG.getConstant(LabelID, MVT::i32),
-                              DAG.getConstant(0, MVT::i32)));
+      DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getRoot(), LabelID));
     }
 
     return 0;
@@ -3576,9 +3572,7 @@
     // Both PendingLoads and PendingExports must be flushed here;
     // this call might not return.
     (void)getRoot();
-    DAG.setRoot(DAG.getNode(ISD::LABEL, MVT::Other, getControlRoot(),
-                            DAG.getConstant(BeginLabel, MVT::i32),
-                            DAG.getConstant(1, MVT::i32)));
+    DAG.setRoot(DAG.getLabel(ISD::EH_LABEL, getControlRoot(), BeginLabel));
   }
 
   std::pair<SDOperand,SDOperand> Result =
@@ -3595,9 +3589,7 @@
     // Insert a label at the end of the invoke call to mark the try range.  This
     // can be used to detect deletion of the invoke via the MachineModuleInfo.
     EndLabel = MMI->NextLabelID();
-    DAG.setRoot(DAG.getNode(ISD::LABEL, MVT::Other, getRoot(),
-                            DAG.getConstant(EndLabel, MVT::i32),
-                            DAG.getConstant(1, MVT::i32)));
+    DAG.setRoot(DAG.getLabel(ISD::EH_LABEL, getRoot(), EndLabel));
 
     // Inform MachineModuleInfo of range.
     MMI->addInvoke(LandingPad, BeginLabel, EndLabel);
@@ -5112,9 +5104,7 @@
     // Add a label to mark the beginning of the landing pad.  Deletion of the
     // landing pad can thus be detected via the MachineModuleInfo.
     unsigned LabelID = MMI->addLandingPad(BB);
-    DAG.setRoot(DAG.getNode(ISD::LABEL, MVT::Other, DAG.getEntryNode(),
-                            DAG.getConstant(LabelID, MVT::i32),
-                            DAG.getConstant(1, MVT::i32)));
+    DAG.setRoot(DAG.getLabel(ISD::EH_LABEL, DAG.getEntryNode(), LabelID));
 
     // Mark exception register as live in.
     unsigned Reg = TLI.getExceptionAddressRegister();
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp
index 5c51cf7..c031191 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp
@@ -144,6 +144,8 @@
     Op += ":" + utostr(D->getLine());
     if (D->getColumn() != 0)
       Op += ":" + utostr(D->getColumn());
+  } else if (const LabelSDNode *L = dyn_cast<LabelSDNode>(Node)) {
+    Op += ": LabelID=" + utostr(L->getLabelID());
   } else if (const ExternalSymbolSDNode *ES =
              dyn_cast<ExternalSymbolSDNode>(Node)) {
     Op += "'" + std::string(ES->getSymbol()) + "'";