X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=glafp-utils%2Frunstdtest%2Frunstdtest.prl;h=1397ac43e0bf6531e053c35d43bdf51637d39f1c;hb=460af126b2b18c68dc2f7b2ba7b493d864ff91bf;hp=f66943ea871ff525e8af19de6fb4c169f98da726;hpb=f1ab58e563bc183b05c94dae2a528209f80f02f7;p=ghc-hetmet.git diff --git a/glafp-utils/runstdtest/runstdtest.prl b/glafp-utils/runstdtest/runstdtest.prl index f66943e..1397ac4 100644 --- a/glafp-utils/runstdtest/runstdtest.prl +++ b/glafp-utils/runstdtest/runstdtest.prl @@ -2,7 +2,7 @@ # The perl script requires the following variables to be bound # to something meaningful before it will operate correctly: # -# TMPDIR +# DEFAULT_TMPDIR # CONTEXT_DIFF # RM # @@ -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 ) [default: /dev/null ] # * a "time" command to use (-t ). # @@ -34,18 +34,32 @@ # # (This is supposed to be a "prettier" replacement for runstdtest.) # +# Flags +# ~~~~~ +# -accept-output replace output files with the ones actually generated by running +# the program +# ($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 $TmpPrefix = $ENV{'TMPDIR'}; } else { - $TmpPrefix ="$TMPDIR"; - $ENV{'TMPDIR'} = "$TMPDIR"; # set the env var as well + $TmpPrefix ="$DEFAULT_TMPDIR"; + $ENV{'TMPDIR'} = "$DEFAULT_TMPDIR"; # set the env var as well +} +# If this is Cygwin, ignore eol and CR characters. +# Perhaps required for MSYS too, although the cygpath +# bit is hopefully unnecessary. +if ( `uname | grep CYGWIN` ) { + $CONTEXT_DIFF=$CONTEXT_DIFF . " --strip-trailing-cr" ; + $TmpPrefix = `cygpath -m $TmpPrefix | tr -d \\\\n`; } $ScriptFile = "$TmpPrefix/run_me$$"; $DefaultStdoutFile = "$TmpPrefix/no_stdout$$"; # can't use /dev/null (e.g. Alphas) @@ -56,13 +70,14 @@ $PreScript = ''; $PostScript = ''; $TimeCmd = ''; $StatsFile = "$TmpPrefix/stats$$"; +$CachegrindStats = "cachegrind.out.summary"; $SysSpecificTiming = ''; -$SpixTiming = 'no'; +$Cachegrind = 'no'; die "$Pgm: program to run not given as first argument\n" if $#ARGV < 0; $ToRun = $ARGV[0]; shift(@ARGV); # avoid picking up same-named thing from somewhere else on $PATH... -$ToRun = "./$ToRun" if $ToRun !~ /^\//; +$ToRun = "./$ToRun" if -e "./$ToRun"; arg: while ($_ = $ARGV[0]) { shift(@ARGV); @@ -72,14 +87,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" @@ -100,9 +118,9 @@ arg: while ($_ = $ARGV[0]) { next arg; }; /^-(ghc|hbc)-timing$/ && do { $SysSpecificTiming = $1; next arg; }; - /^-spix-timing$/ && do { $SysSpecificTiming = 'ghcspix'; - $SpixTiming = 'yes'; - next arg; }; + /^-cachegrind$/ && do { $SysSpecificTiming = 'ghc-instrs'; + $Cachegrind = 'yes'; + next arg }; /^-t(.*)/ && do { $TimeCmd = &grab_arg_arg('-t', $1); next arg; }; # anything else is taken to be a pgm arg @@ -110,17 +128,17 @@ arg: while ($_ = $ARGV[0]) { } foreach $out_file ( @PgmStdoutFile ) { - #$Status++ , - pop(@PgmStdoutFile), - print STDERR "$Pgm: warning: expected-output file missing: $out_file\n" - if ! -f $out_file; + if ( ! -f $out_file && !$SaveStdout ) { + print STDERR "$Pgm: warning: expected-stdout file missing: $out_file\n"; + pop(@PgmStdoutFile); + } } foreach $out_file ( @PgmStderrFile ) { - #$Status++, - pop(@PgmStderrFile), - print STDERR "$Pgm: warning: expected-stderr file missing: $out_file\n" - if ! -f $out_file; + if ( ! -f $out_file && !$SaveStderr ) { + print STDERR "$Pgm: warning: expected-stderr file missing: $out_file\n"; + pop(@PgmStderrFile); + } } exit 1 if $Status; @@ -131,12 +149,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 =~ /'/) { @@ -148,42 +166,15 @@ 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 () { - 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`; + $PreScriptLines =~ s/\r//g; } else { $PreScriptLines = ''; } @@ -191,6 +182,7 @@ if ($PreScript ne '') { if ($PostScript ne '') { local($to_do); $PostScriptLines = `cat $PostScript`; + $PostScriptLines =~ s/\r//g; $* = 1; $PostScriptLines =~ s#\$o1#$TmpPrefix/runtest$$.1#g; $PostScriptLines =~ s#\$o2#$TmpPrefix/runtest$$.2#g; @@ -200,6 +192,12 @@ if ($PostScript ne '') { # OK, so we're gonna do the normal thing... +if ($Cachegrind eq 'yes') { + $CachegrindPrefix = "valgrind --skin=cachegrind --logfile-fd=99 99>$CachegrindStats"; +} else { + $CachegrindPrefix = ''; +} + $Script = < $DefaultStdoutFile cat /dev/null > $DefaultStderrFile $PreScriptLines $SpixifyLine1 -$TimeCmd /bin/sh -c \'$ToRun $TimingMagic @PgmArgs < $PgmStdinFile 1> $TmpPrefix/runtest$$.1 2> $TmpPrefix/runtest$$.2 3> $TmpPrefix/runtest$$.3\' +echo $TimeCmd /bin/sh -c \'$CachegrindPrefix $ToRun $TimingMagic @PgmArgs < $PgmStdinFile 1> $TmpPrefix/runtest$$.1 2> $TmpPrefix/runtest$$.2 3> $TmpPrefix/runtest$$.3\' +$TimeCmd /bin/sh -c \'$CachegrindPrefix $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 exit status $PgmExitStatus not seen \\; got \$progexit + 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 else $PostScriptLines @@ -226,19 +230,22 @@ 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 -egrep -v '^ld\.so:.*has older revision than expected' < $TmpPrefix/runtest$$.2 > $TmpPrefix/runtest$$.2b -mv -f $TmpPrefix/runtest$$.2b $TmpPrefix/runtest$$.2 hit='NO' for out_file in @PgmStderrFile ; do @@ -249,23 +256,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 @@ -288,18 +293,16 @@ if ( $SysSpecificTiming eq '' ) { } &process_stats_file(); -&process_spixstats_files() if $SpixTiming eq 'yes'; +&process_cachegrind_files() if $Cachegrind 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 ( $Cachegrind 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, $TotMisses L2 cache misses"; +}; +print STDERR " :$SysSpecificTiming>>\n"; # OK, party over unlink $StatsFile; @@ -309,7 +312,7 @@ exit 0; sub grab_arg_arg { local($option, $rest_of_arg) = @_; - if ($rest_of_arg) { + if ($rest_of_arg ne "") { return($rest_of_arg); } elsif ($#ARGV >= 0) { local($temp) = $ARGV[0]; shift(@ARGV); @@ -356,25 +359,30 @@ sub process_stats_file { local($tot_samples) = 0; while () { - 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+([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\)/ ) { + 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; } } @@ -418,6 +426,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); @@ -426,6 +436,7 @@ sub process_stats_file { # a bit of tidying $BytesAlloc =~ s/,//g; + $GCWork =~ s/,//g; $MaxResidency =~ s/,//g; $GCs =~ s/,//g; $InitTime =~ s/,//g; @@ -436,47 +447,28 @@ sub process_stats_file { $GcElapsed =~ s/,//g; } -sub process_spixstats_files { # 2 of them; one for mutator, one for GC +sub process_cachegrind_files { - @TotalInsns = (); - @LoadInsns = (); - @StoreInsns = (); - @BranchInsns= (); - @OtherInsns = (); + open(STATS, "< $CachegrindStats") || die("Can't open $CachegrindStats\n"); - foreach $f (1, 2) { + while () { + /^==\d+==\s+I\s+refs:\s+([0-9,]*)/ && do { + $TotInstrs = $1; + $TotInstrs =~ s/,//g; + }; - open(STATS, "< $ToRunOrig.spixstats$f") || die "Failed when opening $ToRunOrig.spixstats$f\n"; - while () { - last if /^OPCODES \(STATIC\):/; # party over + /^==\d+==\s+D\s+refs:\s+[0-9,]+\s+\(([0-9,]+)\s+rd\s+\+\s+([0-9,]+)\s+wr/ && do { + $TotReads = $1; + $TotWrites = $2; + $TotReads =~ s/,//g; + $TotWrites =~ s/,//g; + }; - 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?? $_"; - } - } - close(STATS) || die "Failed when closing $ToRunOrig.spixstats\n"; + /^==\d+==\s+L2d\s+misses:\s+([0-9,]+)/ && do { + $TotMisses = $1; + $TotMisses =~ s/,//g; + }; } + close(STATS); } +