| #! /usr/bin/env perl |
| # Copyright (c) 2003-2007 The Regents of The University of Michigan |
| # All rights reserved. |
| # |
| # Redistribution and use in source and binary forms, with or without |
| # modification, are permitted provided that the following conditions are |
| # met: redistributions of source code must retain the above copyright |
| # notice, this list of conditions and the following disclaimer; |
| # redistributions in binary form must reproduce the above copyright |
| # notice, this list of conditions and the following disclaimer in the |
| # documentation and/or other materials provided with the distribution; |
| # neither the name of the copyright holders nor the names of its |
| # contributors may be used to endorse or promote products derived from |
| # this software without specific prior written permission. |
| # |
| # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| # |
| # Authors: Steve Reinhardt |
| |
| # Script to simplify using rundiff on trace outputs from two |
| # invocations of m5. Takes a common m5 command line with embedded |
| # alternatives and executes the two alternative commands in separate |
| # subdirectories with output piped to rundiff. |
| # |
| # ******Note that you need to enable some trace flags in the args in order |
| # to do anything useful!****** |
| # |
| # Script arguments are handled uniformly as follows: |
| # - If the argument does not contain a '|' character, it is appended |
| # to both command lines. |
| # - If the argument has a '|' character in it, the text on either side |
| # of the '|' is appended to the respective command lines. Note that |
| # you'll have to quote the arg or escape the '|' with a backslash |
| # so that the shell doesn't think you're doing a pipe. |
| # - Arguments with '#' characters are split at those characters, |
| # processed for alternatives ('|'s) as independent terms, then |
| # pasted back into a single argument (without the '#'s). (Sort of |
| # inspired by the C preprocessor '##' token pasting operator.) |
| # |
| # In other words, the arguments should look like the command line you |
| # want to run, with "|" used to list the alternatives for the parts |
| # that you want to differ between the two runs. |
| # |
| # For example: |
| # |
| # % tracediff m5.opt --opt1 '--opt2|--opt3' --opt4 |
| # would compare these two runs: |
| # m5.opt --opt1 --opt2 --opt4 |
| # m5.opt --opt1 --opt3 --opt4 |
| # |
| # % tracediff 'path1|path2#/m5.opt' --opt1 --opt2 |
| # would compare these two runs: |
| # path1/m5.opt --opt1 --opt2 |
| # path2/m5.opt --opt1 --opt2 |
| # |
| # If you want to add arguments to one run only, just put a '|' in with |
| # text only on one side ('--onlyOn1|'). You can do this with multiple |
| # arguments together too ('|-a -b -c' adds three args to the second |
| # run only). |
| # |
| # The '-n' argument to tracediff allows you to preview the two |
| # generated command lines without running them. |
| # |
| |
| use FindBin; |
| |
| $dryrun = 0; |
| |
| if (@ARGV >= 1 && $ARGV[0] eq '-n') { |
| $dryrun = 1; |
| shift @ARGV; |
| } |
| |
| if (@ARGV < 1) { |
| die "Usage: tracediff [-n] \"sim1|sim2\" [common-arg \"arg1|arg2\" ...]\n"; |
| } |
| |
| foreach $arg (@ARGV) { |
| $a1 = $a2 = ''; |
| @subargs = split('#', $arg); |
| foreach $subarg (@subargs) { |
| if ($subarg eq '') { |
| next; |
| } |
| @pair = split('\|', $subarg, -1); # -1 enables null trailing fields |
| if (@pair == 1) { |
| $a1 .= $subarg; |
| $a2 .= $subarg; |
| } elsif (@pair == 2) { |
| $a1 .= $pair[0]; |
| $a2 .= $pair[1]; |
| } else { |
| print 'Parse error: too many |s in ', $arg, "\n"; |
| exit(1); |
| } |
| } |
| |
| push @cmd1, $a1; |
| push @cmd2, $a2; |
| } |
| |
| |
| if ($dryrun) { |
| print "CMD1: ", join(' ', @cmd1), "\n"; |
| print "CMD2: ", join(' ', @cmd2), "\n"; |
| exit(0); |
| } |
| |
| # First two args are the two simulator binaries to compare |
| $sim1 = shift @cmd1; |
| $sim2 = shift @cmd2; |
| |
| # Everything else is a simulator arg. |
| $args1 = join(' ', @cmd1); |
| $args2 = join(' ', @cmd2); |
| |
| # Common mistake: if you don't set any debugflags this often isn't |
| # doing what you want. |
| if ($args1 !~ /--debug-flags/) { |
| print "****\n"; |
| print "**** WARNING: no debug flags set... you may not be diffing much!\n"; |
| print "****\n"; |
| } |
| |
| # Run individual invocations in separate dirs so output and intermediate |
| # files (particularly config.py and config.ini) don't conflict. |
| $dir1 = "tracediff-$$-1"; |
| $dir2 = "tracediff-$$-2"; |
| mkdir($dir1) or die "Can't create dir $dir1\n"; |
| mkdir($dir2) or die "Can't create dir $dir2\n"; |
| |
| $cmd1 = "$sim1 -d $dir1 $args1 2>&1 |"; |
| $cmd2 = "$sim2 -d $dir2 $args2 2>&1 |"; |
| |
| # Expect that rundiff is in the same dir as the tracediff script. |
| # FindBin figures that out for us. |
| $fullcmd = "$FindBin::Bin/rundiff '$cmd1' '$cmd2' 2>&1 > tracediff-$$.out"; |
| |
| print "Executing $fullcmd\n"; |
| system($fullcmd); |
| |
| |
| |