18c2ecf20Sopenharmony_ci#!/usr/bin/env perl
28c2ecf20Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0
38c2ecf20Sopenharmony_ci
48c2ecf20Sopenharmony_ci# Read two files produced by the stackusage script, and show the
58c2ecf20Sopenharmony_ci# delta between them.
68c2ecf20Sopenharmony_ci#
78c2ecf20Sopenharmony_ci# Currently, only shows changes for functions listed in both files. We
88c2ecf20Sopenharmony_ci# could add an option to show also functions which have vanished or
98c2ecf20Sopenharmony_ci# appeared (which would often be due to gcc making other inlining
108c2ecf20Sopenharmony_ci# decisions).
118c2ecf20Sopenharmony_ci#
128c2ecf20Sopenharmony_ci# Another possible option would be a minimum absolute value for the
138c2ecf20Sopenharmony_ci# delta.
148c2ecf20Sopenharmony_ci#
158c2ecf20Sopenharmony_ci# A third possibility is for sorting by delta, but that can be
168c2ecf20Sopenharmony_ci# achieved by piping to sort -k5,5g.
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_cisub read_stack_usage_file {
198c2ecf20Sopenharmony_ci    my %su;
208c2ecf20Sopenharmony_ci    my $f = shift;
218c2ecf20Sopenharmony_ci    open(my $fh, '<', $f)
228c2ecf20Sopenharmony_ci	or die "cannot open $f: $!";
238c2ecf20Sopenharmony_ci    while (<$fh>) {
248c2ecf20Sopenharmony_ci	chomp;
258c2ecf20Sopenharmony_ci	my ($file, $func, $size, $type) = split;
268c2ecf20Sopenharmony_ci	# Old versions of gcc (at least 4.7) have an annoying quirk in
278c2ecf20Sopenharmony_ci	# that a (static) function whose name has been changed into
288c2ecf20Sopenharmony_ci	# for example ext4_find_unwritten_pgoff.isra.11 will show up
298c2ecf20Sopenharmony_ci	# in the .su file with a name of just "11". Since such a
308c2ecf20Sopenharmony_ci	# numeric suffix is likely to change across different
318c2ecf20Sopenharmony_ci	# commits/compilers/.configs or whatever else we're trying to
328c2ecf20Sopenharmony_ci	# tweak, we can't really track those functions, so we just
338c2ecf20Sopenharmony_ci	# silently skip them.
348c2ecf20Sopenharmony_ci	#
358c2ecf20Sopenharmony_ci	# Newer gcc (at least 5.0) report the full name, so again,
368c2ecf20Sopenharmony_ci	# since the suffix is likely to change, we strip it.
378c2ecf20Sopenharmony_ci	next if $func =~ m/^[0-9]+$/;
388c2ecf20Sopenharmony_ci	$func =~ s/\..*$//;
398c2ecf20Sopenharmony_ci	# Line numbers are likely to change; strip those.
408c2ecf20Sopenharmony_ci	$file =~ s/:[0-9]+$//;
418c2ecf20Sopenharmony_ci	$su{"${file}\t${func}"} = {size => $size, type => $type};
428c2ecf20Sopenharmony_ci    }
438c2ecf20Sopenharmony_ci    close($fh);
448c2ecf20Sopenharmony_ci    return \%su;
458c2ecf20Sopenharmony_ci}
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci@ARGV == 2
488c2ecf20Sopenharmony_ci    or die "usage: $0 <old> <new>";
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_cimy $old = read_stack_usage_file($ARGV[0]);
518c2ecf20Sopenharmony_cimy $new = read_stack_usage_file($ARGV[1]);
528c2ecf20Sopenharmony_cimy @common = sort grep {exists $new->{$_}} keys %$old;
538c2ecf20Sopenharmony_cifor (@common) {
548c2ecf20Sopenharmony_ci    my $x = $old->{$_}{size};
558c2ecf20Sopenharmony_ci    my $y = $new->{$_}{size};
568c2ecf20Sopenharmony_ci    my $delta = $y - $x;
578c2ecf20Sopenharmony_ci    if ($delta) {
588c2ecf20Sopenharmony_ci	printf "%s\t%d\t%d\t%+d\n", $_, $x, $y, $delta;
598c2ecf20Sopenharmony_ci    }
608c2ecf20Sopenharmony_ci}
61