office-gobmx/bin/update_pch_autotune.sh
Ashod Nakashian 24ef3924d8 PCH support on Linux
Fixes and improvements to support Precompiled Headers
on Linux.

Change-Id: I8145c146b0dba56c7a4d0fdf9c330164b67ada53
Reviewed-on: https://gerrit.libreoffice.org/21307
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Ashod Nakashian <ashnakash@gmail.com>
2016-01-11 03:55:46 +00:00

229 lines
7.1 KiB
Bash
Executable file

#! /bin/bash
#
# This file is part of the LibreOffice project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# Finds the optimal update_pch settings that results in,
# per module and library, the fastest build time and
# smallest intermediate files (.o/.obj) output.
# Usage: update_pch_autotune.sh [<module1> <module2>]
# Invoke: /opt/lo/bin/make cmd cmd="./bin/update_pch_autotune.sh [..]"
# The resulting values may be entered in update_pch
# to be use for generating PCH in the future.
# Run this script after major header changes.
root=`dirname $0`
root=`cd $root/.. && pwd`
cd $root
if test -z "$1"; then
modules=`ls ./*/inc/pch/precompiled_*.hxx | sed -e s%./%% -e s%/.*%% | uniq`
else
modules="$@"
fi
if [[ "$OSTYPE" == "cygwin" ]]; then
MAKE=/opt/lo/bin/make
else
MAKE=make
fi
function build()
{
local START=$(date +%s.%N)
$MAKE -sr "$module" > /dev/null
status=$?
if [ $status -ne 0 ];
then
# Spurious failures happen.
$MAKE "$module.build" > /dev/null
status=$?
fi
local END=$(date +%s.%N1)
build_time=$(printf %.1f $(echo "$END - $START" | bc))
size="FAILED"
score="FAILED"
if [ $status -eq 0 ];
then
# The total size of the object files.
size="$(du -s workdir/CxxObject/$module/ | awk '{print $1}')"
# Add the pch file size.
filename_rel="workdir/PrecompiledHeader/nodebug/$(basename $header)*"
filename_dbg="workdir/PrecompiledHeader/debug/$(basename $header)*"
if [[ $filename_rel -nt $filename_dbg ]]; then
pch_size="$(du -s $filename_rel | awk '{print $1}' | paste -sd+ | bc)"
else
pch_size="$(du -s $filename_dbg | awk '{print $1}' | paste -sd+ | bc)"
fi
size="$(echo "$pch_size + $size" | bc)"
# Compute a score based on the build time and size.
# The shorter the build time, and smaller disk usage, the higher the score.
score=$(printf %.2f $(echo "10000 / ($build_time * e($size/1048576))" | bc -l))
fi
}
function run()
{
local msg="$module.$libname, ${@:3}, "
printf "$msg"
./bin/update_pch "$module" "$libname" "${@:3}" --silent
status=$?
if [ $status -eq 0 ];
then
build
summary="$build_time, $size, $score"
if [ $status -eq 0 ];
then
new_best_for_cuttof=$(echo "$score > $best_score_for_cuttof" | bc -l)
if [ $new_best_for_cuttof -eq 1 ];
then
best_score_for_cuttof=$score
fi
new_best=$(echo "$score > $best_score" | bc -l)
if [ $new_best -eq 1 ];
then
best_score=$score
best_args="${@:3}"
best_time=$build_time
best_cutoff=$cutoff
summary="$build_time, $size, $score,*"
fi
fi
else
# Skip if pch is not updated.
summary="0, 0, 0"
fi
echo "$summary"
}
function args_to_table()
{
local sys="EXCLUDE"
local mod="EXCLUDE"
local loc="EXCLUDE"
local cutoff=0
IFS=' ' read -r -a aargs <<< $best_args
for index in "${!aargs[@]}"
do
if [ "${aargs[index]}" = "--include:system" ];
then
sys="INCLUDE"
elif [ "${aargs[index]}" = "--exclude:system" ];
then
sys="EXCLUDE"
elif [ "${aargs[index]}" = "--include:module" ];
then
mod="INCLUDE"
elif [ "${aargs[index]}" = "--exclude:module" ];
then
mod="EXCLUDE"
elif [ "${aargs[index]}" = "--include:local" ];
then
loc="INCLUDE"
elif [ "${aargs[index]}" = "--exclude:local" ];
then
loc="EXCLUDE"
elif [[ "${aargs[index]}" == *"cutoff"* ]]
then
cutoff=$(echo "${aargs[index]}" | grep -Po '\-\-cutoff\=\K\d+')
fi
done
local key=$(printf "'%s.%s'" $module $libname)
echo "$(printf " %-36s: (%2d, %s, %s, %s), # %5.1f" $key $cutoff $sys $mod $loc $best_time)"
}
for module in $modules; do
# Build without pch includes as sanity check.
#run "$root" "$module" --cutoff=999
# Build before updating pch.
$MAKE "$module.build" > /dev/null
if [ $? -ne 0 ];
then
# Build with dependencies before updating pch.
echo "Failed to build $module, building known state with dependencies..."
./bin/update_pch.sh "$module" > /dev/null
$MAKE "$module.clean" > /dev/null
$MAKE "$module.all" > /dev/null
if [ $? -ne 0 ];
then
# Build all!
echo "Failed to build $module with dependencies, building all..."
$MAKE build-nocheck > /dev/null
if [ $? -ne 0 ];
then
>&2 echo "Broken build. Please revert changes and try again."
exit 1
fi
fi
fi
# Find pch files in the module to update.
headers=`find $root/$module/ -type f -iname "precompiled_*.hxx"`
# Each pch belongs to a library.
for header in $headers; do
libname=`echo $header | sed -e s/.*precompiled_// -e s/\.hxx//`
#TODO: Backup the header and restore when last tune fails.
# Force update on first try below.
echo "Autotuning $module.$libname..."
./bin/update_pch "$module" "$libname" --cutoff=999 --silent --force
best_score=0
best_args=""
best_time=0
best_cutoff=0
for i in {1..16}; do
cutoff=$i
best_score_for_cuttof=0
#run "$root" "$module" "--cutoff=$i" --include:system --exclude:module --exclude:local
run "$root" "$module" "--cutoff=$i" --exclude:system --exclude:module --exclude:local
#run "$root" "$module" "--cutoff=$i" --include:system --include:module --exclude:local
run "$root" "$module" "--cutoff=$i" --exclude:system --include:module --exclude:local
#run "$root" "$module" "--cutoff=$i" --include:system --exclude:module --include:local
run "$root" "$module" "--cutoff=$i" --exclude:system --exclude:module --include:local
#run "$root" "$module" "--cutoff=$i" --include:system --include:module --include:local
run "$root" "$module" "--cutoff=$i" --exclude:system --include:module --include:local
if [ $i -gt $((best_cutoff+2)) ];
then
score_too_low=$(echo "$best_score_for_cuttof < $best_score / 1.10" | bc -l)
if [ $score_too_low -eq 1 ];
then
echo "Score hit low of $best_score_for_cuttof, well bellow overall best of $best_score. Stopping."
break;
fi
fi
done
./bin/update_pch "$module" "$libname" $best_args --force --silent
echo "> $module.$libname, $best_args, $best_time, $size, $score"
echo
table+=$'\n'
table+="$(args_to_table)"
done
done
echo "Update the relevant lines in ./bin/update_pch script:"
>&2 echo "$table"
exit 0