[llvm] r331842 - [DebugInfo] Convert intrinsic llvm.dbg.label to MachineInstr.

Shiva Chen via llvm-commits llvm-commits at lists.llvm.org
Tue May 8 19:41:08 PDT 2018


Author: shiva
Date: Tue May  8 19:41:08 2018
New Revision: 331842

URL: http://llvm.org/viewvc/llvm-project?rev=331842&view=rev
Log:
[DebugInfo] Convert intrinsic llvm.dbg.label to MachineInstr.

In order to convert LLVM IR to MachineInstr, we need a new TargetOpcode,
DBG_LABEL, to ‘lower’ intrinsic llvm.dbg.label. The patch
creates this new TargetOpcode and convert intrinsic llvm.dbg.label to
MachineInstr through SelectionDAG.

In SelectionDAG, debug information is stored in SDDbgInfo. We create a
new data member of SDDbgInfo for labels and use the new data member,
SDDbgLabel, to create DBG_LABEL MachineInstr.

The new DBG_LABEL MachineInstr uses label metadata from LLVM IR as its
parameter. So, the backend could get metadata information of labels from
DBG_LABEL MachineInstr.

Differential Revision: https://reviews.llvm.org/D45341

Patch by Hsiangkai Wang.

Added:
    llvm/trunk/test/DebugInfo/Generic/debug-label-mi.ll
    llvm/trunk/test/DebugInfo/Generic/debug-label-opt.ll
Modified:
    llvm/trunk/include/llvm/CodeGen/MachineInstr.h
    llvm/trunk/include/llvm/CodeGen/SelectionDAG.h
    llvm/trunk/include/llvm/Support/TargetOpcodes.def
    llvm/trunk/include/llvm/Target/Target.td
    llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
    llvm/trunk/lib/CodeGen/MachineInstr.cpp
    llvm/trunk/lib/CodeGen/PatchableFunction.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/InstrEmitter.h
    llvm/trunk/lib/CodeGen/SelectionDAG/SDNodeDbgValue.h
    llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Modified: llvm/trunk/include/llvm/CodeGen/MachineInstr.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineInstr.h?rev=331842&r1=331841&r2=331842&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/MachineInstr.h (original)
+++ llvm/trunk/include/llvm/CodeGen/MachineInstr.h Tue May  8 19:41:08 2018
@@ -292,6 +292,10 @@ public:
   /// this DBG_VALUE instruction.
   const DIExpression *getDebugExpression() const;
 
+  /// Return the debug label referenced by
+  /// this DBG_LABEL instruction.
+  const DILabel *getDebugLabel() const;
+
   /// Emit an error referring to the source location of this instruction.
   /// This should only be used for inline assembly that is somehow
   /// impossible to compile. Other errors should have been handled much
@@ -831,6 +835,8 @@ public:
   bool isPosition() const { return isLabel() || isCFIInstruction(); }
 
   bool isDebugValue() const { return getOpcode() == TargetOpcode::DBG_VALUE; }
+  bool isDebugLabel() const { return getOpcode() == TargetOpcode::DBG_LABEL; }
+  bool isDebugInstr() const { return isDebugValue() || isDebugLabel(); }
 
   /// A DBG_VALUE is indirect iff the first operand is a register and
   /// the second operand is an immediate.
@@ -907,6 +913,7 @@ public:
     case TargetOpcode::EH_LABEL:
     case TargetOpcode::GC_LABEL:
     case TargetOpcode::DBG_VALUE:
+    case TargetOpcode::DBG_LABEL:
     case TargetOpcode::LIFETIME_START:
     case TargetOpcode::LIFETIME_END:
       return true;

Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAG.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAG.h?rev=331842&r1=331841&r2=331842&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/SelectionDAG.h (original)
+++ llvm/trunk/include/llvm/CodeGen/SelectionDAG.h Tue May  8 19:41:08 2018
@@ -73,6 +73,7 @@ class MachineConstantPoolValue;
 class MCSymbol;
 class OptimizationRemarkEmitter;
 class SDDbgValue;
+class SDDbgLabel;
 class SelectionDAG;
 class SelectionDAGTargetInfo;
 class TargetLibraryInfo;
@@ -148,6 +149,7 @@ class SDDbgInfo {
   BumpPtrAllocator Alloc;
   SmallVector<SDDbgValue*, 32> DbgValues;
   SmallVector<SDDbgValue*, 32> ByvalParmDbgValues;
+  SmallVector<SDDbgLabel*, 4> DbgLabels;
   using DbgValMapType = DenseMap<const SDNode *, SmallVector<SDDbgValue *, 2>>;
   DbgValMapType DbgValMap;
 
@@ -164,6 +166,10 @@ public:
       DbgValMap[Node].push_back(V);
   }
 
+  void add(SDDbgLabel *L) {
+    DbgLabels.push_back(L);
+  }
+
   /// Invalidate all DbgValues attached to the node and remove
   /// it from the Node-to-DbgValues map.
   void erase(const SDNode *Node);
@@ -172,13 +178,14 @@ public:
     DbgValMap.clear();
     DbgValues.clear();
     ByvalParmDbgValues.clear();
+    DbgLabels.clear();
     Alloc.Reset();
   }
 
   BumpPtrAllocator &getAlloc() { return Alloc; }
 
   bool empty() const {
-    return DbgValues.empty() && ByvalParmDbgValues.empty();
+    return DbgValues.empty() && ByvalParmDbgValues.empty() && DbgLabels.empty();
   }
 
   ArrayRef<SDDbgValue*> getSDDbgValues(const SDNode *Node) {
@@ -189,11 +196,14 @@ public:
   }
 
   using DbgIterator = SmallVectorImpl<SDDbgValue*>::iterator;
+  using DbgLabelIterator = SmallVectorImpl<SDDbgLabel*>::iterator;
 
   DbgIterator DbgBegin() { return DbgValues.begin(); }
   DbgIterator DbgEnd()   { return DbgValues.end(); }
   DbgIterator ByvalParmDbgBegin() { return ByvalParmDbgValues.begin(); }
   DbgIterator ByvalParmDbgEnd()   { return ByvalParmDbgValues.end(); }
+  DbgLabelIterator DbgLabelBegin() { return DbgLabels.begin(); }
+  DbgLabelIterator DbgLabelEnd()   { return DbgLabels.end(); }
 };
 
 void checkForCycles(const SelectionDAG *DAG, bool force = false);
@@ -255,7 +265,7 @@ class SelectionDAG {
   /// Pool allocation for misc. objects that are created once per SelectionDAG.
   BumpPtrAllocator Allocator;
 
-  /// Tracks dbg_value information through SDISel.
+  /// Tracks dbg_value and dbg_label information through SDISel.
   SDDbgInfo *DbgInfo;
 
   uint16_t NextPersistentId = 0;
@@ -1247,6 +1257,9 @@ public:
                               unsigned VReg, bool IsIndirect,
                               const DebugLoc &DL, unsigned O);
 
+  /// Creates a SDDbgLabel node.
+  SDDbgLabel *getDbgLabel(DILabel *Label, const DebugLoc &DL, unsigned O);
+
   /// Transfer debug values from one node to another, while optionally
   /// generating fragment expressions for split-up values. If \p InvalidateDbg
   /// is set, debug values are invalidated after they are transferred.
@@ -1328,6 +1341,9 @@ public:
   /// value is produced by SD.
   void AddDbgValue(SDDbgValue *DB, SDNode *SD, bool isParameter);
 
+  /// Add a dbg_label SDNode.
+  void AddDbgLabel(SDDbgLabel *DB);
+
   /// Get the debug values which reference the given SDNode.
   ArrayRef<SDDbgValue*> GetDbgValues(const SDNode* SD) {
     return DbgInfo->getSDDbgValues(SD);
@@ -1349,6 +1365,13 @@ public:
     return DbgInfo->ByvalParmDbgEnd();
   }
 
+  SDDbgInfo::DbgLabelIterator DbgLabelBegin() {
+    return DbgInfo->DbgLabelBegin();
+  }
+  SDDbgInfo::DbgLabelIterator DbgLabelEnd() {
+    return DbgInfo->DbgLabelEnd();
+  }
+
   /// To be invoked on an SDNode that is slated to be erased. This
   /// function mirrors \c llvm::salvageDebugInfo.
   void salvageDebugInfo(SDNode &N);

Modified: llvm/trunk/include/llvm/Support/TargetOpcodes.def
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/TargetOpcodes.def?rev=331842&r1=331841&r2=331842&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/TargetOpcodes.def (original)
+++ llvm/trunk/include/llvm/Support/TargetOpcodes.def Tue May  8 19:41:08 2018
@@ -77,6 +77,9 @@ HANDLE_TARGET_OPCODE(SUBREG_TO_REG)
 /// DBG_VALUE - a mapping of the llvm.dbg.value intrinsic
 HANDLE_TARGET_OPCODE(DBG_VALUE)
 
+/// DBG_LABEL - a mapping of the llvm.dbg.label intrinsic
+HANDLE_TARGET_OPCODE(DBG_LABEL)
+
 /// REG_SEQUENCE - This variadic instruction is used to form a register that
 /// represents a consecutive sequence of sub-registers. It's used as a
 /// register coalescing / allocation aid and must be eliminated before code

Modified: llvm/trunk/include/llvm/Target/Target.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/Target.td?rev=331842&r1=331841&r2=331842&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/Target.td (original)
+++ llvm/trunk/include/llvm/Target/Target.td Tue May  8 19:41:08 2018
@@ -997,6 +997,12 @@ def DBG_VALUE : StandardPseudoInstructio
   let AsmString = "DBG_VALUE";
   let hasSideEffects = 0;
 }
+def DBG_LABEL : StandardPseudoInstruction {
+  let OutOperandList = (outs);
+  let InOperandList = (ins unknown:$label);
+  let AsmString = "DBG_LABEL";
+  let hasSideEffects = 0;
+}
 def REG_SEQUENCE : StandardPseudoInstruction {
   let OutOperandList = (outs unknown:$dst);
   let InOperandList = (ins unknown:$supersrc, variable_ops);

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=331842&r1=331841&r2=331842&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Tue May  8 19:41:08 2018
@@ -911,6 +911,30 @@ static bool emitDebugValueComment(const
   return true;
 }
 
+/// This method handles the target-independent form of DBG_LABEL, returning
+/// true if it was able to do so.  A false return means the target will need
+/// to handle MI in EmitInstruction.
+static bool emitDebugLabelComment(const MachineInstr *MI, AsmPrinter &AP) {
+  if (MI->getNumOperands() != 1)
+    return false;
+
+  SmallString<128> Str;
+  raw_svector_ostream OS(Str);
+  OS << "DEBUG_LABEL: ";
+
+  const DILabel *V = MI->getDebugLabel();
+  if (auto *SP = dyn_cast<DISubprogram>(V->getScope())) {
+    StringRef Name = SP->getName();
+    if (!Name.empty())
+      OS << Name << ":";
+  }
+  OS << V->getName();
+
+  // NOTE: Want this comment at start of line, don't emit with AddComment.
+  AP.OutStreamer->emitRawComment(OS.str());
+  return true;
+}
+
 AsmPrinter::CFIMoveType AsmPrinter::needsCFIMoves() const {
   if (MAI->getExceptionHandlingType() == ExceptionHandling::DwarfCFI &&
       MF->getFunction().needsUnwindTableEntry())
@@ -1074,6 +1098,12 @@ void AsmPrinter::EmitFunctionBody() {
             EmitInstruction(&MI);
         }
         break;
+      case TargetOpcode::DBG_LABEL:
+        if (isVerbose()) {
+          if (!emitDebugLabelComment(&MI, *this))
+            EmitInstruction(&MI);
+        }
+        break;
       case TargetOpcode::IMPLICIT_DEF:
         if (isVerbose()) emitImplicitDef(&MI);
         break;

Modified: llvm/trunk/lib/CodeGen/MachineInstr.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineInstr.cpp?rev=331842&r1=331841&r2=331842&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineInstr.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineInstr.cpp Tue May  8 19:41:08 2018
@@ -613,6 +613,11 @@ int MachineInstr::findInlineAsmFlagIdx(u
   return -1;
 }
 
+const DILabel *MachineInstr::getDebugLabel() const {
+  assert(isDebugLabel() && "not a DBG_LABEL");
+  return cast<DILabel>(getOperand(0).getMetadata());
+}
+
 const DILocalVariable *MachineInstr::getDebugVariable() const {
   assert(isDebugValue() && "not a DBG_VALUE");
   return cast<DILocalVariable>(getOperand(2).getMetadata());
@@ -1380,6 +1385,17 @@ void MachineInstr::print(raw_ostream &OS
       else {
         LLT TypeToPrint = MRI ? getTypeToPrint(i, PrintedTypes, *MRI) : LLT{};
         unsigned TiedOperandIdx = getTiedOperandIdx(i);
+        MO.print(OS, MST, TypeToPrint, /*PrintDef=*/true, IsStandalone,
+                 ShouldPrintRegisterTies, TiedOperandIdx, TRI, IntrinsicInfo);
+      }
+    } else if (isDebugLabel() && MO.isMetadata()) {
+      // Pretty print DBG_LABEL instructions.
+      auto *DIL = dyn_cast<DILabel>(MO.getMetadata());
+      if (DIL && !DIL->getName().empty())
+        OS << "\"" << DIL->getName() << '\"';
+      else {
+        LLT TypeToPrint = MRI ? getTypeToPrint(i, PrintedTypes, *MRI) : LLT{};
+        unsigned TiedOperandIdx = getTiedOperandIdx(i);
         MO.print(OS, MST, TypeToPrint, /*PrintDef=*/true, IsStandalone,
                  ShouldPrintRegisterTies, TiedOperandIdx, TRI, IntrinsicInfo);
       }

Modified: llvm/trunk/lib/CodeGen/PatchableFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PatchableFunction.cpp?rev=331842&r1=331841&r2=331842&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/PatchableFunction.cpp (original)
+++ llvm/trunk/lib/CodeGen/PatchableFunction.cpp Tue May  8 19:41:08 2018
@@ -49,6 +49,7 @@ static bool doesNotGeneratecode(const Ma
   case TargetOpcode::EH_LABEL:
   case TargetOpcode::GC_LABEL:
   case TargetOpcode::DBG_VALUE:
+  case TargetOpcode::DBG_LABEL:
     return true;
   }
 }

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/InstrEmitter.cpp?rev=331842&r1=331841&r2=331842&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/InstrEmitter.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/InstrEmitter.cpp Tue May  8 19:41:08 2018
@@ -753,6 +753,20 @@ InstrEmitter::EmitDbgValue(SDDbgValue *S
   return &*MIB;
 }
 
+MachineInstr *
+InstrEmitter::EmitDbgLabel(SDDbgLabel *SD) {
+  MDNode *Label = SD->getLabel();
+  DebugLoc DL = SD->getDebugLoc();
+  assert(cast<DILabel>(Label)->isValidLocationForIntrinsic(DL) &&
+         "Expected inlined-at fields to agree");
+
+  const MCInstrDesc &II = TII->get(TargetOpcode::DBG_LABEL);
+  MachineInstrBuilder MIB = BuildMI(*MF, DL, II);
+  MIB.addMetadata(Label);
+
+  return &*MIB;
+}
+
 /// EmitMachineNode - Generate machine code for a target-specific node and
 /// needed dependencies.
 ///

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/InstrEmitter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/InstrEmitter.h?rev=331842&r1=331841&r2=331842&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/InstrEmitter.h (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/InstrEmitter.h Tue May  8 19:41:08 2018
@@ -113,6 +113,9 @@ public:
   MachineInstr *EmitDbgValue(SDDbgValue *SD,
                              DenseMap<SDValue, unsigned> &VRBaseMap);
 
+  /// Generate machine instruction for a dbg_label node.
+  MachineInstr *EmitDbgLabel(SDDbgLabel *SD);
+
   /// EmitNode - Generate machine code for a node and needed dependencies.
   ///
   void EmitNode(SDNode *Node, bool IsClone, bool IsCloned,

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SDNodeDbgValue.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SDNodeDbgValue.h?rev=331842&r1=331841&r2=331842&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SDNodeDbgValue.h (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SDNodeDbgValue.h Tue May  8 19:41:08 2018
@@ -128,6 +128,28 @@ public:
   bool isInvalidated() const { return Invalid; }
 };
 
+/// Holds the information from a dbg_label node through SDISel.
+/// We do not use SDValue here to avoid including its header.
+class SDDbgLabel {
+  MDNode *Label;
+  DebugLoc DL;
+  unsigned Order;
+
+public:
+  SDDbgLabel(MDNode *Label, DebugLoc dl, unsigned O)
+      : Label(Label), DL(std::move(dl)), Order(O) {}
+
+  /// Returns the MDNode pointer for the label.
+  MDNode *getLabel() const { return Label; }
+
+  /// Returns the DebugLoc.
+  DebugLoc getDebugLoc() const { return DL; }
+
+  /// Returns the SDNodeOrder.  This is the order of the preceding node in the
+  /// input.
+  unsigned getOrder() const { return Order; }
+};
+
 } // end llvm namespace
 
 #endif

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp?rev=331842&r1=331841&r2=331842&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp Tue May  8 19:41:08 2018
@@ -911,6 +911,39 @@ EmitSchedule(MachineBasicBlock::iterator
     MachineBasicBlock *InsertBB = Emitter.getBlock();
     MachineBasicBlock::iterator Pos = InsertBB->getFirstTerminator();
     InsertBB->insert(Pos, DbgMIs.begin(), DbgMIs.end());
+
+    SDDbgInfo::DbgLabelIterator DLI = DAG->DbgLabelBegin();
+    SDDbgInfo::DbgLabelIterator DLE = DAG->DbgLabelEnd();
+    // Now emit the rest according to source order.
+    LastOrder = 0;
+    for (const auto &InstrOrder : Orders) {
+      unsigned Order = InstrOrder.first;
+      MachineInstr *MI = InstrOrder.second;
+      if (!MI)
+        continue;
+
+      // Insert all SDDbgLabel's whose order(s) are before "Order".
+      for (; DLI != DLE &&
+             (*DLI)->getOrder() >= LastOrder && (*DLI)->getOrder() < Order;
+             ++DLI) {
+        MachineInstr *DbgMI = Emitter.EmitDbgLabel(*DLI);
+        if (DbgMI) {
+          if (!LastOrder)
+            // Insert to start of the BB (after PHIs).
+            BB->insert(BBBegin, DbgMI);
+          else {
+            // Insert at the instruction, which may be in a different
+            // block, if the block was split by a custom inserter.
+            MachineBasicBlock::iterator Pos = MI;
+            MI->getParent()->insert(Pos, DbgMI);
+          }
+        }
+      }
+      if (DLI == DLE)
+        break;
+
+      LastOrder = Order;
+    }
   }
 
   InsertPos = Emitter.getInsertPos();

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=331842&r1=331841&r2=331842&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Tue May  8 19:41:08 2018
@@ -7420,6 +7420,14 @@ void SelectionDAG::salvageDebugInfo(SDNo
     AddDbgValue(Dbg, Dbg->getSDNode(), false);
 }
 
+/// Creates a SDDbgLabel node.
+SDDbgLabel *SelectionDAG::getDbgLabel(DILabel *Label,
+                                      const DebugLoc &DL, unsigned O) {
+  assert(cast<DILabel>(Label)->isValidLocationForIntrinsic(DL) &&
+         "Expected inlined-at fields to agree");
+  return new (DbgInfo->getAlloc()) SDDbgLabel(Label, DL, O);
+}
+
 namespace {
 
 /// RAUWUpdateListener - Helper for ReplaceAllUsesWith - When the node
@@ -7905,6 +7913,10 @@ void SelectionDAG::AddDbgValue(SDDbgValu
   DbgInfo->add(DB, SD, isParameter);
 }
 
+void SelectionDAG::AddDbgLabel(SDDbgLabel *DB) {
+  DbgInfo->add(DB);
+}
+
 SDValue SelectionDAG::makeEquivalentMemoryOrdering(LoadSDNode *OldLoad,
                                                    SDValue NewMemOp) {
   assert(isa<MemSDNode>(NewMemOp.getNode()) && "Expected a memop node");

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=331842&r1=331841&r2=331842&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Tue May  8 19:41:08 2018
@@ -5230,6 +5230,16 @@ SelectionDAGBuilder::visitIntrinsicCall(
     }
     return nullptr;
   }
+  case Intrinsic::dbg_label: {
+    const DbgLabelInst &DI = cast<DbgLabelInst>(I);
+    DILabel *Label = DI.getLabel();
+    assert(Label && "Missing label");
+
+    SDDbgLabel *SDV;
+    SDV = DAG.getDbgLabel(Label, dl, SDNodeOrder);
+    DAG.AddDbgLabel(SDV);
+    return nullptr;
+  }
   case Intrinsic::dbg_value: {
     const DbgValueInst &DI = cast<DbgValueInst>(I);
     assert(DI.getVariable() && "Missing variable");

Added: llvm/trunk/test/DebugInfo/Generic/debug-label-mi.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/Generic/debug-label-mi.ll?rev=331842&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/Generic/debug-label-mi.ll (added)
+++ llvm/trunk/test/DebugInfo/Generic/debug-label-mi.ll Tue May  8 19:41:08 2018
@@ -0,0 +1,58 @@
+; Test DBG_LABEL MachineInstr for label debugging.
+; RUN: llc -fast-isel=false -debug-only=isel %s -o /dev/null 2> %t.debug
+; RUN: cat %t.debug | FileCheck %s --check-prefix=CHECKMI
+;
+; CHECKMI: DBG_LABEL "top", debug-location !9
+; CHECKMI: DBG_LABEL "done", debug-location !11
+;
+; RUN: llc -fast-isel=false %s -o - | FileCheck %s --check-prefix=CHECKASM
+;
+; CHECKASM: #DEBUG_LABEL: foo:top 
+; CHECKASM: #DEBUG_LABEL: foo:done
+
+source_filename = "debug-label-mi.c"
+
+; Function Attrs: noinline nounwind optnone
+define i32 @foo(i32 signext %a, i32 signext %b) #0 !dbg !4 {
+entry:
+  %a.addr = alloca i32, align 4
+  %b.addr = alloca i32, align 4
+  %sum = alloca i32, align 4
+  store i32 %a, i32* %a.addr, align 4
+  store i32 %b, i32* %b.addr, align 4
+  br label %top
+
+top:                                              ; preds = %entry
+  call void @llvm.dbg.label(metadata !8), !dbg !9
+  %0 = load i32, i32* %a.addr, align 4
+  %1 = load i32, i32* %b.addr, align 4
+  %add = add nsw i32 %0, %1
+  store i32 %add, i32* %sum, align 4
+  br label %done
+
+done:                                             ; preds = %top
+  call void @llvm.dbg.label(metadata !10), !dbg !11
+  %2 = load i32, i32* %sum, align 4
+  ret i32 %2
+}
+
+; Function Attrs: nounwind readnone speculatable
+declare void @llvm.dbg.label(metadata)
+
+attributes #0 = { noinline nounwind optnone uwtable }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, isOptimized: false, emissionKind: FullDebug, enums: !2)
+!1 = !DIFile(filename: "debug-label-mi.c", directory: "./")
+!2 = !{}
+!3 = !{i32 2, !"Debug Info Version", i32 3}
+!4 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !5, isLocal: false, isDefinition: true, scopeLine: 2, isOptimized: false, unit: !0, retainedNodes: !2)
+!5 = !DISubroutineType(types: !6)
+!6 = !{!7, !7, !7}
+!7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!8 = !DILabel(scope: !4, name: "top", file: !1, line: 4)
+!9 = !DILocation(line: 4, column: 1, scope: !4)
+!10 = !DILabel(scope: !4, name: "done", file: !1, line: 7)
+!11 = !DILocation(line: 7, column: 1, scope: !4)

Added: llvm/trunk/test/DebugInfo/Generic/debug-label-opt.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/Generic/debug-label-opt.ll?rev=331842&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/Generic/debug-label-opt.ll (added)
+++ llvm/trunk/test/DebugInfo/Generic/debug-label-opt.ll Tue May  8 19:41:08 2018
@@ -0,0 +1,73 @@
+; Test DBG_LABEL MachineInstr under optimization.
+; The test case is generated by clang with -O2 is on.
+; RUN: llc -fast-isel=false -debug-only=isel %s -o /dev/null 2> %t.debug
+; RUN: cat %t.debug | FileCheck %s --check-prefix=CHECKMI
+;
+; CHECKMI: DBG_LABEL "end_sum", debug-location !18
+; CHECKMI: DBG_LABEL "end", debug-location !20
+source_filename = "debug-label-opt.c"
+
+define i32 @foo(i32* nocapture readonly %a, i32 %n) local_unnamed_addr !dbg !7 {
+entry:
+  call void @llvm.dbg.value(metadata i32* %a, metadata !13, metadata !DIExpression()), !dbg !6
+  call void @llvm.dbg.value(metadata i32 %n, metadata !14, metadata !DIExpression()), !dbg !6
+  call void @llvm.dbg.value(metadata i32 0, metadata !15, metadata !DIExpression()), !dbg !6
+  switch i32 %n, label %end_sum [
+    i32 2, label %end_sum.sink.split
+    i32 3, label %if.then3
+  ], !dbg !6
+
+if.then3:                                         ; preds = %entry
+  %arrayidx4 = getelementptr inbounds i32, i32* %a, i64 1, !dbg !6
+  br label %end_sum.sink.split, !dbg !6
+
+end_sum.sink.split:                               ; preds = %entry, %if.then3
+  %a.sink = phi i32* [ %arrayidx4, %if.then3 ], [ %a, %entry ]
+  %.sink = phi i64 [ 2, %if.then3 ], [ 1, %entry ]
+  %0 = load i32, i32* %a.sink, align 4
+  %arrayidx1 = getelementptr inbounds i32, i32* %a, i64 %.sink
+  %1 = load i32, i32* %arrayidx1, align 4
+  %add = add nsw i32 %1, %0
+  br label %end_sum, !dbg !6
+
+end_sum:                                          ; preds = %end_sum.sink.split, %entry
+  %sum.0 = phi i32 [ 0, %entry ], [ %add, %end_sum.sink.split ]
+  call void @llvm.dbg.value(metadata i32 %sum.0, metadata !15, metadata !DIExpression()), !dbg !6
+  call void @llvm.dbg.label(metadata !16), !dbg !18
+  %2 = load i32, i32* %a, align 4, !dbg !6
+  %mul = mul nsw i32 %2, %sum.0, !dbg !19
+  call void @llvm.dbg.value(metadata i32 %mul, metadata !15, metadata !DIExpression()), !dbg !6
+  call void @llvm.dbg.label(metadata !17), !dbg !20
+  ret i32 %mul, !dbg !6
+}
+
+; Function Attrs: nounwind readnone speculatable
+declare void @llvm.dbg.label(metadata)
+
+; Function Attrs: nounwind readnone speculatable
+declare void @llvm.dbg.value(metadata, metadata, metadata)
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4, !5}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
+!1 = !DIFile(filename: "debug-label-opt.c", directory: "./")
+!2 = !{}
+!3 = !{i32 2, !"Dwarf Version", i32 4}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{i32 1, !"wchar_size", i32 4}
+!6 = !DILocation(line: 1, column: 14, scope: !7)
+!7 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !8, isLocal: false, isDefinition: true, scopeLine: 2, flags: DIFlagPrototyped, isOptimized: true, unit: !0, retainedNodes: !12)
+!8 = !DISubroutineType(types: !9)
+!9 = !{!10, !11, !10}
+!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!11 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !10, size: 64)
+!12 = !{!13, !14, !15, !16, !17}
+!13 = !DILocalVariable(name: "a", arg: 1, scope: !7, file: !1, line: 1, type: !11)
+!14 = !DILocalVariable(name: "n", arg: 2, scope: !7, file: !1, line: 1, type: !10)
+!15 = !DILocalVariable(name: "sum", scope: !7, file: !1, line: 3, type: !10)
+!16 = !DILabel(scope: !7, name: "end_sum", file: !1, line: 10)
+!17 = !DILabel(scope: !7, name: "end", file: !1, line: 13)
+!18 = !DILocation(line: 10, column: 1, scope: !7)
+!19 = !DILocation(line: 11, column: 7, scope: !7)
+!20 = !DILocation(line: 13, column: 1, scope: !7)




More information about the llvm-commits mailing list