1#! /usr/bin/perl -w
2
3
4use strict;
5
6
7if (scalar (@ARGV) < 3)
8  {
9    die " Format: $0 <build-dir1> <build-dir2> <program> [options...]\n";
10  }
11
12# beg: conf
13my $num_cmp = 4;
14my $ld_tmpfile = "ld_cmp_tmp.$$";
15# end: conf
16
17
18
19sub gen_stats
20  {
21    my $bdir = shift;
22
23    if (!open(STATS, "> $ld_tmpfile"))
24      { die "open($ld_tmpfile): $!\n"; }
25    if (!open(OLD_STDERR, ">&STDERR"))
26      { die "dup2(OLD, STDERR): $!\n"; }
27    if (!open(STDERR, ">&STATS"))
28      { die "dup2(STDERR, STATS): $!\n"; }
29
30    $ENV{LD_LIBRARY_PATH} = "../$bdir/src/.libs/";
31    for (1..$num_cmp)
32      {	system("./ld_stats.sh", @_); }
33
34    if (!open(STDERR, ">&OLD_STDERR"))
35      { die "dup2(STATS): $!\n"; }
36
37    close(OLD_STDERR);
38    close(STATS);
39
40    if (!open(STATS, "< $ld_tmpfile"))
41      { die "open($ld_tmpfile): $!\n"; }
42  }
43
44sub proc_stats
45  {
46    my $bstats = shift;
47
48    $bstats->{startup} = [];
49    $bstats->{time_reloc_clock} = [];
50    $bstats->{time_reloc_per} = [];
51    $bstats->{num_reloc} = [];
52    $bstats->{num_cache_reloc} = [];
53    $bstats->{time_objs_clock} = [];
54    $bstats->{time_objs_per} = [];
55    $bstats->{final_num_reloc} = [];
56    $bstats->{final_num_cache_reloc} = [];
57
58    while (<STATS>)
59      {
60	if (/\d+: \s+ $/x) { next; }
61	if (/\d+: \s+ runtime \s linker \s statistics:/x) { next; }
62	if (/\d+: \s+ total \s startup \s time \s in \s dynamic \s loader: \s
63	    (\d+) \s clock \s cycles$/x)
64	  {
65	    push @{$bstats->{startup}}, $1;
66	    next;
67	  }
68	if (/\d+: \s+ time \s needed \s for \s relocation: \s
69	    (\d+) \s clock \s cycles \s \((\d+).(\d+)\%\)/x)
70	  {
71	    push @{$bstats->{time_reloc_clock}}, $1;
72	    push @{$bstats->{time_reloc_per}}, "$2.$3";
73	    next;
74	  }
75	if (/\d+: \s+ number \s of \s relocations: \s
76	    (\d+)$/x)
77	  {
78	    push @{$bstats->{num_reloc}}, $1;
79	    next;
80	  }
81	if (/\d+: \s+ number \s of \s relocations \s from \s cache: \s
82	    (\d+)$/x)
83	  {
84	    push @{$bstats->{num_cache_reloc}}, $1;
85	    next;
86	  }
87	if (/\d+: \s+ time \s needed \s to \s load \s objects: \s
88	    (\d+) \s clock \s cycles \s \((\d+).(\d+)\%\)/x)
89	  {
90	    push @{$bstats->{time_objs_clock}}, $1;
91	    push @{$bstats->{time_objs_per}}, "$2.$3";
92	    next;
93	  }
94	if (/\d+: \s+ final \s number \s of \s relocations: \s
95	    (\d+)$/x)
96	  {
97	    push @{$bstats->{final_num_reloc}}, $1;
98	    next;
99	  }
100	if (/\d+: \s+ final \s number \s of \s relocations \s from \s cache: \s
101	    (\d+)$/x)
102	  {
103	    push @{$bstats->{final_num_cache_reloc}}, $1;
104	    next;
105	  }
106	die "No match: $_\n";
107      }
108  }
109
110my %b1_stats = ();
111my %b2_stats = ();
112my @bl = [];
113
114$bl[0] = shift @ARGV;
115$bl[1] = shift @ARGV;
116
117gen_stats($bl[0], @ARGV);
118proc_stats(\%b1_stats);
119
120gen_stats($bl[1], @ARGV);
121proc_stats(\%b2_stats);
122
123for my $i (keys %b1_stats)
124  {
125    print "$i\n";
126
127    for my $j (1..$num_cmp)
128      {
129	my $off = $j - 1;
130	my @vals;
131
132	$vals[0] = ${$b1_stats{$i}}[$off];
133	$vals[1] = ${$b2_stats{$i}}[$off];
134
135        print sprintf("%4d.  ", $j);
136	print "$bl[0]($vals[0]) - $bl[1]($vals[1]) = ";
137	print $vals[0] - $vals[1];
138	print "\n";
139      }
140  }
141
142unlink($ld_tmpfile);
143