+dwarfredundant
authorJan Kratochvil <jan.kratochvil@redhat.com>
Sat, 22 Aug 2020 07:50:42 +0000 (09:50 +0200)
committerJan Kratochvil <jan.kratochvil@redhat.com>
Sat, 22 Aug 2020 07:50:42 +0000 (09:50 +0200)
dwarfredundant [new file with mode: 0755]

diff --git a/dwarfredundant b/dwarfredundant
new file mode 100755 (executable)
index 0000000..5302c08
--- /dev/null
@@ -0,0 +1,72 @@
+#! /usr/bin/perl
+use strict;
+use warnings;
+$|=1;
+my $quiet=shift @ARGV if ($ARGV[0]||"") eq "-q";
+for my $argv (@ARGV) {
+  local *F;
+  open F,"llvm-dwarfdump --color=0 --verbose --debug-info '$argv'|" or die;
+  my $redundant;
+  my $redundant_text;
+  my $redundant_addr;
+  my $redundant_children;
+  my $die_addr;
+  my $die_text;
+  my $saved_total=0;
+  my $emptyline;
+  sub null($) {
+    my($addr)=@_;
+    die if !$redundant;
+    my $saved=eval($addr)+1-eval($redundant_addr);
+    $saved_total+=$saved;
+    print "saved=$saved:\n$redundant_text\nsaved_total=$saved_total\n" if !$quiet;
+    $redundant=0;
+  }
+  while (<F>) {
+    if (/^\s*$/s) {
+      $emptyline=1;
+      next;
+    }
+    my($addr,$spaces,$rest)=(/^(0x[0-9a-f]{8}:| {11})( +)(.*)$/) or do {
+      next;
+    };
+    if ($addr ne " "x11) {
+      $addr=~s/:$// or die;
+    } else {
+      $addr=0;
+    }
+    if ($addr) {
+      if ($emptyline&&$redundant&&!$redundant_children) {
+       null($addr);
+      }
+      $die_addr=$addr;
+      $die_text=$_;
+    } else {
+      $die_text.=$_;
+    }
+    $emptyline=0;
+    if ($redundant) {
+      $redundant_text.=$_ if !$quiet;
+    }
+    my $spacesl=length $spaces or die;
+    if ($rest=~/DW_FORM_addr.*0x0000000000000000/) {
+      next if $redundant;
+      $redundant=$spacesl;
+      $redundant_text=$die_text if !$quiet;
+      $redundant_children=($die_text=~/^.* [*]\n/);
+      $redundant_addr=$die_addr or die;
+      next;
+    }
+    if ($rest=~/DW_AT_stmt_list/) {
+      $redundant=0;
+      next;
+    }
+    if ($rest eq "NULL") {
+      next if !$redundant;
+      next if $spacesl>$redundant;
+      null($addr);
+    }
+  }
+  close F or die;
+  print "$saved_total\n";
+}