[project @ 2000-02-24 17:45:53 by simonmar]
[ghc-hetmet.git] / glafp-utils / runstdtest / runstdtest.prl
index 55860fd..9aa7ac9 100644 (file)
@@ -12,7 +12,7 @@
 #          [default: anything on the cmd line this script doesn't recognise ]
 #        the first opt not starting w/ "-" is taken to be an input
 #        file and (if it exists) is grepped for "what's going on here"
-#        comments (^--!!!).
+#        comments (^-- !!!).
 #      * a file to feed to stdin ( -i<file> ) [default: /dev/null ]
 #      * a "time" command to use (-t <cmd>).
 #
 #
 ($Pgm = $0) =~ s|.*/||;
 $Verbose = 0;
-$SaveTmpFile = 0;
+$SaveStderr = 0;
+$SaveStdout = 0;
 $Status = 0;
 @PgmArgs = ();
+$PgmFail=0;
 $PgmExitStatus = 0;
 $PgmStdinFile  = '/dev/null';
 if ( $ENV{'TMPDIR'} ) { # where to make tmp file names
@@ -61,8 +63,9 @@ $PreScript = '';
 $PostScript = '';
 $TimeCmd = '';
 $StatsFile = "$TmpPrefix/stats$$";
+$CacheProfStats = "cacheprof.out.summary";
 $SysSpecificTiming = '';
-$SpixTiming = 'no';
+$CacheProf = 'no';
 
 die "$Pgm: program to run not given as first argument\n" if $#ARGV < 0;
 $ToRun = $ARGV[0]; shift(@ARGV);
@@ -77,14 +80,17 @@ arg: while ($_ = $ARGV[0]) {
                        last arg; };
 
     /^-v$/            && do { $Verbose = 1; next arg; };
-    /^-accept-output$/ && do { $SaveTmpFile = 1; next arg; };
+    /^-accept-output-stderr$/ && do { $SaveStderr = 1; next arg; };
+    /^-accept-output-stdout$/ && do { $SaveStdout = 1; next arg; };
+    /^-accept-output$/        && do { $SaveStdout = 1; $SaveStderr = 1; next arg; };
 
     /^-O(.*)/  && do { push(@PgmArgs, &grab_arg_arg('-O',$1)); next arg; };
     /^-i(.*)/  && do { $PgmStdinFile = &grab_arg_arg('-i',$1);
                        $Status++,
                        print STDERR "$Pgm: bogus -i input file: $PgmStdinFile\n"
-                           if ! -f $PgmStdinFile;
+                           if $PgmStdinFile !~ /^\/dev\/.*$/ && ! -f $PgmStdinFile;
                        next arg; };
+    /^-fail/    && do { $PgmFail=1; next arg; };
     /^-x(.*)/  && do { $PgmExitStatus = &grab_arg_arg('-x',$1);
                        $Status++ ,
                        print STDERR "$Pgm: bogus -x expected exit status: $PgmExitStatus\n"
@@ -105,9 +111,9 @@ arg: while ($_ = $ARGV[0]) {
                    next arg; };
     /^-(ghc|hbc)-timing$/ && do { $SysSpecificTiming = $1;
                                  next arg; };
-    /^-spix-timing$/ && do { $SysSpecificTiming = 'ghcspix';
-                            $SpixTiming = 'yes';
-                            next arg; };
+    /^-cacheprof$/ && do { $SysSpecificTiming = 'ghc-instrs';
+                          $CacheProf = 'yes'; 
+                          next arg };
     /^-t(.*)/  && do { $TimeCmd = &grab_arg_arg('-t', $1); next arg; };
 
     # anything else is taken to be a pgm arg
@@ -115,26 +121,16 @@ arg: while ($_ = $ARGV[0]) {
 }
 
 foreach $out_file ( @PgmStdoutFile ) {
-    if ( ! -f $out_file ) {
-        #$Status++;
-        pop(@PgmStdoutFile);
-       if ( $SaveTmpFile ) {
-           system("touch $out_file");
-       } else {
+    if ( ! -f $out_file && !$SaveStdout ) {
            print STDERR "$Pgm: warning: expected-stdout file missing: $out_file\n";
-       }
+           pop(@PgmStdoutFile);
     }
 }
 
 foreach $out_file ( @PgmStderrFile ) {
-    if ( ! -f $out_file ) {
-       #$Status++;
-        pop(@PgmStderrFile);
-       if ( $SaveTmpFile ) {
-           system("touch $out_file");
-       } else {
-           print STDERR "$Pgm: warning: expected-stderr file missing: $out_file\n";
-       }
+    if ( ! -f $out_file && !$SaveStderr ) {
+           print STDERR "$Pgm: warning: expected-stderr file missing: $out_file\n";
+           pop(@PgmStderrFile);
     }
 }
 
@@ -146,12 +142,12 @@ exit 1 if $Status;
 
 # tidy up the pgm args:
 # (1) look for the "first input file"
-#     and grep it for "interesting" comments (--!!! )
+#     and grep it for "interesting" comments (-- !!! )
 # (2) quote any args w/ whitespace in them.
 $grep_done = 0;
 foreach $a ( @PgmArgs ) {
     if (! $grep_done && $a !~ /^-/ && -f $a) {
-       print `egrep "^--!!!" $a`;
+       print `egrep "^--[ ]?!!!" $a`;
        $grep_done = 1;
     }
     if ($a =~ /\s/ || $a =~ /'/) {
@@ -163,39 +159,11 @@ foreach $a ( @PgmArgs ) {
 # deal with system-specific timing options
 $TimingMagic = '';
 if ( $SysSpecificTiming =~ /^ghc/ ) {
-    $TimingMagic = "+RTS -s$StatsFile -RTS"
+    $TimingMagic = "+RTS -S$StatsFile -RTS"
 } elsif ( $SysSpecificTiming eq 'hbc' ) {
     $TimingMagic = "-S$StatsFile";
 }
 
-$ToRunOrig = $ToRun;
-if ( $SpixTiming eq 'yes' ) {
-    $ToRun .= '.spix';
-
-    # gotta find first/last addresses in the mutator code
-    $FirstSpix = '_callWrapper';
-    $LastSpix  = '???'; # usually _mpz_get_si, but can't be sure
-
-    open(SPIXNM, "nm -n $ToRunOrig |") || die "nm -n $ToRunOrig open failed!\n";
-    spix: while (<SPIXNM>) {
-       if ( / T +(_freeForeignObj|_([A-Za-z]+)Hook|_xmalloc|_mpz_get_si)$/ ) {
-           $LastSpix = $1;
-           last spix;
-       }
-    }
-    close(SPIXNM); # || die "nm -n $ToRunOrig close failed!\n";
-
-    $SpixifyLine1 = "spix -o $ToRun -t$FirstSpix,$LastSpix $ToRunOrig";
-    $SpixstatsLine1 = "spixstats -b $TmpPrefix/runtest$$.3 $ToRunOrig > $ToRunOrig.spixstats1";
-    $SpixifyLine2 = "spix -o $ToRun +t$FirstSpix,$LastSpix $ToRunOrig";
-    $SpixstatsLine2 = "spixstats -b $TmpPrefix/runtest$$.3 $ToRunOrig > $ToRunOrig.spixstats2";
-} else {
-    $SpixifyLine1 = '';
-    $SpixstatsLine1 = '';
-    $SpixifyLine2 = '';
-    $SpixstatsLine2 = '';
-}
-
 if ($PreScript ne '') {
     local($to_do);
     $PreScriptLines = `cat $PreScript`;
@@ -226,7 +194,12 @@ $PreScriptLines
 $SpixifyLine1
 $TimeCmd /bin/sh -c \'$ToRun $TimingMagic @PgmArgs < $PgmStdinFile 1> $TmpPrefix/runtest$$.1 2> $TmpPrefix/runtest$$.2 3> $TmpPrefix/runtest$$.3\'
 progexit=\$?
-if [ \$progexit -ne $PgmExitStatus ]; then
+if [ \$progexit -eq 0 ] && [ $PgmFail -ne 0 ]; then
+    echo $ToRun @PgmArgs \\< $PgmStdinFile
+    echo "****" expected a failure, but was successful
+    myexit=1
+fi
+if [ \$progexit -ne $PgmExitStatus ] && [ $PgmFail -eq 0 ]; then
     echo $ToRun @PgmArgs \\< $PgmStdinFile
     echo "****" expected exit status $PgmExitStatus not seen \\; got \$progexit
     myexit=1
@@ -241,14 +214,19 @@ else
     if [ \$hit = 'NO' ] ; then
        echo $ToRun @PgmArgs \\< $PgmStdinFile
        echo expected stdout not matched by reality
-       ${CONTEXT_DIFF} $PgmStdoutFile[0] $TmpPrefix/runtest$$.1
-       myexit=1
+       orig_file="$PgmStdoutFile[0]";
+       [ ! -f \$orig_file ] && orig_file="/dev/null"
+       ${CONTEXT_DIFF} \$orig_file $TmpPrefix/runtest$$.1
+       myexit=\$?
        diffsShown=1
     fi
-    if [ $SaveTmpFile = 1 ] && [ \$progexit = $PgmExitStatus ] ; then
-       rm -f $PgmStdoutFile[0].bak
+    if [ $SaveStdout = 1 ] && 
+       [ $PgmStdoutFile[0] != $DefaultStdoutFile ] && [ -s $TmpPrefix/runtest$$.1 ]; then
        echo Saving away stdout output in $PgmStdoutFile[0] ...
-       cp $PgmStdoutFile[0] $PgmStdoutFile[0].bak
+       if [ -f $PgmStdoutFile[0] ]; then
+            rm -f $PgmStdoutFile[0].bak
+            cp $PgmStdoutFile[0] $PgmStdoutFile[0].bak
+       fi;
        cp $TmpPrefix/runtest$$.1 $PgmStdoutFile[0]
     fi
 fi
@@ -264,23 +242,21 @@ done
 if [ \$hit = 'NO' ] ; then
     echo $ToRun @PgmArgs \\< $PgmStdinFile
     echo expected stderr not matched by reality
-    ${CONTEXT_DIFF} $PgmStderrFile[0] $TmpPrefix/runtest$$.2
-    myexit=1
+    orig_file="$PgmStderrFile[0]"
+    [ ! -f \$orig_file ] && orig_file="/dev/null"
+    ${CONTEXT_DIFF} \$orig_file $TmpPrefix/runtest$$.2
+    myexit=\$?
     diffsShown=1
 fi
-if [ $SaveTmpFile = 1 ] && [ \$progexit = $PgmExitStatus ] ; then
-       rm -f $PgmStderrFile[0].bak
+if [ $SaveStderr = 1 ] &&
+   [ $PgmStderrFile[0] != $DefaultStderrFile ] && [ -s $TmpPrefix/runtest$$.2 ]; then
        echo Saving away stderr output in $PgmStderrFile[0] ...
-       cp $PgmStderrFile[0] $PgmStderrFile[0].bak
+       if [ -f $PgmStderrFile[0] ]; then
+          rm -f $PgmStderrFile[0].bak
+          cp $PgmStderrFile[0] $PgmStderrFile[0].bak
+       fi;
        cp $TmpPrefix/runtest$$.2 $PgmStderrFile[0]
 fi
-$SpixstatsLine1
-
-if [ $SpixTiming = 'yes' -a \$myexit = 0 ] ; then
-    $SpixifyLine2
-    $TimeCmd /bin/sh -c \'$ToRun $TimingMagic @PgmArgs < $PgmStdinFile 1> /dev/null 2> /dev/null 3> $TmpPrefix/runtest$$.3\'
-    $SpixstatsLine2
-fi
 
 ${RM} core $ToRunOrig.spix $DefaultStdoutFile $DefaultStderrFile $TmpPrefix/runtest$$.1 $TmpPrefix/runtest$$.2 $TmpPrefix/runtest$$.3
 exit \$myexit
@@ -303,18 +279,16 @@ if ( $SysSpecificTiming eq '' ) {
 }
 
 &process_stats_file();
-&process_spixstats_files() if $SpixTiming eq 'yes';
+&process_cacheprof_files() if $CacheProf eq 'yes';
 
 # print out what we found
-if ( $SpixTiming ne 'yes' ) {
-    print STDERR "<<$SysSpecificTiming: ",
-       "$BytesAlloc bytes, $GCs GCs, $AvgResidency/$MaxResidency avg/max bytes residency ($ResidencySamples samples), $InitTime INIT ($InitElapsed elapsed), $MutTime MUT ($MutElapsed elapsed), $GcTime GC ($GcElapsed elapsed)",
-       " :$SysSpecificTiming>>\n";
+print STDERR "<<$SysSpecificTiming: ";
+if ( $CacheProf ne 'yes' ) {
+       print STDERR "$BytesAlloc bytes, $GCs GCs, $AvgResidency/$MaxResidency avg/max bytes residency ($ResidencySamples samples), $GCWork bytes GC work, ${TotMem}M in use, $InitTime INIT ($InitElapsed elapsed), $MutTime MUT ($MutElapsed elapsed), $GcTime GC ($GcElapsed elapsed)";
 } else {
-    print STDERR "<<$SysSpecificTiming: ",
-       "$BytesAlloc bytes, $GCs GCs, $AvgResidency/$MaxResidency avg/max bytes residency ($ResidencySamples samples), $TotalInsns[1]/$TotalInsns[2] instructions, $LoadInsns[1]/$LoadInsns[2] loads, $StoreInsns[1]/$StoreInsns[2] stores, $BranchInsns[1]/$BranchInsns[2] branches, $OtherInsns[1]/$OtherInsns[2] others",
-       " :$SysSpecificTiming>>\n";
-}
+       print STDERR "$BytesAlloc bytes, $GCs GCs, $AvgResidency/$MaxResidency avg/max bytes residency ($ResidencySamples samples), $GCWork bytes GC work, ${TotMem}M in use, $InitTime INIT ($InitElapsed elapsed), $MutTime MUT ($MutElapsed elapsed), $GcTime GC ($GcElapsed elapsed), $TotInstrs instructions, $TotReads memory reads, $TotWrites memory writes";
+};
+print STDERR " :$SysSpecificTiming>>\n";
 
 # OK, party over
 unlink $StatsFile;
@@ -371,25 +345,30 @@ sub process_stats_file {
        local($tot_samples) = 0;
 
        while (<STATS>) {
-           if (! /Minor/ && /^\s*\d+\s+\d+\s+(\d+)\s+\d+\.\d+\%/ ) {
+           if (! /Gen:\s+0/ && /^\s*\d+\s+\d+\s+(\d+)\s+\d+\.\d+/ ) {
                $max_live = $1 if $max_live < $1;
                $tot_live += $1;
                $tot_samples += 1;
            }
 
            $BytesAlloc = $1 if /^\s*([0-9,]+) bytes allocated in the heap/;
+           $GCWork = $1     if /^\s*([0-9,]+) bytes copied during GC/;
 
 #          if ( /^\s*([0-9,]+) bytes maximum residency .* (\d+) sample/ ) {
 #              $MaxResidency = $1; $ResidencySamples = $2;
 #          }
 
-           $GCs = $1 if /^\s*([0-9,]+) garbage collections? performed/;
+           $GCs = $1 if /^\s*([0-9,]+) collections? in generation 0/;
 
-           if ( /^\s*INIT\s+time\s*(\d+\.\d\d)s\s*\(\s*(\d+\.\d\d)s elapsed\)/ ) {
+           if ( /^\s+([0-9]+)\s+Mb total memory/ ) {
+               $TotMem = $1;
+           }
+
+           if ( /^\s*INIT\s+time\s*(-*\d+\.\d\d)s\s*\(\s*(-*\d+\.\d\d)s elapsed\)/ ) {
                $InitTime = $1; $InitElapsed = $2;
-           } elsif ( /^\s*MUT\s+time\s*(\d+\.\d\d)s\s*\(\s*(\d+\.\d\d)s elapsed\)/ ) {
+           } elsif ( /^\s*MUT\s+time\s*(-*\d+\.\d\d)s\s*\(\s*(-*\d+\.\d\d)s elapsed\)/ ) {
                $MutTime = $1; $MutElapsed = $2;
-           } elsif ( /^\s*GC\s+time\s*(\d+\.\d\d)s\s*\(\s*(\d+\.\d\d)s elapsed\)/ ) {
+           } elsif ( /^\s*GC\s+time\s*(-*\d+\.\d\d)s\s*\(\s*(-*\d+\.\d\d)s elapsed\)/ ) {
                $GcTime = $1; $GcElapsed = $2;
            }
        }
@@ -433,6 +412,8 @@ sub process_stats_file {
     print STDERR "Warning: MutElapsed not found in stats file\n" unless defined($MutElapsed);
     print STDERR "Warning: GcTime inot found in stats file\n" unless defined($GcTime);
     print STDERR "Warning: GcElapsed not found in stats file\n" unless defined($GcElapsed);
+    print STDERR "Warning: total memory not found in stats file\n" unless defined($TotMem);
+    print STDERR "Warning: GC work not found in stats file\n" unless defined($GCWork);
 
     # things we didn't necessarily expect to find
     $MaxResidency     = 0 unless defined($MaxResidency);
@@ -441,6 +422,7 @@ sub process_stats_file {
 
     # a bit of tidying
     $BytesAlloc =~ s/,//g;
+    $GCWork =~ s/,//g;
     $MaxResidency =~ s/,//g;
     $GCs =~ s/,//g;
     $InitTime =~ s/,//g;
@@ -451,47 +433,20 @@ sub process_stats_file {
     $GcElapsed =~ s/,//g;
 }
 
-sub process_spixstats_files { # 2 of them; one for mutator, one for GC
-
-    @TotalInsns = ();
-    @LoadInsns  = ();
-    @StoreInsns = ();
-    @BranchInsns= ();
-    @OtherInsns = ();
-
-    foreach $f (1, 2) {
+sub process_cacheprof_files {
 
-      open(STATS, "< $ToRunOrig.spixstats$f") || die "Failed when opening $ToRunOrig.spixstats$f\n";
-      while (<STATS>) {
-         last if /^OPCODES \(STATIC\):/; # party over
+    open(STATS, "< $CacheProfStats") || die("Can't open $CacheProfStats\n");
 
-         next if /^OPCODES \(DYNAMIC\):/;
-         next if /^$/;
-         next if /^opcode\s+#executed/;
-         next if /^SUBTOTAL/;
-
-         if ( /^ld\S*\s+(\d+)/ ) {
-             $LoadInsns[$f] += $1;
-
-         } elsif ( /^st\S*\s+(\d+)/ ) {
-             $StoreInsns[$f] += $1;
-
-         } elsif ( /^(jmpl|call|b\S*)\s+(\d+)/ ) {
-             $BranchInsns[$f] += $2;
-
-         } elsif ( /^TOTAL\s+(\d+)/ ) {
-             $TotalInsns[$f] = $1;
-             print STDERR "TotalInsns doesn't match categories total!\n"
-                 if $TotalInsns[$f] !=
-                    ($LoadInsns[$f] + $StoreInsns[$f] + $BranchInsns[$f] + $OtherInsns[$f]);
-
-         } elsif ( /^\S+\s+(\d+)/ ) {
-             $OtherInsns[$f] += $1;
-
-         } else {
-             die "Funny line?? $_";
-         }
+    # the format of the info in this file is:
+    #    OTHER(intrs,reads,writes,read-misses,write-misses)
+    # where read-misses and write-misses will both be zero if we're
+    # just counting instructions.
+    while (<STATS>) {
+       /OTHER\(\s*([0-9]+),\s*([0-9]+),\s*([0-9]+),\s*([0-9]+),\s*([0-9]+)\)/ && do {
+          $TotInstrs = $1;
+          $TotReads  = $2;
+          $TotWrites = $3;
       }
-      close(STATS) || die "Failed when closing $ToRunOrig.spixstats\n";
-    }
+  }
+  close(STATS);
 }