162306a36Sopenharmony_ci#!/usr/bin/env perl
262306a36Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0
362306a36Sopenharmony_ci
462306a36Sopenharmony_ci# Read two files produced by the stackusage script, and show the
562306a36Sopenharmony_ci# delta between them.
662306a36Sopenharmony_ci#
762306a36Sopenharmony_ci# Currently, only shows changes for functions listed in both files. We
862306a36Sopenharmony_ci# could add an option to show also functions which have vanished or
962306a36Sopenharmony_ci# appeared (which would often be due to gcc making other inlining
1062306a36Sopenharmony_ci# decisions).
1162306a36Sopenharmony_ci#
1262306a36Sopenharmony_ci# Another possible option would be a minimum absolute value for the
1362306a36Sopenharmony_ci# delta.
1462306a36Sopenharmony_ci#
1562306a36Sopenharmony_ci# A third possibility is for sorting by delta, but that can be
1662306a36Sopenharmony_ci# achieved by piping to sort -k5,5g.
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_cisub read_stack_usage_file {
1962306a36Sopenharmony_ci    my %su;
2062306a36Sopenharmony_ci    my $f = shift;
2162306a36Sopenharmony_ci    open(my $fh, '<', $f)
2262306a36Sopenharmony_ci	or die "cannot open $f: $!";
2362306a36Sopenharmony_ci    while (<$fh>) {
2462306a36Sopenharmony_ci	chomp;
2562306a36Sopenharmony_ci	my ($file, $func, $size, $type) = split;
2662306a36Sopenharmony_ci	# Old versions of gcc (at least 4.7) have an annoying quirk in
2762306a36Sopenharmony_ci	# that a (static) function whose name has been changed into
2862306a36Sopenharmony_ci	# for example ext4_find_unwritten_pgoff.isra.11 will show up
2962306a36Sopenharmony_ci	# in the .su file with a name of just "11". Since such a
3062306a36Sopenharmony_ci	# numeric suffix is likely to change across different
3162306a36Sopenharmony_ci	# commits/compilers/.configs or whatever else we're trying to
3262306a36Sopenharmony_ci	# tweak, we can't really track those functions, so we just
3362306a36Sopenharmony_ci	# silently skip them.
3462306a36Sopenharmony_ci	#
3562306a36Sopenharmony_ci	# Newer gcc (at least 5.0) report the full name, so again,
3662306a36Sopenharmony_ci	# since the suffix is likely to change, we strip it.
3762306a36Sopenharmony_ci	next if $func =~ m/^[0-9]+$/;
3862306a36Sopenharmony_ci	$func =~ s/\..*$//;
3962306a36Sopenharmony_ci	# Line numbers are likely to change; strip those.
4062306a36Sopenharmony_ci	$file =~ s/:[0-9]+$//;
4162306a36Sopenharmony_ci	$su{"${file}\t${func}"} = {size => $size, type => $type};
4262306a36Sopenharmony_ci    }
4362306a36Sopenharmony_ci    close($fh);
4462306a36Sopenharmony_ci    return \%su;
4562306a36Sopenharmony_ci}
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci@ARGV == 2
4862306a36Sopenharmony_ci    or die "usage: $0 <old> <new>";
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_cimy $old = read_stack_usage_file($ARGV[0]);
5162306a36Sopenharmony_cimy $new = read_stack_usage_file($ARGV[1]);
5262306a36Sopenharmony_cimy @common = sort grep {exists $new->{$_}} keys %$old;
5362306a36Sopenharmony_cifor (@common) {
5462306a36Sopenharmony_ci    my $x = $old->{$_}{size};
5562306a36Sopenharmony_ci    my $y = $new->{$_}{size};
5662306a36Sopenharmony_ci    my $delta = $y - $x;
5762306a36Sopenharmony_ci    if ($delta) {
5862306a36Sopenharmony_ci	printf "%s\t%d\t%d\t%+d\n", $_, $x, $y, $delta;
5962306a36Sopenharmony_ci    }
6062306a36Sopenharmony_ci}
61