1*1debfc3dSmrg#!/usr/bin/perl 2*1debfc3dSmrg 3*1debfc3dSmrg# Three-way DejaGNU comparison; uses dglib.pm. Run perldoc on this file for 4*1debfc3dSmrg# usage. 5*1debfc3dSmrg# 6*1debfc3dSmrg# Author: Matthew Sachs <msachs@apple.com> 7*1debfc3dSmrg# 8*1debfc3dSmrg# Copyright (c) 2006 Free Software Foundation. 9*1debfc3dSmrg# 10*1debfc3dSmrg# This file is part of GCC. 11*1debfc3dSmrg# 12*1debfc3dSmrg# GCC is free software; you can redistribute it and/or modify 13*1debfc3dSmrg# it under the terms of the GNU General Public License as published by 14*1debfc3dSmrg# the Free Software Foundation; either version 3, or (at your option) 15*1debfc3dSmrg# any later version. 16*1debfc3dSmrg# 17*1debfc3dSmrg# GCC is distributed in the hope that it will be useful, 18*1debfc3dSmrg# but WITHOUT ANY WARRANTY; without even the implied warranty of 19*1debfc3dSmrg# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20*1debfc3dSmrg# GNU General Public License for more details. 21*1debfc3dSmrg# 22*1debfc3dSmrg# You should have received a copy of the GNU General Public License 23*1debfc3dSmrg# along with GCC; see the file COPYING. If not, write to 24*1debfc3dSmrg# the Free Software Foundation, 51 Franklin Street, Fifth Floor, 25*1debfc3dSmrg# Boston, MA 02110-1301, USA. 26*1debfc3dSmrg 27*1debfc3dSmrg=pod 28*1debfc3dSmrg 29*1debfc3dSmrg=head1 SYNOPSIS 30*1debfc3dSmrg 31*1debfc3dSmrgcompareSumTests3 -- Two-way or three-way compare between DejaGNU .sum files 32*1debfc3dSmrg 33*1debfc3dSmrg=head1 USAGE 34*1debfc3dSmrg 35*1debfc3dSmrg compareSumTests3 old1.sum [old2.sum] new.sum 36*1debfc3dSmrg compareSumTests3 -i 1:2 -x 2:3 old1.sum old2.sum new.sum 37*1debfc3dSmrg 38*1debfc3dSmrg=head1 DESCRIPTION 39*1debfc3dSmrg 40*1debfc3dSmrgGives results in terms of 'new' (e.g. things that work in 'new' and don't in 41*1debfc3dSmrgother compilers are improvements, things that don't in 'new' and do in others 42*1debfc3dSmrgare regressions, and it tells you which of the two old compilers (or both) 43*1debfc3dSmrgthe test is a regression from. 44*1debfc3dSmrg 45*1debfc3dSmrgWe treat any DG result other than PASS or XFAIL as a failure, e.g. 46*1debfc3dSmrgUNRESOLVED, UNTESTED or test was not run. 47*1debfc3dSmrg 48*1debfc3dSmrgWe merge some tests into 'logical tests' with multiple subphases. 49*1debfc3dSmrgFor instance, some tests will have compile, execute, and link 50*1debfc3dSmrgsubtests. For these tests, if one of the phases fails, we 51*1debfc3dSmrgindicate which phase the failure originates in. For instance, 52*1debfc3dSmrgin the following test results: 53*1debfc3dSmrg 54*1debfc3dSmrg gcc.c-torture/compile_execute/xxxx.c: [FAIL:C,FAIL:X,PASS] 55*1debfc3dSmrg 56*1debfc3dSmrgthe "compile_execute" replaces the compile or execute portion of the test name, 57*1debfc3dSmrgand "FAIL:C" and "FAIL:X" indicates where the combined test failed. 58*1debfc3dSmrg 59*1debfc3dSmrg=head1 OPTIONS 60*1debfc3dSmrg 61*1debfc3dSmrg=head2 OVERVIEW 62*1debfc3dSmrg 63*1debfc3dSmrg=over 4 64*1debfc3dSmrg 65*1debfc3dSmrg=item * 66*1debfc3dSmrg 67*1debfc3dSmrgC<-i X:Y>: Only display differences between the two indicated runs. 68*1debfc3dSmrg 69*1debfc3dSmrg=item * 70*1debfc3dSmrg 71*1debfc3dSmrgC<-p>: Give plain output, suitable for piping to another program. 72*1debfc3dSmrg 73*1debfc3dSmrg=item * 74*1debfc3dSmrg 75*1debfc3dSmrgC<-x X:Y>: Exclude differences between the two indicated runs. 76*1debfc3dSmrg 77*1debfc3dSmrg=back 78*1debfc3dSmrg 79*1debfc3dSmrg=head2 PLAIN OUTPUT FORMAT 80*1debfc3dSmrg 81*1debfc3dSmrgIn the plain 82*1debfc3dSmrgoutput format, the category headers are not displayed and there are no tabs 83*1debfc3dSmrgin front of each result line. Instead, each result line has two characters 84*1debfc3dSmrgfollowed by a space in front of it. The first character will be either an 'I' 85*1debfc3dSmrgfor improvement or 'R' for regression; the second character will be a 1, 2, or 3, 86*1debfc3dSmrgindicating which run was the odd one out. 87*1debfc3dSmrg 88*1debfc3dSmrg=head2 SELECTING CHANGE SUBSETS 89*1debfc3dSmrg 90*1debfc3dSmrgThe following options cause only a selected subset of changes to be displayed. 91*1debfc3dSmrgThese options ask for a "run", a number which is used to select 92*1debfc3dSmrgone of the three runs (C<old1>, C<old2>, or C<new>.) C<1> and C<2> signify C<old1> and C<old2> 93*1debfc3dSmrgrespectively; 3 signifies C<new>. If multiple options are given, the changes displayed 94*1debfc3dSmrgwill be those which obey all of the given restrictions. 95*1debfc3dSmrg 96*1debfc3dSmrgTypical usage of these options is to express something like "give me all changes 97*1debfc3dSmrgbetween 2 and 3, except for those where there was the same difference betwen 1 and 2 98*1debfc3dSmrg(as between 2 and 3.)" This would be given as: 99*1debfc3dSmrg 100*1debfc3dSmrg -i 2:3 -x 1:2 101*1debfc3dSmrg 102*1debfc3dSmrg=over 4 103*1debfc3dSmrg 104*1debfc3dSmrg=item * 105*1debfc3dSmrg 106*1debfc3dSmrgC<-i X:Y>: Only differences which are present between the two runs given 107*1debfc3dSmrgare displayed. For instance, if C<-i 1:2> is given and test A passes in 108*1debfc3dSmrgruns 1 and 2 but fails in run 3, that result will not be displayed. 109*1debfc3dSmrg 110*1debfc3dSmrg=item * 111*1debfc3dSmrg 112*1debfc3dSmrgC<-x X:Y>: Differences which are identical to a difference between the two runs 113*1debfc3dSmrggiven will B<not> be displayed. For instance, if C<-x 1:2> is given and 114*1debfc3dSmrgtest A passes in run 1 and fails in runs 2 and 3, that result will not be 115*1debfc3dSmrgdisplayed (since C<-x> will cause the difference between 1 and 2 to be ignored, 116*1debfc3dSmrgand the difference in 1 and 3 parallels the difference between 1 and 2.) 117*1debfc3dSmrgThis option may only be used in conjunction with C<-i>. 118*1debfc3dSmrg 119*1debfc3dSmrg=back 120*1debfc3dSmrg 121*1debfc3dSmrg=cut 122*1debfc3dSmrg 123*1debfc3dSmrguse strict; 124*1debfc3dSmrguse warnings; 125*1debfc3dSmrguse Getopt::Long; 126*1debfc3dSmrg 127*1debfc3dSmrguse FindBin qw($Bin); 128*1debfc3dSmrguse lib "$Bin"; 129*1debfc3dSmrguse dglib; 130*1debfc3dSmrg 131*1debfc3dSmrgmy %options; 132*1debfc3dSmrgmy $error = undef; 133*1debfc3dSmrg 134*1debfc3dSmrgif(!GetOptions( 135*1debfc3dSmrg "p" => \$options{p}, 136*1debfc3dSmrg "i=s" => \$options{i}, 137*1debfc3dSmrg "x=s" => \$options{x}, 138*1debfc3dSmrg)) { 139*1debfc3dSmrg $error = ""; 140*1debfc3dSmrg} elsif(@ARGV != 2 and @ARGV != 3) { 141*1debfc3dSmrg $error = ""; 142*1debfc3dSmrg} elsif($options{x} and !$options{i}) { 143*1debfc3dSmrg $error = "-x may only be given in conjunction with -i."; 144*1debfc3dSmrg} else { 145*1debfc3dSmrg foreach my $opt("i", "x") { 146*1debfc3dSmrg if($options{$opt} and 147*1debfc3dSmrg ($options{$opt} !~ /^([123]):([123])$/ or 148*1debfc3dSmrg $1 == $2) 149*1debfc3dSmrg ) { 150*1debfc3dSmrg $error = "Invalid -$opt argument."; 151*1debfc3dSmrg } 152*1debfc3dSmrg } 153*1debfc3dSmrg} 154*1debfc3dSmrg 155*1debfc3dSmrgif(defined($error)) { 156*1debfc3dSmrg print STDERR "$error\n" if $error; 157*1debfc3dSmrg print STDERR "Usage: compareSumTests3 [-p] [-i X:Y [-x X:Y]] old1.sum old2.sum new.sum\n"; 158*1debfc3dSmrg print STDERR "Try 'perldoc $0' for further information.\n"; 159*1debfc3dSmrg exit 1; 160*1debfc3dSmrg} 161*1debfc3dSmrg 162*1debfc3dSmrgmy(@sumfiles) = @ARGV; 163*1debfc3dSmrg-f $_ || die "$_ is not a regular file!\n" foreach @sumfiles; 164*1debfc3dSmrgmy(%results, @inc_changes, @exc_changes, %checksums); 165*1debfc3dSmrg 166*1debfc3dSmrg# We decrement the values given so that they correspond 167*1debfc3dSmrg# to indices into our results array. 168*1debfc3dSmrgif($options{i}) { 169*1debfc3dSmrg $options{i} =~ /(\d+):(\d+)/; 170*1debfc3dSmrg @inc_changes = ($1 - 1, $2 - 1); 171*1debfc3dSmrg} 172*1debfc3dSmrgif($options{x}) { 173*1debfc3dSmrg $options{x} =~ /(\d+):(\d+)/; 174*1debfc3dSmrg @exc_changes = ($1 - 1, $2 - 1); 175*1debfc3dSmrg} 176*1debfc3dSmrg 177*1debfc3dSmrg 178*1debfc3dSmrgmy %analyzed_results = compareSumFiles(\@sumfiles); 179*1debfc3dSmrg 180*1debfc3dSmrgforeach my $cat (qw(improvements regressions miscellaneous)) { 181*1debfc3dSmrg if(@sumfiles == 3) { 182*1debfc3dSmrg my @subcounts; 183*1debfc3dSmrg if(!$options{p}) { 184*1debfc3dSmrg $subcounts[$_] = @{$analyzed_results{$cat}->[$_] || []} for(0..2); 185*1debfc3dSmrg print "\u$cat: ", ($subcounts[0]+$subcounts[1]+$subcounts[2]), "\n"; 186*1debfc3dSmrg } 187*1debfc3dSmrg 188*1debfc3dSmrg for(my $i = 0; $i < 3; $i++) { 189*1debfc3dSmrg if(!$options{p} and $cat ne "miscellaneous") { 190*1debfc3dSmrg if($i == 0) { 191*1debfc3dSmrg if($cat eq "regressions") { 192*1debfc3dSmrg print "\tSuccess in old1 only: $subcounts[$i]\n"; 193*1debfc3dSmrg } else { 194*1debfc3dSmrg print "\tFailure in old1 only: $subcounts[$i]\n"; 195*1debfc3dSmrg } 196*1debfc3dSmrg } elsif($i == 1) { 197*1debfc3dSmrg if($cat eq "regressions") { 198*1debfc3dSmrg print "\tSuccess in old2 only: $subcounts[$i]\n"; 199*1debfc3dSmrg } else { 200*1debfc3dSmrg print "\tFailure in old2 only: $subcounts[$i]\n"; 201*1debfc3dSmrg } 202*1debfc3dSmrg } else { 203*1debfc3dSmrg if($cat eq "regressions") { 204*1debfc3dSmrg print "\tFailure in new only: $subcounts[$i]\n"; 205*1debfc3dSmrg } else { 206*1debfc3dSmrg print "\tSuccess in new only: $subcounts[$i]\n"; 207*1debfc3dSmrg } 208*1debfc3dSmrg } 209*1debfc3dSmrg } 210*1debfc3dSmrg 211*1debfc3dSmrg foreach my $test (sort {$a->{name} cmp $b->{name}} @{$analyzed_results{$cat}->[$i] || []}) { 212*1debfc3dSmrg if(!$options{p}) { 213*1debfc3dSmrg if($cat eq "miscellaneous") { 214*1debfc3dSmrg print "\t"; 215*1debfc3dSmrg } else { 216*1debfc3dSmrg print "\t\t"; 217*1debfc3dSmrg } 218*1debfc3dSmrg } else { 219*1debfc3dSmrg if($cat eq "regressions") { 220*1debfc3dSmrg print "R"; 221*1debfc3dSmrg } else { 222*1debfc3dSmrg print "I"; 223*1debfc3dSmrg } 224*1debfc3dSmrg 225*1debfc3dSmrg print $i+1, " "; 226*1debfc3dSmrg } 227*1debfc3dSmrg printf "%s [%s,%s,%s]\n", $test->{name}, $test->{data}->[0], $test->{data}->[1], $test->{data}->[2]; 228*1debfc3dSmrg } 229*1debfc3dSmrg } 230*1debfc3dSmrg } else { 231*1debfc3dSmrg if(!$options{p}) { 232*1debfc3dSmrg my $subcount = @{$analyzed_results{$cat}}; 233*1debfc3dSmrg print "\u$cat: $subcount\n"; 234*1debfc3dSmrg } 235*1debfc3dSmrg 236*1debfc3dSmrg foreach my $test (sort {$a->{name} cmp $b->{name}} @{$analyzed_results{$cat}}) { 237*1debfc3dSmrg if(!$options{p}) { 238*1debfc3dSmrg print "\t"; 239*1debfc3dSmrg } else { 240*1debfc3dSmrg if($cat eq "regressions") { 241*1debfc3dSmrg print "R"; } else { 242*1debfc3dSmrg print "I"; 243*1debfc3dSmrg } 244*1debfc3dSmrg 245*1debfc3dSmrg print " "; 246*1debfc3dSmrg } 247*1debfc3dSmrg printf "%s [%s,%s]\n", $test->{name}, $test->{data}->[0], $test->{data}->[1], $test->{data}->[2]; 248*1debfc3dSmrg } 249*1debfc3dSmrg } 250*1debfc3dSmrg} 251