[llvm] 2c799b7 - [llvm-reduce] Add pass that reduces DebugInfo metadata

Matthew Voss via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 6 14:24:59 PDT 2022


Author: Matthew Voss
Date: 2022-10-06T14:24:39-07:00
New Revision: 2c799b7793ccdce1759b779f45f10ce5755b9d5d

URL: https://github.com/llvm/llvm-project/commit/2c799b7793ccdce1759b779f45f10ce5755b9d5d
DIFF: https://github.com/llvm/llvm-project/commit/2c799b7793ccdce1759b779f45f10ce5755b9d5d.diff

LOG: [llvm-reduce] Add pass that reduces DebugInfo metadata

This new pass for llvm-reduce attempts to reduce DebugInfo metadata.
The process used is:
  1. Scan every MD node, keeping track of nodes already visited.
  2. Look for DebugInfo nodes, then record any operands that are lists.
  3. Bisect though all the elements of the collected lists.

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

Added: 
    llvm/test/tools/llvm-reduce/Inputs/remove-dimetadata.py
    llvm/test/tools/llvm-reduce/remove-dimetadata.ll
    llvm/tools/llvm-reduce/deltas/ReduceDIMetadata.cpp
    llvm/tools/llvm-reduce/deltas/ReduceDIMetadata.h

Modified: 
    llvm/test/tools/llvm-reduce/remove-debug-info-nodes.ll
    llvm/tools/llvm-reduce/CMakeLists.txt
    llvm/tools/llvm-reduce/DeltaManager.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/test/tools/llvm-reduce/Inputs/remove-dimetadata.py b/llvm/test/tools/llvm-reduce/Inputs/remove-dimetadata.py
new file mode 100644
index 0000000000000..9fc290c8f26ca
--- /dev/null
+++ b/llvm/test/tools/llvm-reduce/Inputs/remove-dimetadata.py
@@ -0,0 +1,8 @@
+import sys
+
+input = open(sys.argv[1], "r")
+for line in input:
+  if "interesting" in line:
+    sys.exit(0)
+
+sys.exit(1)

diff  --git a/llvm/test/tools/llvm-reduce/remove-debug-info-nodes.ll b/llvm/test/tools/llvm-reduce/remove-debug-info-nodes.ll
index 1863d35d9c750..9c8630be462ee 100644
--- a/llvm/test/tools/llvm-reduce/remove-debug-info-nodes.ll
+++ b/llvm/test/tools/llvm-reduce/remove-debug-info-nodes.ll
@@ -1,7 +1,7 @@
 ; Test that llvm-reduce can drop unneeded debug metadata nodes referenced by
 ; DICompileUnit and DISuprogram.
 ;
-; RUN: llvm-reduce --delta-passes=metadata --test FileCheck --test-arg --check-prefixes=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t
+; RUN: llvm-reduce --delta-passes=di-metadata --abort-on-invalid-reduction --test FileCheck --test-arg --check-prefixes=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t
 ; RUN: cat %t | FileCheck %s
 
 ; CHECK-INTERESTINGNESS: define void @test() !dbg
@@ -21,13 +21,12 @@
 ; CHECK: !llvm.dbg.cu = !{[[CU:.+]]}
 
 ; CHECK-DAG: [[CU]] = distinct !DICompileUnit(language: DW_LANG_C99,{{.*}}, retainedTypes: [[TYPES:![0-9]+]], globals: [[GLOBALS:![0-9]+]]
+; CHECK-DAG: [[EMPTY:![0-9]+]] = !{}
 ; CHECK-DAG: [[TYPES]] = !{[[T0:![0-9]+]]
 ; CHECK-DAG: [[T0]] = !DIBasicType(name: "unsigned int",
-; CHECK-DAG: [[GLOBALS]] = !{!{{.+}}
+; CHECK-DAG: [[GLOBALS]] = !{{{![0-9]+}}
 
-
-; CHECK-DAG: [[SUBPROG]] = distinct !DISubprogram(name: "test", {{.*}}retainedNodes: [[RETAINED_NODES:.+]])
-; CHECK-DAG: [[RETAINED_NODES]] = !{!{{.+}},
+; CHECK-DAG: [[SUBPROG]] = distinct !DISubprogram(name: "test", {{.*}}retainedNodes: [[EMPTY]])
 
 define void @test() !dbg !17 {
   ret void

diff  --git a/llvm/test/tools/llvm-reduce/remove-dimetadata.ll b/llvm/test/tools/llvm-reduce/remove-dimetadata.ll
new file mode 100644
index 0000000000000..71cefaf173634
--- /dev/null
+++ b/llvm/test/tools/llvm-reduce/remove-dimetadata.ll
@@ -0,0 +1,34 @@
+; Test that llvm-reduce can remove uninteresting DI metadata from an IR file.
+;
+; RUN: llvm-reduce --abort-on-invalid-reduction --delta-passes=di-metadata --test %python --test-arg %p/Inputs/remove-dimetadata.py %s -o %t
+; RUN: FileCheck <%t %s
+
+ at global = global i32 0
+
+define void @main() !dbg !5 {
+   ret void
+}
+
+!llvm.module.flags = !{!0}
+!llvm.dbg.cu = !{!4}
+
+!0 = !{i32 2, !"Debug Info Version", i32 3}
+!1 = !DIFile(filename: "test.c", directory: "test")
+!2 = !{!10}
+; CHECK: [[EMPTY:![0-9]+]] = !{}
+!4 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !9)
+!5 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 498, type: !6, scopeLine: 0, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !4, retainedNodes: !2)
+!6 = !DISubroutineType(types: !7)
+; CHECK: !DISubroutineType(types: [[EMPTY]])
+!7 = !{!13}
+!8 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !9)
+!9 = !{}
+!10 = !DILocalVariable(name: "one", scope: !14, file: !1, line: 0, type: !15)
+!13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!14 = distinct !DILexicalBlock(scope: !5, file: !1, line: 3)
+!15 = !DICompositeType(tag: DW_TAG_structure_type, name: "test", file: !1, size: 64, align: 32, flags: DIFlagPublic, elements: !16)
+!16 = !{!17, !18}
+; CHECK: elements: [[EL:![0-9]+]])
+; CHECK: [[EL]] = !{!{{[0-9]+}}}
+!17 = !DIDerivedType(tag: DW_TAG_member, name: "interesting", scope: !14, file: !1, baseType: !13, size: 32, align: 32, flags: DIFlagPublic)
+!18 = !DIDerivedType(tag: DW_TAG_member, name: "uninteresting", scope: !14, file: !1, baseType: !13, size: 32, align: 32, offset: 32, flags: DIFlagPublic)

diff  --git a/llvm/tools/llvm-reduce/CMakeLists.txt b/llvm/tools/llvm-reduce/CMakeLists.txt
index a782d39c495b7..0dafd8834d8eb 100644
--- a/llvm/tools/llvm-reduce/CMakeLists.txt
+++ b/llvm/tools/llvm-reduce/CMakeLists.txt
@@ -28,6 +28,7 @@ add_llvm_tool(llvm-reduce
   deltas/ReduceArguments.cpp
   deltas/ReduceAttributes.cpp
   deltas/ReduceBasicBlocks.cpp
+  deltas/ReduceDIMetadata.cpp
   deltas/ReduceFunctionBodies.cpp
   deltas/ReduceFunctions.cpp
   deltas/ReduceGlobalObjects.cpp

diff  --git a/llvm/tools/llvm-reduce/DeltaManager.cpp b/llvm/tools/llvm-reduce/DeltaManager.cpp
index 89fd33b24be12..9d7b4342429cb 100644
--- a/llvm/tools/llvm-reduce/DeltaManager.cpp
+++ b/llvm/tools/llvm-reduce/DeltaManager.cpp
@@ -19,6 +19,7 @@
 #include "deltas/ReduceArguments.h"
 #include "deltas/ReduceAttributes.h"
 #include "deltas/ReduceBasicBlocks.h"
+#include "deltas/ReduceDIMetadata.h"
 #include "deltas/ReduceFunctionBodies.h"
 #include "deltas/ReduceFunctions.h"
 #include "deltas/ReduceGlobalObjects.h"
@@ -65,6 +66,7 @@ static cl::opt<std::string>
     DELTA_PASS("global-objects", reduceGlobalObjectsDeltaPass)                 \
     DELTA_PASS("global-initializers", reduceGlobalsInitializersDeltaPass)      \
     DELTA_PASS("global-variables", reduceGlobalsDeltaPass)                     \
+    DELTA_PASS("di-metadata", reduceDIMetadataDeltaPass)                       \
     DELTA_PASS("metadata", reduceMetadataDeltaPass)                            \
     DELTA_PASS("arguments", reduceArgumentsDeltaPass)                          \
     DELTA_PASS("instructions", reduceInstructionsDeltaPass)                    \

diff  --git a/llvm/tools/llvm-reduce/deltas/ReduceDIMetadata.cpp b/llvm/tools/llvm-reduce/deltas/ReduceDIMetadata.cpp
new file mode 100644
index 0000000000000..e72dc2c80f46b
--- /dev/null
+++ b/llvm/tools/llvm-reduce/deltas/ReduceDIMetadata.cpp
@@ -0,0 +1,102 @@
+//===- ReduceDIMetadata.cpp - Specialized Delta pass for DebugInfo --------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements two functions used by the Generic Delta Debugging
+// Algorithm, which are used to reduce DebugInfo metadata nodes.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ReduceDIMetadata.h"
+#include "Delta.h"
+#include "llvm/ADT/Sequence.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/DebugInfoMetadata.h"
+#include "llvm/IR/InstIterator.h"
+#include <set>
+#include <stack>
+#include <tuple>
+#include <vector>
+
+using namespace llvm;
+
+using MDNodeList = SmallVector<MDNode *>;
+
+void identifyUninterestingMDNodes(Oracle &O, MDNodeList &MDs) {
+  DenseSet<std::tuple<MDNode *, size_t, MDNode *>> Tuples;
+  std::vector<MDNode *> ToLook;
+  DenseSet<MDNode *> Visited;
+
+  // Start by looking at the attachments we collected
+  for (const auto &NMD : MDs)
+    if (NMD && !Visited.count(NMD))
+      ToLook.push_back(NMD);
+
+  while (!ToLook.empty()) {
+    MDNode *MD = ToLook.back();
+    ToLook.pop_back();
+
+    if (Visited.count(MD))
+      continue;
+
+    // Determine if the current MDNode is DebugInfo
+    if (DINode *DIM = dyn_cast_or_null<DINode>(MD)) {
+      // Scan operands and record attached tuples
+      for (size_t I = 0; I < DIM->getNumOperands(); ++I)
+        if (MDTuple *MDT = dyn_cast_or_null<MDTuple>(DIM->getOperand(I)))
+          if (!Visited.count(MDT) && MDT->getNumOperands())
+            Tuples.insert({DIM, I, MDT});
+    }
+
+    // Add all of the operands of the current node to the loop's todo list.
+    for (Metadata *Op : MD->operands())
+      if (MDNode *OMD = dyn_cast_or_null<MDNode>(Op))
+        ToLook.push_back(OMD);
+
+    Visited.insert(MD);
+  }
+
+  for (auto &T : Tuples) {
+    auto [DbgNode, OpIdx, Tup] = T;
+    // Remove the operands of the tuple that are not in the desired chunks.
+    SmallVector<Metadata *, 16> TN;
+    for (size_t I = 0; I < Tup->getNumOperands(); ++I) {
+      // Ignore any operands that are not DebugInfo metadata nodes.
+      if (MDNode *OMD = dyn_cast_or_null<DINode>(Tup->getOperand(I)))
+        // Don't add uninteresting operands to the tuple.
+        if (!O.shouldKeep())
+          continue;
+
+      TN.push_back(Tup->getOperand(I));
+    }
+    if (TN.size() != Tup->getNumOperands())
+      DbgNode->replaceOperandWith(OpIdx, DbgNode->get(DbgNode->getContext(), TN));
+  }
+}
+
+static void extractDIMetadataFromModule(Oracle &O, Module &Program) {
+  MDNodeList MDs;
+  // Collect all !dbg metadata attachments.
+  for (const auto &DC : Program.debug_compile_units())
+    if (DC)
+      MDs.push_back(DC);
+  for (GlobalVariable &GV : Program.globals())
+    GV.getMetadata(llvm::LLVMContext::MD_dbg, MDs);
+  for (Function &F : Program.functions()) {
+    F.getMetadata(llvm::LLVMContext::MD_dbg, MDs);
+    for (Instruction &I : instructions(F))
+      if (auto *DI = I.getMetadata(llvm::LLVMContext::MD_dbg))
+        MDs.push_back(DI);
+  }
+  identifyUninterestingMDNodes(O, MDs);
+}
+
+void llvm::reduceDIMetadataDeltaPass(TestRunner &Test) {
+  outs() << "*** Reducing DIMetadata...\n";
+  runDeltaPass(Test, extractDIMetadataFromModule);
+  outs() << "----------------------------\n";
+}

diff  --git a/llvm/tools/llvm-reduce/deltas/ReduceDIMetadata.h b/llvm/tools/llvm-reduce/deltas/ReduceDIMetadata.h
new file mode 100644
index 0000000000000..379c14a0db200
--- /dev/null
+++ b/llvm/tools/llvm-reduce/deltas/ReduceDIMetadata.h
@@ -0,0 +1,23 @@
+//===- ReduceMetadata.h - Specialized Delta Pass --------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements two functions used by the Generic Delta Debugging
+// Algorithm, which are used to reduce Metadata nodes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLS_LLVM_REDUCE_DELTAS_REDUCEDIMETADATA_H
+#define LLVM_TOOLS_LLVM_REDUCE_DELTAS_REDUCEDIMETADATA_H
+
+#include "TestRunner.h"
+
+namespace llvm {
+void reduceDIMetadataDeltaPass(TestRunner &Test);
+} // namespace llvm
+
+#endif


        


More information about the llvm-commits mailing list