187 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
			
		
		
	
	
			187 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
| #! /usr/bin/perl
 | |
| # Script to find regressions by binary-searching a time interval in the
 | |
| # CVS tree.  Written by Brian Gaeke on 2-Mar-2004.
 | |
| #
 | |
| 
 | |
| require 5.6.0;  # NOTE: This script not tested with earlier versions.
 | |
| use Getopt::Std;
 | |
| use POSIX;
 | |
| use Time::Local;
 | |
| use IO::Handle;
 | |
| 
 | |
| sub usage {
 | |
|     print STDERR <<END;
 | |
| findRegression [-I] -w WTIME -d DTIME -t TOOLS -c SCRIPT
 | |
| 
 | |
| The -w, -d, -t, and -c options are required.
 | |
| Run findRegression in the top level of an LLVM tree.
 | |
| WTIME is a time when you are sure the regression does NOT exist ("Works").
 | |
| DTIME is a time when you are sure the regression DOES exist ("Doesntwork").
 | |
| WTIME and DTIME are both in the format: "YYYY/MM/DD HH:MM".
 | |
| -I means run builds at WTIME and DTIME first to make sure.
 | |
| TOOLS is a comma separated list of tools to rebuild before running SCRIPT.
 | |
| SCRIPT exits 1 if the regression is present in TOOLS; 0 otherwise.
 | |
| END
 | |
|     exit 1;
 | |
| }
 | |
| 
 | |
| sub timeAsSeconds {
 | |
|     my ($timestr) = @_;
 | |
| 
 | |
|     if ( $timestr =~ /(\d\d\d\d)\/(\d\d)\/(\d\d) (\d\d):(\d\d)/ ) {
 | |
|         my ( $year, $mon, $mday, $hour, $min ) = ( $1, $2, $3, $4, $5 );
 | |
|         return timegm( 0, $min, $hour, $mday, $mon - 1, $year );
 | |
|     }
 | |
|     else {
 | |
|         die "** Can't parse date + time: $timestr\n";
 | |
|     }
 | |
| }
 | |
| 
 | |
| sub timeAsString {
 | |
|     my ($secs) = @_;
 | |
|     return strftime( "%Y/%m/%d %H:%M", gmtime($secs) );
 | |
| }
 | |
| 
 | |
| sub run {
 | |
|     my ($cmdline) = @_;
 | |
|     print LOG "** Running: $cmdline\n";
 | |
| 	return system($cmdline);
 | |
| }
 | |
| 
 | |
| sub buildLibrariesAndTools {
 | |
|     run("sh /home/vadve/gaeke/scripts/run-configure");
 | |
|     run("$MAKE -C lib/Support");
 | |
|     run("$MAKE -C utils");
 | |
|     run("$MAKE -C lib");
 | |
|     foreach my $tool (@TOOLS) { run("$MAKE -C tools/$tool"); }
 | |
| }
 | |
| 
 | |
| sub contains {
 | |
|     my ( $file, $regex ) = @_;
 | |
|     local (*FILE);
 | |
|     open( FILE, "<$file" ) or die "** can't read $file: $!\n";
 | |
|     while (<FILE>) {
 | |
|         if (/$regex/) {
 | |
|             close FILE;
 | |
|             return 1;
 | |
|         }
 | |
|     }
 | |
|     close FILE;
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| sub updateSources {
 | |
|     my ($time) = @_;
 | |
|     my $inst = "include/llvm/Instruction.h";
 | |
|     unlink($inst);
 | |
|     run( "cvs update -D'" . timeAsString($time) . "'" );
 | |
|     if ( !contains( $inst, 'class Instruction.*Annotable' ) ) {
 | |
|         run("patch -F100 -p0 < makeInstructionAnnotable.patch");
 | |
|     }
 | |
| }
 | |
| 
 | |
| sub regressionPresentAt {
 | |
|     my ($time) = @_;
 | |
| 
 | |
|     updateSources($time);
 | |
|     buildLibrariesAndTools();
 | |
|     my $rc = run($SCRIPT);
 | |
|     if ($rc) {
 | |
|         print LOG "** Found that regression was PRESENT at "
 | |
|           . timeAsString($time) . "\n";
 | |
|         return 1;
 | |
|     }
 | |
|     else {
 | |
|         print LOG "** Found that regression was ABSENT at "
 | |
|           . timeAsString($time) . "\n";
 | |
|         return 0;
 | |
|     }
 | |
| }
 | |
| 
 | |
| sub regressionAbsentAt {
 | |
|     my ($time) = @_;
 | |
|     return !regressionPresentAt($time);
 | |
| }
 | |
| 
 | |
| sub closeTo {
 | |
|     my ( $time1, $time2 ) = @_;
 | |
|     return abs( $time1 - $time2 ) < 600;    # 10 minutes seems reasonable.
 | |
| }
 | |
| 
 | |
| sub halfWayPoint {
 | |
|     my ( $time1, $time2 ) = @_;
 | |
|     my $halfSpan = int( abs( $time1 - $time2 ) / 2 );
 | |
|     if ( $time1 < $time2 ) {
 | |
|         return $time1 + $halfSpan;
 | |
|     }
 | |
|     else {
 | |
|         return $time2 + $halfSpan;
 | |
|     }
 | |
| }
 | |
| 
 | |
| sub checkBoundaryConditions {
 | |
|     print LOG "** Checking for presence of regression at ", timeAsString($DTIME),
 | |
|       "\n";
 | |
|     if ( !regressionPresentAt($DTIME) ) {
 | |
|         die ( "** Can't help you; $SCRIPT says regression absent at dtime: "
 | |
|               . timeAsString($DTIME)
 | |
|               . "\n" );
 | |
|     }
 | |
|     print LOG "** Checking for absence of regression at ", timeAsString($WTIME),
 | |
|       "\n";
 | |
|     if ( !regressionAbsentAt($WTIME) ) {
 | |
|         die ( "** Can't help you; $SCRIPT says regression present at wtime: "
 | |
|               . timeAsString($WTIME)
 | |
|               . "\n" );
 | |
|     }
 | |
| }
 | |
| 
 | |
| ##############################################################################
 | |
| 
 | |
| # Set up log files
 | |
| open (STDERR, ">&STDOUT") || die "** Can't redirect std.err: $!\n";
 | |
| autoflush STDOUT 1;
 | |
| autoflush STDERR 1;
 | |
| open (LOG, ">RegFinder.log") || die "** can't write RegFinder.log: $!\n";
 | |
| autoflush LOG 1;
 | |
| # Check command line arguments and environment variables
 | |
| getopts('Iw:d:t:c:');
 | |
| if ( !( $opt_w && $opt_d && $opt_t && $opt_c ) ) {
 | |
|     usage;
 | |
| }
 | |
| $MAKE  = $ENV{'MAKE'};
 | |
| $MAKE  = 'gmake' unless $MAKE;
 | |
| $WTIME = timeAsSeconds($opt_w);
 | |
| print LOG "** Assuming worked at ", timeAsString($WTIME), "\n";
 | |
| $DTIME = timeAsSeconds($opt_d);
 | |
| print LOG "** Assuming didn't work at ", timeAsString($DTIME), "\n";
 | |
| $opt_t =~ s/\s*//g;
 | |
| $SCRIPT = $opt_c;
 | |
| die "** $SCRIPT is not executable or not found\n" unless -x $SCRIPT;
 | |
| print LOG "** Checking for the regression using $SCRIPT\n";
 | |
| @TOOLS = split ( /,/, $opt_t );
 | |
| print LOG (
 | |
|     "** Going to rebuild: ",
 | |
|     ( join ", ", @TOOLS ),
 | |
|     " before each $SCRIPT run\n"
 | |
| );
 | |
| if ($opt_I) { checkBoundaryConditions(); }
 | |
| # do the dirty work:
 | |
| while ( !closeTo( $DTIME, $WTIME ) ) {
 | |
|     my $halfPt = halfWayPoint( $DTIME, $WTIME );
 | |
|     print LOG "** Checking whether regression is present at ",
 | |
|       timeAsString($halfPt), "\n";
 | |
|     if ( regressionPresentAt($halfPt) ) {
 | |
|         $DTIME = $halfPt;
 | |
|     }
 | |
|     else {
 | |
|         $WTIME = $halfPt;
 | |
|     }
 | |
| }
 | |
| # Tell them what we found
 | |
| print LOG "** Narrowed it down to:\n";
 | |
| print LOG "** Worked at: ",       timeAsString($WTIME), "\n";
 | |
| print LOG "** Did not work at: ", timeAsString($DTIME), "\n";
 | |
| close LOG;
 | |
| exit 0;
 |