#!/bin/bash

rm -f bench.bin

if [ "$1" = "-new" ] ; then
	rm -fv cache.txt
elif [ "$1" != "-resume" ] ; then
	echo "Usage: $0 { -new | -resume } [ compiler ]"
	exit 1
fi

compiler=${2:-gcc}

declare -a options=()
did_new_tests=1

tryit() {
	thisval=$( egrep "^[0-9]+: $*\$" cache.txt 2> /dev/null | cut -f1 -d: )
	[ -z "$thisval" ] || return

	tmp=`mktemp`
	echo -e "\nTesting: $* ..."
	if ! $* *.c -o bench.bin &> $tmp || [ -s $tmp ]
	then
		cat $tmp ; rm $tmp ; thisval=0
		echo "Compiler returned an error!"
		echo "0: $*" >> cache.txt
		return
	fi
	if ! ./bench.bin > $tmp || [ ! -s $tmp ]
	then
		rm $tmp ; thisval=0
		echo "Benchmark returned an error!"
		echo "0: $*" >> cache.txt
		return
	fi
	thisval=$( cat $tmp )
	echo "$thisval: $*" >> cache.txt
	did_new_tests=1
	rm $tmp
}

try() {
	bestval=0 ; best=""
	for x ; do
		options[options_counter]="$x"
		tryit $compiler ${options[*]}
		if [ $thisval -gt $bestval ] ; then
			bestval=$thisval ; best="$x"
		fi
	done
	options[options_counter]="$best"
	(( options_counter++ ))
}

while
	[ $did_new_tests -eq 1 ]
do
	options_counter=0
	did_new_tests=0

	try "" -O2 -O3
	try "" -march={i386,i486,i586,i686,pentium{-mmx,2,3,4}} \
	       -march={k6,k6-2,k6-3,athlon,athlon-{tbird,4,xp,mp}}
	try "" -fforce-addr
	try "" -fomit-frame-pointer
	try "" -finline-functions
	try "" -fcse-follow-jumps -fcse-skip-blocks
	try "" -funroll-loops
	try "" -frerun-cse-after-loop
	try "" -frerun-loop-opt
	try "" -fgcse
	try "" -fexpensive-optimizations
	try "" -fdelayed-branch
	try "" -funroll-all-loops
	try "" -maccumulate-outgoing-args
	try "" -fschedule-insns -fschedule-insns2
	try "" -{m,f}align-functions={2,4}
	try "" -preferred-stack-boundary={2,4}
done

echo -e "\nCompiler benchmark finished. Best results with:"
echo "$compiler" ${options[*]} ; echo

