brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.0 KiB · 2405220 Raw
178 lines · plain
1#!/bin/bash2#3#  findmisopt4#5#      This is a quick and dirty hack to potentially find a misoptimization6#      problem. Mostly its to work around problems in bugpoint that prevent7#      it from finding a problem unless the set of failing optimizations are8#      known and given to it on the command line.9#10#      Given a bitcode file that produces correct output (or return code), 11#      this script will run through all the optimizations passes that gccas12#      uses (in the same order) and will narrow down which optimizations13#      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. If a16#      release version of bugpoint is available it will be used, otherwise 17#      debug.18#19#   Usage:20#      findmisopt bcfile outdir progargs [match]21#22#   Where:23#      bcfile 24#          is the bitcode file input (the unoptimized working case)25#      outdir26#          is a directory into which intermediate results are placed27#      progargs28#          is a single argument containing all the arguments the program needs29#      proginput30#          is a file name from which stdin should be directed31#      match32#          if specified to any value causes the result code of the program to33#          be used to determine success/fail. If not specified success/fail is34#          determined by diffing the program's output with the non-optimized35#          output.36#       37if [ "$#" -lt 3 ] ; then38  echo "usage: findmisopt bcfile outdir progargs [match]"39  exit 140fi41 42dir="${0%%/utils/findmisopt}"43if [ -x "$dir/Release/bin/bugpoint" ] ; then44  bugpoint="$dir/Release/bin/bugpoint"45elif [ -x "$dir/Debug/bin/bugpoint" ] ; then46  bugpoint="$dir/Debug/bin/bugpoint"47else48  echo "findmisopt: bugpoint not found"49  exit 150fi51 52bcfile="$1"53outdir="$2"54args="$3"55input="$4"56if [ ! -f "$input" ] ; then57  input="/dev/null"58fi59match="$5"60name=`basename $bcfile .bc`61ll="$outdir/${name}.ll"62s="$outdir/${name}.s"63prog="$outdir/${name}"64out="$outdir/${name}.out"65optbc="$outdir/${name}.opt.bc"66optll="$outdir/${name}.opt.ll"67opts="$outdir/${name}.opt.s"68optprog="$outdir/${name}.opt"69optout="$outdir/${name}.opt.out"70ldflags="-lstdc++ -lm -ldl -lc"71 72echo "Test Name: $name"73echo "Unoptimized program: $prog"74echo "  Optimized program: $optprog"75 76# Define the list of optimizations to run. This comprises the same set of 77# optimizations that opt -O3 runs, in the same order.78opt_switches=`llvm-as < /dev/null -o - | opt -O3 -disable-output -debug-pass=Arguments 2>&1 | sed 's/Pass Arguments: //'`79all_switches="$opt_switches"80echo "Passes : $all_switches"81 82# Create output directory if it doesn't exist83if [ -f "$outdir" ] ; then84  echo "$outdir is not a directory"85  exit 186fi87 88if [ ! -d "$outdir" ] ; then89  mkdir "$outdir" || exit 190fi91 92# Generate the disassembly93llvm-dis "$bcfile" -o "$ll" -f || exit 194 95# Generate the non-optimized program and its output96llc "$bcfile" -o "$s" -f || exit 197gcc "$s" -o "$prog" $ldflags || exit 198"$prog" $args > "$out" 2>&1 <$input99ex1=$?100 101# Current set of switches is empty102function tryit {103  switches_to_use="$1"104  opt $switches_to_use "$bcfile" -o "$optbc" -f || exit105  llvm-dis "$optbc" -o "$optll" -f || exit106  llc "$optbc" -o "$opts" -f || exit107  gcc "$opts" -o "$optprog" $ldflags || exit108  "$optprog" $args > "$optout" 2>&1 <"$input"109  ex2=$?110 111  if [ -n "$match" ] ; then112    if [ "$ex1" -ne "$ex2" ] ; then113      echo "Return code not the same with these switches:"114      echo $switches115      echo "Unoptimized returned: $ex1"116      echo "Optimized   returned: $ex2"117      return 0118    fi119  else120    diff "$out" "$optout" > /dev/null121    if [ $? -ne 0 ] ; then122      echo "Diff fails with these switches:"123      echo $switches124      echo "Differences:"125      diff "$out" "$optout" | head126      return 0;127    fi128  fi129  return 1130}131 132echo "Trying to find optimization that breaks program:"133for sw in $all_switches ; do134  echo -n " $sw"135  switches="$switches $sw"136  if tryit "$switches" ; then137    break;138  fi139done140 141# Terminate the previous output with a newline142echo ""143 144# Determine if we're done because none of the optimizations broke the program145if [ "$switches" == " $all_switches" ] ; then146  echo "The program did not miscompile"147  exit 0148fi149 150final=""151while [ ! -z "$switches" ] ; do152  trimmed=`echo "$switches" | sed -e 's/^ *\(-[^ ]*\).*/\1/'`153  switches=`echo "$switches" | sed -e 's/^ *-[^ ]* *//'`154  echo "Trimmed $trimmed from left"155  tryit "$final $switches"156  if [ "$?" -eq "0" ] ; then157    echo "Still Failing .. continuing ..."158    continue159  else160    echo "Found required early pass: $trimmed"161    final="$final $trimmed"162    continue163  fi164  echo "Next Loop"165done166 167if [ "$final" == " $all_switches" ] ; then168  echo "findmisopt: All optimizations pass. Perhaps this isn't a misopt?"169  exit 0170fi171echo "Smallest Optimization list=$final"172 173bpcmd="$bugpoint -run-llc -disable-loop-extraction --output "$out" --input /dev/null $bcfile $final --args $args"174 175echo "Running: $bpcmd"176$bpcmd177echo "findmisopt finished."178