This adds a simple perl script for reading two files as produced by the stackusage script and computing the changes in stack usage. For example: $ scripts/stackusage -o /tmp/old.su CC=gcc-4.7 -j8 fs/ext4/ $ scripts/stackusage -o /tmp/new.su CC=gcc-5.0 -j8 fs/ext4/ $ scripts/stackdelta /tmp/{old,new}.su | sort -k5,5g shows that gcc 5.0 generally produces less stack-hungry code than gcc 4.7. Obviously, the script can also be used for measuring the effect of commits, .config tweaks or whatnot.
Showing the changes to scripts/stackdelta (1 of 1 file). Show all
Unified · Split
| @@ -0,0 +1,59 @@ | ||
| 1 | +#!/usr/bin/perl | |
| 2 | + | |
| 3 | +# Read two files produced by the stackusage script, and show the | |
| 4 | +# delta between them. | |
| 5 | +# | |
| 6 | +# Currently, only shows changes for functions listed in both files. We | |
| 7 | +# could add an option to show also functions which have vanished or | |
| 8 | +# appeared (which would often be due to gcc making other inlining | |
| 9 | +# decisions). | |
| 10 | +# | |
| 11 | +# Another possible option would be a minimum absolute value for the | |
| 12 | +# delta. | |
| 13 | +# | |
| 14 | +# A third possibility is for sorting by delta, but that can be | |
| 15 | +# achieved by piping to sort -k5,5g. | |
| 16 | + | |
| 17 | +sub read_stack_usage_file { | |
| 18 | + my %su; | |
| 19 | + my $f = shift; | |
| 20 | + open(my $fh, '<', $f) | |
| 21 | + or die "cannot open $f: $!"; | |
| 22 | + while (<$fh>) { | |
| 23 | + chomp; | |
| 24 | + my ($file, $func, $size, $type) = split; | |
| 25 | + # Old versions of gcc (at least 4.7) have an annoying quirk in | |
| 26 | + # that a (static) function whose name has been changed into | |
| 27 | + # for example ext4_find_unwritten_pgoff.isra.11 will show up | |
| 28 | + # in the .su file with a name of just "11". Since such a | |
| 29 | + # numeric suffix is likely to change across different | |
| 30 | + # commits/compilers/.configs or whatever else we're trying to | |
| 31 | + # tweak, we can't really track those functions, so we just | |
| 32 | + # silently skip them. | |
| 33 | + # | |
| 34 | + # Newer gcc (at least 5.0) report the full name, so again, | |
| 35 | + # since the suffix is likely to change, we strip it. | |
| 36 | + next if $func =~ m/^[0-9]+$/; | |
| 37 | + $func =~ s/\..*$//; | |
| 38 | + # Line numbers are likely to change; strip those. | |
| 39 | + $file =~ s/:[0-9]+$//; | |
| 40 | + $su{"${file}\t${func}"} = {size => $size, type => $type}; | |
| 41 | + } | |
| 42 | + close($fh); | |
| 43 | + return \%su; | |
| 44 | +} | |
| 45 | + | |
| 46 | +@ARGV == 2 | |
| 47 | + or die "usage: $0 <old> <new>"; | |
| 48 | + | |
| 49 | +my $old = read_stack_usage_file($ARGV[0]); | |
| 50 | +my $new = read_stack_usage_file($ARGV[1]); | |
| 51 | +my @common = sort grep {exists $new->{$_}} keys %$old; | |
| 52 | +for (@common) { | |
| 53 | + my $x = $old->{$_}{size}; | |
| 54 | + my $y = $new->{$_}{size}; | |
| 55 | + my $delta = $y - $x; | |
| 56 | + if ($delta) { | |
| 57 | + printf "%s\t%d\t%d\t%+d\n", $_, $x, $y, $delta; | |
| 58 | + } | |
| 59 | +} | |