Reid Spencer | 33c9683 | 2006-12-11 17:42:12 +0000 | [diff] [blame] | 1 | #!/bin/bash |
| 2 | # |
| 3 | # findoptdiff |
| 4 | # |
| 5 | # This script helps find the optimization difference between two llvm |
| 6 | # builds. It is useful when you have a build that is known to work and |
| 7 | # one that exhibits an optimization problem. Identifying the difference |
| 8 | # between the two builds can lead to discovery of the source of a |
| 9 | # mis-optimization. |
| 10 | # |
| 11 | # The script takes two llvm build paths as arguments. These specify the |
| 12 | # the two llvm builds to compare. It is generally expected that they |
| 13 | # are "close cousins". That is, they are the same except that the |
| 14 | # second build contains some experimental optimization features that |
| 15 | # are suspected of producing a misoptimization. |
| 16 | # |
Duncan Sands | 18d52f2 | 2010-09-29 20:09:55 +0000 | [diff] [blame^] | 17 | # The script takes two bitcode files, one from each build. They are |
Reid Spencer | 33c9683 | 2006-12-11 17:42:12 +0000 | [diff] [blame] | 18 | # presumed to be a compilation of the same program or program fragment |
| 19 | # with the only difference being the builds. |
| 20 | # |
| 21 | # The script operates by iteratively applying the optimizations that gccas |
| 22 | # and gccld run until there is a difference in the assembly resulting |
| 23 | # from the optimization. The difference is then reported with the set of |
Reid Spencer | b1788a3 | 2006-12-18 00:37:37 +0000 | [diff] [blame] | 24 | # optimization passes that produce the difference. The processing |
| 25 | # continues until all optimization passes have been tried. The differences |
| 26 | # for each pass, if they do differ, are placed in a diffs.# file. |
Reid Spencer | 33c9683 | 2006-12-11 17:42:12 +0000 | [diff] [blame] | 27 | # |
| 28 | # To work around differences in the assembly language format, the script |
| 29 | # can also take two filter arguments that post-process the assembly |
| 30 | # so they can be differenced without making false positives for known |
| 31 | # differences in the two builds. These filters are optional. |
| 32 | # |
| 33 | # Usage: |
| 34 | # findoptdiff llvm1 llvm2 bc1 bc2 filter1 filter2 |
| 35 | # |
| 36 | # Where: |
| 37 | # llvm1 |
| 38 | # is the path to the first llvm build dir |
| 39 | # llvm2 |
| 40 | # is the path to the second llvm build dir |
| 41 | # bc1 |
Duncan Sands | 18d52f2 | 2010-09-29 20:09:55 +0000 | [diff] [blame^] | 42 | # is the bitcode file for the first llvm environment |
Reid Spencer | 33c9683 | 2006-12-11 17:42:12 +0000 | [diff] [blame] | 43 | # bc2 |
Duncan Sands | 18d52f2 | 2010-09-29 20:09:55 +0000 | [diff] [blame^] | 44 | # is the bitcode file for the second llvm environment |
Reid Spencer | 33c9683 | 2006-12-11 17:42:12 +0000 | [diff] [blame] | 45 | # filter1 |
| 46 | # is an optional filter for filtering the llvm1 generated assembly |
| 47 | # filter2 |
| 48 | # is an optional filter for filtering the llvm2 generated assembly |
| 49 | # |
| 50 | llvm1=$1 |
| 51 | llvm2=$2 |
| 52 | bc1=$3 |
| 53 | bc2=$4 |
| 54 | filt1=$5 |
Reid Spencer | b1788a3 | 2006-12-18 00:37:37 +0000 | [diff] [blame] | 55 | filt2=$6 |
Reid Spencer | 33c9683 | 2006-12-11 17:42:12 +0000 | [diff] [blame] | 56 | if [ -z "$filt1" ] ; then |
| 57 | filt1="cat" |
| 58 | fi |
Reid Spencer | 33c9683 | 2006-12-11 17:42:12 +0000 | [diff] [blame] | 59 | if [ -z "$filt2" ] ; then |
| 60 | filt2="cat" |
| 61 | fi |
Reid Spencer | b1788a3 | 2006-12-18 00:37:37 +0000 | [diff] [blame] | 62 | opt1="${bc1}.opt" |
| 63 | opt2="${bc2}.opt" |
| 64 | ll1="${bc1}.ll" |
| 65 | ll2="${bc2}.ll" |
| 66 | opt1ll="${bc1}.opt.ll" |
| 67 | opt2ll="${bc2}.opt.ll" |
| 68 | dis1="$llvm1/Debug/bin/llvm-dis" |
| 69 | dis2="$llvm2/Debug/bin/llvm-dis" |
| 70 | opt1="$llvm1/Debug/bin/opt" |
| 71 | opt2="$llvm2/Debug/bin/opt" |
Reid Spencer | 33c9683 | 2006-12-11 17:42:12 +0000 | [diff] [blame] | 72 | |
Victor Hernandez | 66284e0 | 2009-10-24 04:23:03 +0000 | [diff] [blame] | 73 | all_switches="-verify -lowersetjmp -simplifycfg -mem2reg -globalopt -globaldce -ipconstprop -deadargelim -instcombine -simplifycfg -prune-eh -inline -simplify-libcalls -argpromotion -tailduplicate -simplifycfg -scalarrepl -instcombine -predsimplify -condprop -tailcallelim -simplifycfg -reassociate -licm -loop-unswitch -instcombine -indvars -loop-unroll -instcombine -load-vn -gcse -sccp -instcombine -condprop -dse -dce -simplifycfg -deadtypeelim -constmerge -internalize -ipsccp -globalopt -constmerge -deadargelim -inline -prune-eh -globalopt -globaldce -argpromotion -instcombine -predsimplify -scalarrepl -globalsmodref-aa -licm -load-vn -gcse -dse -instcombine -simplifycfg -verify" |
Reid Spencer | 33c9683 | 2006-12-11 17:42:12 +0000 | [diff] [blame] | 74 | |
Reid Spencer | b1788a3 | 2006-12-18 00:37:37 +0000 | [diff] [blame] | 75 | #counter=0 |
Reid Spencer | 33c9683 | 2006-12-11 17:42:12 +0000 | [diff] [blame] | 76 | function tryit { |
| 77 | switches_to_use="$1" |
Reid Spencer | b1788a3 | 2006-12-18 00:37:37 +0000 | [diff] [blame] | 78 | $opt1 $switches_to_use "$bc1" -o - | $dis1 | $filt1 > "$opt1ll" |
| 79 | $opt2 $switches_to_use "$bc2" -o - | $dis2 | $filt2 > "$opt2ll" |
| 80 | diffs="diffs."$((counter++)) |
| 81 | diff "$opt1ll" "$opt2ll" > $diffs |
Reid Spencer | 33c9683 | 2006-12-11 17:42:12 +0000 | [diff] [blame] | 82 | if [ $? -ne 0 ] ; then |
| 83 | echo |
| 84 | echo "Diff fails with these switches:" |
| 85 | echo $switches |
| 86 | echo "Differences:" |
Reid Spencer | b1788a3 | 2006-12-18 00:37:37 +0000 | [diff] [blame] | 87 | head $diffs |
| 88 | echo 'Switches:' $switches_to_use >> $diffs |
| 89 | else |
| 90 | rm $diffs |
Reid Spencer | 33c9683 | 2006-12-11 17:42:12 +0000 | [diff] [blame] | 91 | fi |
| 92 | return 1 |
| 93 | } |
| 94 | |
| 95 | for sw in $all_switches ; do |
| 96 | echo -n " $sw" |
| 97 | switches="$switches $sw" |
| 98 | if tryit "$switches" ; then |
| 99 | break; |
| 100 | fi |
| 101 | done |