[llvm] 69549de - [llvm-reduce] Remove debug metadata elements
Ellis Hoag via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 6 09:29:04 PDT 2022
Author: Ellis Hoag
Date: 2022-10-06T09:28:55-07:00
New Revision: 69549de865550e54983ed8d00009920184de47ff
URL: https://github.com/llvm/llvm-project/commit/69549de865550e54983ed8d00009920184de47ff
DIFF: https://github.com/llvm/llvm-project/commit/69549de865550e54983ed8d00009920184de47ff.diff
LOG: [llvm-reduce] Remove debug metadata elements
There can be lots of `MDTuple` debug metadata nodes. For example, `globals: !{!1, !2}` in `!DICompileUnit()`. Search through all debug info to find `MDTuple`'s and remove some of their elements.
For D135114 I was able to get a reproducer with 364 lines without manually deleting elements. After this patch I got it down to 67 lines.
Reviewed By: dblaikie
Differential Revision: https://reviews.llvm.org/D135237
Added:
llvm/test/tools/llvm-reduce/remove-metadata-elements.ll
llvm/test/tools/llvm-reduce/remove-named-metadata-elements.ll
Modified:
llvm/test/tools/llvm-reduce/remove-debug-info-nodes.ll
llvm/test/tools/llvm-reduce/remove-metadata.ll
llvm/tools/llvm-reduce/deltas/ReduceMetadata.cpp
Removed:
llvm/test/tools/llvm-reduce/Inputs/remove-metadata.py
################################################################################
diff --git a/llvm/test/tools/llvm-reduce/Inputs/remove-metadata.py b/llvm/test/tools/llvm-reduce/Inputs/remove-metadata.py
deleted file mode 100755
index 37af33314853c..0000000000000
--- a/llvm/test/tools/llvm-reduce/Inputs/remove-metadata.py
+++ /dev/null
@@ -1,8 +0,0 @@
-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..ab1380508f1e3 100644
--- a/llvm/test/tools/llvm-reduce/remove-debug-info-nodes.ll
+++ b/llvm/test/tools/llvm-reduce/remove-debug-info-nodes.ll
@@ -12,6 +12,10 @@
; CHECK-INTERESTINGNESS-DAG: [[CU]] = distinct !DICompileUnit(language: DW_LANG_C99,{{.*}}, retainedTypes: [[TYPES:![0-9]+]]
; CHECK-INTERESTINGNESS-DAG: [[TYPES]] = !{[[T0:![0-9]+]]
; CHECK-INTERESTINGNESS-DAG: [[T0]] = !DIBasicType(name: "unsigned int",
+; CHECK-INTERESTINGNESS-DAG: !DIGlobalVariable(
+; CHECK-INTERESTINGNESS-DAG: !DILocalVariable(name: "A"
+; CHECK-INTERESTINGNESS-DAG: !DILocalVariable(name: "B"
+; CHECK-INTERESTINGNESS-DAG: !DILocalVariable(name: "C"
diff --git a/llvm/test/tools/llvm-reduce/remove-metadata-elements.ll b/llvm/test/tools/llvm-reduce/remove-metadata-elements.ll
new file mode 100644
index 0000000000000..07c21115a487a
--- /dev/null
+++ b/llvm/test/tools/llvm-reduce/remove-metadata-elements.ll
@@ -0,0 +1,35 @@
+; RUN: llvm-reduce %s -o %t --delta-passes=metadata --test FileCheck --test-arg %s --test-arg --input-file
+; RUN: FileCheck %s < %t --implicit-check-not="boring"
+
+; Test that debug metadata lists can be reduced by making sure debug info for
+; "boring" globals are removed.
+
+; $ cat a.c
+; int boringA, interesting, boringB;
+; $ clang a.c -g -S -emit-llvm -o -
+
+ at A = dso_local global i32 0, align 4, !dbg !0
+ at B = dso_local global i32 0, align 4, !dbg !5
+ at C = dso_local global i32 0, align 4, !dbg !8
+
+!llvm.dbg.cu = !{!2}
+!llvm.module.flags = !{!10, !11, !12, !13, !14, !15, !16}
+
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!1 = distinct !DIGlobalVariable(name: "boringA", scope: !2, file: !3, line: 1, type: !7, isLocal: false, isDefinition: true)
+!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: None)
+!3 = !DIFile(filename: "a.c", directory: "")
+!4 = !{!0, !5, !8}
+!5 = !DIGlobalVariableExpression(var: !6, expr: !DIExpression())
+; CHECK: !DIGlobalVariable(name: "interesting"
+!6 = distinct !DIGlobalVariable(name: "interesting", scope: !2, file: !3, line: 1, type: !7, isLocal: false, isDefinition: true)
+!7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!8 = !DIGlobalVariableExpression(var: !9, expr: !DIExpression())
+!9 = distinct !DIGlobalVariable(name: "boringB", scope: !2, file: !3, line: 1, type: !7, isLocal: false, isDefinition: true)
+!10 = !{i32 7, !"Dwarf Version", i32 5}
+!11 = !{i32 2, !"Debug Info Version", i32 3}
+!12 = !{i32 1, !"wchar_size", i32 4}
+!13 = !{i32 8, !"PIC Level", i32 2}
+!14 = !{i32 7, !"PIE Level", i32 2}
+!15 = !{i32 7, !"uwtable", i32 2}
+!16 = !{i32 7, !"frame-pointer", i32 2}
diff --git a/llvm/test/tools/llvm-reduce/remove-metadata.ll b/llvm/test/tools/llvm-reduce/remove-metadata.ll
index 51a50ca20a985..2ffcdd1ac7554 100644
--- a/llvm/test/tools/llvm-reduce/remove-metadata.ll
+++ b/llvm/test/tools/llvm-reduce/remove-metadata.ll
@@ -1,8 +1,8 @@
; Test that llvm-reduce can remove uninteresting metadata from an IR file.
; The Metadata pass erases named & unnamed metadata nodes.
;
-; RUN: llvm-reduce --test %python --test-arg %p/Inputs/remove-metadata.py %s -o %t
-; RUN: cat %t | FileCheck -implicit-check-not=! %s
+; RUN: llvm-reduce %s -o %t --delta-passes=metadata --test FileCheck --test-arg %s --test-arg --input-file
+; RUN: FileCheck %s < %t
@global = global i32 0, !dbg !0
@@ -11,9 +11,9 @@ define void @main() !dbg !0 {
}
!uninteresting = !{!0}
-; CHECK: !interesting = !{!0}
+; CHECK: !interesting = !{![[I:[0-9]+]]}
!interesting = !{!1}
!0 = !{!"uninteresting"}
-; CHECK: !0 = !{!"interesting"}
+; CHECK: ![[I]] = !{!"interesting"}
!1 = !{!"interesting"}
diff --git a/llvm/test/tools/llvm-reduce/remove-named-metadata-elements.ll b/llvm/test/tools/llvm-reduce/remove-named-metadata-elements.ll
new file mode 100644
index 0000000000000..9ac735ba7d014
--- /dev/null
+++ b/llvm/test/tools/llvm-reduce/remove-named-metadata-elements.ll
@@ -0,0 +1,23 @@
+; RUN: llvm-reduce %s -o %t --delta-passes=metadata --test FileCheck --test-arg %s --test-arg --input-file
+; RUN: FileCheck %s < %t --implicit-check-not="boring" --check-prefixes=CHECK,REDUCED
+
+; Test that we can remove elements from named metadata.
+
+!llvm.dbg.cu = !{!0, !1}
+; CHECK: !llvm.module.flags =
+; REDUCED-SAME: !{}
+!llvm.module.flags = !{!10, !11, !12, !13, !14, !15, !16}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !2, isOptimized: false, runtimeVersion: 0, emissionKind: NoDebug)
+!1 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, isOptimized: false, runtimeVersion: 0, emissionKind: NoDebug)
+; CHECK: !DIFile(filename: "interesting.c"
+!2 = !DIFile(filename: "interesting.c", directory: "")
+!3 = !DIFile(filename: "boring.c", directory: "")
+
+!10 = !{i32 7, !"Dwarf Version", i32 5}
+!11 = !{i32 2, !"Debug Info Version", i32 3}
+!12 = !{i32 1, !"wchar_size", i32 4}
+!13 = !{i32 8, !"PIC Level", i32 2}
+!14 = !{i32 7, !"PIE Level", i32 2}
+!15 = !{i32 7, !"uwtable", i32 2}
+!16 = !{i32 7, !"frame-pointer", i32 2}
diff --git a/llvm/tools/llvm-reduce/deltas/ReduceMetadata.cpp b/llvm/tools/llvm-reduce/deltas/ReduceMetadata.cpp
index 078230e809549..7409a4a19a0a9 100644
--- a/llvm/tools/llvm-reduce/deltas/ReduceMetadata.cpp
+++ b/llvm/tools/llvm-reduce/deltas/ReduceMetadata.cpp
@@ -23,11 +23,18 @@ using namespace llvm;
/// Removes all the Named and Unnamed Metadata Nodes, as well as any debug
/// functions that aren't inside the desired Chunks.
static void extractMetadataFromModule(Oracle &O, Module &Program) {
+ SmallSetVector<MDNode *, 8> NodesToVisit;
+
// Get out-of-chunk Named metadata nodes
SmallVector<NamedMDNode *> NamedNodesToDelete;
- for (NamedMDNode &MD : Program.named_metadata())
- if (!O.shouldKeep())
+ for (NamedMDNode &MD : Program.named_metadata()) {
+ if (O.shouldKeep()) {
+ for (auto *Op : MD.operands())
+ NodesToVisit.insert(Op);
+ } else {
NamedNodesToDelete.push_back(&MD);
+ }
+ }
for (NamedMDNode *NN : NamedNodesToDelete) {
for (auto I : seq<unsigned>(0, NN->getNumOperands()))
@@ -35,13 +42,30 @@ static void extractMetadataFromModule(Oracle &O, Module &Program) {
NN->eraseFromParent();
}
+ // Delete elements from named metadata lists
+ for (auto &NamedList : Program.named_metadata()) {
+ SmallVector<MDNode *> NewOperands;
+ for (auto *Op : NamedList.operands())
+ if (O.shouldKeep())
+ NewOperands.push_back(Op);
+ if (NewOperands.size() == NamedList.getNumOperands())
+ continue;
+ NamedList.clearOperands();
+ for (auto *Op : NewOperands)
+ NamedList.addOperand(Op);
+ }
+
// Delete out-of-chunk metadata attached to globals.
for (GlobalVariable &GV : Program.globals()) {
SmallVector<std::pair<unsigned, MDNode *>> MDs;
GV.getAllMetadata(MDs);
- for (std::pair<unsigned, MDNode *> &MD : MDs)
- if (!O.shouldKeep())
+ for (std::pair<unsigned, MDNode *> &MD : MDs) {
+ if (O.shouldKeep()) {
+ NodesToVisit.insert(MD.second);
+ } else {
GV.setMetadata(MD.first, nullptr);
+ }
+ }
}
for (Function &F : Program) {
@@ -49,20 +73,57 @@ static void extractMetadataFromModule(Oracle &O, Module &Program) {
SmallVector<std::pair<unsigned, MDNode *>> MDs;
// Delete out-of-chunk metadata attached to functions.
F.getAllMetadata(MDs);
- for (std::pair<unsigned, MDNode *> &MD : MDs)
- if (!O.shouldKeep())
+ for (std::pair<unsigned, MDNode *> &MD : MDs) {
+ if (O.shouldKeep()) {
+ NodesToVisit.insert(MD.second);
+ } else {
F.setMetadata(MD.first, nullptr);
+ }
+ }
}
// Delete out-of-chunk metadata attached to instructions.
for (Instruction &I : instructions(F)) {
SmallVector<std::pair<unsigned, MDNode *>> MDs;
I.getAllMetadata(MDs);
- for (std::pair<unsigned, MDNode *> &MD : MDs)
- if (!O.shouldKeep())
+ for (std::pair<unsigned, MDNode *> &MD : MDs) {
+ if (O.shouldKeep()) {
+ NodesToVisit.insert(MD.second);
+ } else {
I.setMetadata(MD.first, nullptr);
+ }
+ }
}
}
+
+ // Gather all metadata tuples and their parents
+ SmallVector<std::pair<MDNode *, unsigned>> OperandsOfTuples;
+ SmallSet<Metadata *, 8> VisitedNodes;
+ while (!NodesToVisit.empty()) {
+ auto *Node = NodesToVisit.pop_back_val();
+ if (!VisitedNodes.insert(Node).second)
+ continue;
+ for (auto I : seq<unsigned>(0, Node->getNumOperands())) {
+ auto *Op = Node->getOperand(I).get();
+ if (auto *MD = dyn_cast_or_null<MDNode>(Op))
+ NodesToVisit.insert(MD);
+ if (isa_and_nonnull<MDTuple>(Op))
+ OperandsOfTuples.push_back(std::make_pair(Node, I));
+ }
+ }
+
+ // Delete elements from metadata tuples
+ for (auto [Node, NodeOpID] : OperandsOfTuples) {
+ auto *Tuple = dyn_cast<MDTuple>(Node->getOperand(NodeOpID));
+ SmallVector<Metadata *> NewOperands;
+ for (auto &Op : Tuple->operands())
+ if (O.shouldKeep())
+ NewOperands.push_back(Op.get());
+ if (NewOperands.size() == Tuple->getNumOperands())
+ continue;
+ Node->replaceOperandWith(
+ NodeOpID, MDTuple::get(Tuple->getContext(), makeArrayRef(NewOperands)));
+ }
}
void llvm::reduceMetadataDeltaPass(TestRunner &Test) {
More information about the llvm-commits
mailing list