1#!/bin/bash 2# 3# findmisopt 4# 5# This is a quick and dirty hack to potentially find a misoptimization 6# problem. Mostly its to work around problems in bugpoint that prevent 7# it from finding a problem unless the set of failing optimizations are 8# known and given to it on the command line. 9# 10# Given a bytecode file that produces correct output (or return code), 11# this script will run through all the optimizations passes that gccas 12# uses (in the same order) and will narrow down which optimizations 13# cause the program either generate different output or return a 14# different result code. When the passes have been narrowed down, 15# bugpoint is invoked to further refine the problem to its origin. 16# 17# Usage: 18# findmisopt bcfile outdir progargs [match] 19# 20# Where: 21# bcfile 22# is the bytecode file input (the unoptimized working case) 23# outdir 24# is a directory into which intermediate results are placed 25# progargs 26# is a single argument containing all the arguments the program needs 27# match 28# if specified to any value causes the result code of the program to 29# be used to determine success/fail. If not specified success/fail is 30# determined by diffing the program's output with the non-optimized 31# output. 32# 33if [ "$#" -lt 3 ] ; then 34 echo "usage: findmisopt bcfile outdir progargs [match]" 35 exit 1 36fi 37 38bcfile="$1" 39outdir="$2" 40args="$3" 41match="$4" 42name=`basename $bcfile .bc` 43ll="$outdir/${name}.ll" 44s="$outdir/${name}.s" 45prog="$outdir/${name}" 46out="$outdir/${name}.out" 47optbc="$outdir/${name}.opt.bc" 48optll="$outdir/${name}.opt.ll" 49opts="$outdir/${name}.opt.s" 50optprog="$outdir/${name}.opt" 51optout="$outdir/${name}.opt.out" 52 53echo "Test Name: $name" 54echo "Unoptimized program: $prog" 55echo " Optimized program: $optprog" 56 57 58# Generate the disassembly 59llvm-dis "$bcfile" -o "$ll" -f || exit 1 60 61# Generate the non-optimized program 62llc "$bcfile" -o "$s" -f || exit 1 63gcc "$s" -o "$prog" -lstdc++ -lc -lm || exit 1 64 65# Define the list of optimizations to run 66all_switches="-verify -lowersetjmp -funcresolve -raiseallocs -simplifycfg -mem2reg -globalopt -globaldce -ipconstprop -deadargelim -instcombine -simplifycfg -prune-eh -inline -simplify-libcalls -argpromotion -raise -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" 67 68# Current set of switches is empty 69function tryit { 70 switches_to_use="$1" 71 opt $switches_to_use "$bcfile" -o "$optbc" -f || exit 72 llvm-dis "$optbc" -o "$optll" -f || exit 73 llc "$optbc" -o "$opts" -f || exit 74 gcc "$opts" -o "$optprog" -lstdc++ -lc -lm || exit 75 "$prog" $args > "$out" 76 ex1=$? 77 "$optprog" $args > "$optout" 78 ex2=$? 79 80 if [ -n "$match" ] ; then 81 if [ "$ex1" -ne "$ex2" ] ; then 82 echo "Return code not the same with these switches:" 83 echo $switches 84 echo "Unoptimized returned: $ex1" 85 echo "Optimized returned: $ex2" 86 return 0 87 fi 88 else 89 diff "$out" "$optout" > /dev/null 90 if [ $? -ne 0 ] ; then 91 echo "Diff fails with these switches:" 92 echo $switches 93 echo "Differences:" 94 diff "$out" "$optout" 95 return 0; 96 fi 97 fi 98 return 1 99} 100 101for sw in $all_switches ; do 102 switches="$switches $sw" 103 if tryit "$switches" ; then 104 break; 105 fi 106done 107 108final="" 109while [ ! -z "$switches" ] ; do 110 trimmed=`echo "$switches" | sed -e 's/^ *\(-[^ ]*\).*/\1/'` 111 switches=`echo "$switches" | sed -e 's/^ *-[^ ]* *//'` 112 echo "Trimmed $trimmed from left" 113 tryit "$final $switches" 114 if [ "$?" -eq "0" ] ; then 115 echo "Still Failing .. continuing ..." 116 continue 117 else 118 echo "Found required early pass: $trimmed" 119 final="$final $trimmed" 120 continue 121 fi 122 echo "Next Loop" 123done 124 125if [ "$final" == " $all_switches" ] ; then 126 echo "findmisopt: Can't find a set of optimizations that make it fail" 127 exit 0 128fi 129echo "Smallest Optimization list=$final" 130bpcmd="bugpoint -run-llc --output "$out" --input /dev/null $bcfile $final --args $args" 131 132echo "Running: $bpcmd" 133$bpcmd 134echo "findmisopt finished." 135