A-FOT/0001-Add-Bear-to-A-FOT.patch
huitailangzju d2483e912c Add Bear to A-FOT
(cherry picked from commit 84ec6f3b24f95d725a7726ec551ea00c7f5b8c75)
2022-12-20 15:18:55 +08:00

427 lines
13 KiB
Diff
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

diff --git a/a-fot b/a-fot
index 1520a9e..c633098 100644
--- a/a-fot
+++ b/a-fot
@@ -74,6 +74,10 @@ function parse_input_params() {
check_success=$2
shift 2
;;
+ --build_mode)
+ build_mode=$2
+ shift 2
+ ;;
*)
suggest_info
exit 1
@@ -124,6 +128,10 @@ function check_config_item() {
echo "[ERROR] The configuration item 'check_success' is missing, please check!"
exit 1
fi
+ if [[ -z ${build_mode} ]]; then
+ echo "[ERROR] The configuration item 'build_mode' is missing, please check!"
+ exit 1
+ fi
}
function suggest_info() {
@@ -141,6 +149,7 @@ Usage: a-fot [OPTION1 ARG1] [OPTION2 ARG2] [...]
--run_script Script path for run application
--max_waiting_time Maximum binary startup time (unit: seconds)
--check_success Check optimization result
+--build_mode Execute build scrip mode (Wrapper/Bear)
"""
}
@@ -181,11 +190,27 @@ function check_common_dependency() {
is_file_exist "${gcc_path}/bin/gcc"
}
+# 拆分编译数据库
+function split_option() {
+ if [ "$bear_prefix" ];then
+ python3 $current_path/split_json.py -i $PWD/compile_commands.json
+ mv $PWD/compile_commands.json $PWD/compile_commands_$1.json
+ mv $PWD/compile_commands.fail.json $PWD/compile_commands.fail_$1.json
+ fi
+}
+
# 使用原始编译选项进行编译
function first_compilation() {
echo "[INFO] Start raw compilation"
is_file_exist ${build_script} "build_script"
- /bin/bash ${build_script} >> ${log_file} 2>&1
+ if [[ $build_mode =~ "Bear" ]]; then
+ bear_prefix="bear -- "
+ echo "[INFO] Build in Bear mode"
+ else
+ echo "[INFO] Build in Wrapper mode"
+ fi
+ $bear_prefix /bin/bash ${build_script} >> ${log_file} 2>&1
+ split_option first
is_file_exist ${bin_file}
is_success $?
}
@@ -237,7 +262,7 @@ function detect_process() {
function second_compilation() {
echo "[INFO] Try compiling with the new compilation options"
if [[ ${check_success} -eq 1 ]]; then
- /bin/bash ${build_script} >> ${log_file} 2>&1 & build_id=$!
+ $bear_prefix /bin/bash ${build_script} >> ${log_file} 2>&1 & build_id=$!
echo "[INFO] Found build id: ${build_id}"
add_opt=$(cat ${gcc_wrapper}/gcc | awk -F " " '{print $2}')
build_status=`ps -p ${build_id} | grep -c ${build_id}`
@@ -254,9 +279,10 @@ function second_compilation() {
done
wait
else
- /bin/bash ${build_script} >> ${log_file} 2>&1
+ $bear_prefix /bin/bash ${build_script} >> ${log_file} 2>&1
fi
echo "[INFO] Finish compiling with new compilation options"
+ split_option second
is_success $?
}
@@ -308,10 +334,12 @@ function is_opt_success() {
if [[ ${opt_success} -eq 0 ]]; then
echo "[WARNING] Optimization may fail or the build process is too short, please check!"
echo "[WARNING] Please try gcc/g++ at: ${gcc_wrapper} instead of the original compiler"
+ exit 1
else
echo "[INFO] Optimization may success!"
fi
fi
+ exit 0
}
#执行入口,部分函数为加载不同优化脚本中得到
@@ -324,15 +352,17 @@ function main() {
load_script
check_dependency
- create_wrapper
+ prepare_env
first_compilation
execute_run_script
detect_process
perf_record
- create_new_wrapper
+ prepare_new_env
second_compilation
is_opt_success
+ exit "$?"
}
main "$@"
+exit "$?"
diff --git a/a-fot.ini b/a-fot.ini
index 03a4702..b395504 100644
--- a/a-fot.ini
+++ b/a-fot.ini
@@ -18,4 +18,6 @@ perf_time=100
gcc_path=/usr/
# 检测是否优化成功(1=启用0=禁用)
check_success=0
+# 构建模式 Bear、Wrapper
+build_mode=Bear
# 结束行勿删
\ No newline at end of file
diff --git a/auto_bolt.sh b/auto_bolt.sh
index 625d1d5..ebcb2e5 100644
--- a/auto_bolt.sh
+++ b/auto_bolt.sh
@@ -9,11 +9,29 @@ function check_dependency() {
fi
}
+# 根据模式选择Wrapper或者Bear模式构建
+function prepare_env() {
+ case ${build_mode} in
+ "Wrapper")
+ create_wrapper
+ ;;
+ "Bear")
+ export COMPILATION_OPTIONS="-Wl,-q"
+ export LINK_OPTIONS="-q"
+ ;;
+ *)
+ echo "[ERROR] Build mode ${build_mode} is not supported, the value is : Wrapper/Bear"
+ exit 1
+ ;;
+ esac
+}
+
+
# 创建原始wrapper
function create_wrapper() {
echo "[INFO] Start generating the original wrapper"
- echo "${gcc_path}/bin/gcc -Wl,-q \$@" >${gcc_wrapper}/gcc
- echo "${gcc_path}/bin/g++ -Wl,-q \$@" >${gcc_wrapper}/g++
+ echo "${gcc_path}/bin/gcc -Wl,-q \"\$@\"" >${gcc_wrapper}/gcc
+ echo "${gcc_path}/bin/g++ -Wl,-q \"\$@\"" >${gcc_wrapper}/g++
post_create_wrapper
}
@@ -28,9 +46,28 @@ function perf_record() {
pkill ${application_name}
}
+
+# 根据模式选择Wrapper或者Bear模式构建
+function prepare_new_env() {
+ case ${build_mode} in
+ "Wrapper")
+ create_new_wrapper
+ ;;
+ "Bear")
+ export COMPILATION_OPTIONS="-fbolt-use=${profile_data_path}/${gcov_name} -fbolt-target=${bin_file} -Wl,-q"
+ export LINK_OPTIONS="-q"
+ ;;
+ *)
+ echo "[ERROR] Build mode ${build_mode} is not supported, the value is : Wrapper/Bear"
+ exit 1
+ ;;
+ esac
+}
+
+
#生成新的wrapper
function create_new_wrapper() {
echo "[INFO] Start to generate a new wrapper"
- echo "${gcc_path}/bin/gcc -fbolt-use=${profile_data_path}/${gcov_name} -fbolt-target=${bin_file} -Wl,-q \$@" >${gcc_wrapper}/gcc
- echo "${gcc_path}/bin/g++ -fbolt-use=${profile_data_path}/${gcov_name} -fbolt-target=${bin_file} -Wl,-q \$@" >${gcc_wrapper}/g++
+ echo "${gcc_path}/bin/gcc -fbolt-use=${profile_data_path}/${gcov_name} -fbolt-target=${bin_file} -Wl,-q \"\$@\"" >${gcc_wrapper}/gcc
+ echo "${gcc_path}/bin/g++ -fbolt-use=${profile_data_path}/${gcov_name} -fbolt-target=${bin_file} -Wl,-q \"\$@\"" >${gcc_wrapper}/g++
}
diff --git a/auto_fdo.sh b/auto_fdo.sh
index 3d7bbb8..8426b30 100644
--- a/auto_fdo.sh
+++ b/auto_fdo.sh
@@ -9,11 +9,28 @@ function check_dependency() {
fi
}
+# 根据模式选择Wrapper或者Bear模式构建
+function prepare_env() {
+ case ${build_mode} in
+ "Wrapper")
+ create_wrapper
+ ;;
+ "Bear")
+ export COMPILATION_OPTIONS="-g"
+ export LINK_OPTIONS="-g"
+ ;;
+ *)
+ echo "[ERROR] Build mode ${build_mode} is not supported, the value is : Wrapper/Bear"
+ exit 1
+ ;;
+ esac
+}
+
# 创建原始wrapper
function create_wrapper() {
echo "[INFO] Start generating the original wrapper"
- echo "${gcc_path}/bin/gcc -g \$@" >${gcc_wrapper}/gcc
- echo "${gcc_path}/bin/g++ -g \$@" >${gcc_wrapper}/g++
+ echo "${gcc_path}/bin/gcc -g \"\$@\"" >${gcc_wrapper}/gcc
+ echo "${gcc_path}/bin/g++ -g \"\$@\"" >${gcc_wrapper}/g++
post_create_wrapper
}
@@ -39,9 +56,25 @@ function perf_record() {
pkill ${application_name}
}
+# 根据模式选择Wrapper或者Bear模式构建
+function prepare_new_env() {
+ case ${build_mode} in
+ "Wrapper")
+ create_new_wrapper
+ ;;
+ "Bear")
+ export COMPILATION_OPTIONS="-fauto-profile=${profile_data_path}/${gcov_name}"
+ ;;
+ *)
+ echo "[ERROR] Build mode ${build_mode} is not supported, the value is : Wrapper/Bear"
+ exit 1
+ ;;
+ esac
+}
+
#生成新的wrapper
function create_new_wrapper() {
echo "[INFO] Start to generate a new wrapper"
- echo "${gcc_path}/bin/gcc -fauto-profile=${profile_data_path}/${gcov_name} \$@" >${gcc_wrapper}/gcc
- echo "${gcc_path}/bin/g++ -fauto-profile=${profile_data_path}/${gcov_name} \$@" >${gcc_wrapper}/g++
+ echo "${gcc_path}/bin/gcc -fauto-profile=${profile_data_path}/${gcov_name} \"\$@\"" >${gcc_wrapper}/gcc
+ echo "${gcc_path}/bin/g++ -fauto-profile=${profile_data_path}/${gcov_name} \"\$@\"" >${gcc_wrapper}/g++
}
diff --git a/auto_prefetch.sh b/auto_prefetch.sh
index 2562dd6..265828a 100644
--- a/auto_prefetch.sh
+++ b/auto_prefetch.sh
@@ -9,11 +9,28 @@ function check_dependency() {
fi
}
+# 根据模式选择Wrapper或者Bear模式构建
+function prepare_env() {
+ case ${build_mode} in
+ "Wrapper")
+ create_wrapper
+ ;;
+ "Bear")
+ export COMPILATION_OPTIONS="-g"
+ export LINK_OPTIONS="-g"
+ ;;
+ *)
+ echo "[ERROR] Build mode ${build_mode} is not supported, the value is : Wrapper/Bear"
+ exit 1
+ ;;
+ esac
+}
+
# 创建原始wrapper
function create_wrapper() {
echo "[INFO] Start generating the original wrapper"
- echo "${gcc_path}/bin/gcc -g \$@" >${gcc_wrapper}/gcc
- echo "${gcc_path}/bin/g++ -g \$@" >${gcc_wrapper}/g++
+ echo "${gcc_path}/bin/gcc -g \"\$@\"" >${gcc_wrapper}/gcc
+ echo "${gcc_path}/bin/g++ -g \"\$@\"" >${gcc_wrapper}/g++
post_create_wrapper
}
@@ -40,9 +57,25 @@ function perf_record() {
pkill ${application_name}
}
+# 根据模式选择Wrapper或者Bear模式构建
+function prepare_new_env() {
+ case ${build_mode} in
+ "Wrapper")
+ create_new_wrapper
+ ;;
+ "Bear")
+ export COMPILATION_OPTIONS="-fauto-profile=${gcov_file_name} -fcache-misses-profile=${profile_data_path}/${gcov_name}.cache-misses\:u -fprefetch-loop-arrays=2"
+ ;;
+ *)
+ echo "[ERROR] Build mode ${build_mode} is not supported, the value is : Wrapper/Bear"
+ exit 1
+ ;;
+ esac
+}
+
#生成新的wrapper
function create_new_wrapper() {
echo "[INFO] Start to generate a new wrapper"
- echo "${gcc_path}/bin/gcc -fauto-profile=${gcov_file_name} -fcache-misses-profile=${profile_data_path}/${gcov_name}.cache-misses\:u -fprefetch-loop-arrays=2 \$@" >${gcc_wrapper}/gcc
- echo "${gcc_path}/bin/g++ -fauto-profile=${gcov_file_name} -fcache-misses-profile=${profile_data_path}/${gcov_name}.cache-misses\:u -fprefetch-loop-arrays=2 \$@" >${gcc_wrapper}/g++
+ echo "${gcc_path}/bin/gcc -fauto-profile=${gcov_file_name} -fcache-misses-profile=${profile_data_path}/${gcov_name}.cache-misses\:u -fprefetch-loop-arrays=2 \"\$@\"" >${gcc_wrapper}/gcc
+ echo "${gcc_path}/bin/g++ -fauto-profile=${gcov_file_name} -fcache-misses-profile=${profile_data_path}/${gcov_name}.cache-misses\:u -fprefetch-loop-arrays=2 \"\$@\"" >${gcc_wrapper}/g++
}
diff --git a/split_json.py b/split_json.py
new file mode 100644
index 0000000..bb6547f
--- /dev/null
+++ b/split_json.py
@@ -0,0 +1,98 @@
+#!/usr/bin/env python3
+# _*_ coding:utf-8 _*_
+
+
+"""
+ Copyright@2022-2022, All rights reserved, Powered by: Huawei Tech.Co.,Ltd.
+
+split_json is a interface to split compile commands according to its execution result.
+
+It will generate a new JSON file for the failed compile commands and remove these commands from source file.
+
+Input:
+ compile commands json
+Output:
+ compile commands json including commands which has been successfully executed.
+ compile commands json including commands which executed unsuccessfully.
+
+"""
+__author__ = 'z00500762'
+
+import argparse
+import os
+import json
+import sys
+import logging
+
+
+class SplitJson:
+ compile_commands_success = list()
+ compile_commands_fail = list()
+
+ def __init__(self, input_json):
+ self.input = input_json
+
+ @staticmethod
+ def validate(execution):
+ if "arguments" not in execution:
+ return False
+ if "directory" not in execution:
+ return False
+ if "exec_result" not in execution:
+ return False
+ return True
+
+ def get_compile_commands(self):
+ compile_commands = list()
+ try:
+ with open(self.input, "r", encoding='utf-8', errors='ignore') as json_file:
+ compile_commands = json.load(json_file)
+ if len(compile_commands) == 0:
+ logging.info("compile commands json file is empty: %s", self.input)
+ except IOError as exception:
+ logging.error("open compile commands json file failed: %s", exception)
+ except json.decoder.JSONDecodeError as exception:
+ logging.error("json decode file failed: %s", exception)
+
+ return compile_commands
+
+ def split_commands(self):
+ compile_commands = self.get_compile_commands()
+ for item in compile_commands:
+ if not self.validate(item):
+ logging.info("discard invalid commands: %s", str(item))
+ if not item.get("rebuild"):
+ self.compile_commands_success.append(item)
+ else:
+ self.compile_commands_fail.append(item)
+ self.write_json()
+
+ def write_json(self):
+ compile_commands_success_file = os.path.splitext(self.input)[0] + ".json"
+ compile_commands_fail_file = os.path.splitext(self.input)[0] + ".fail.json"
+ with open(compile_commands_success_file, 'w+') as fw:
+ json.dump(self.compile_commands_success, fw, sort_keys=False, indent=4)
+
+ with open(compile_commands_fail_file, 'w+') as fw:
+ json.dump(self.compile_commands_fail, fw, sort_keys=False, indent=4)
+
+
+def main(input_json):
+ if not os.path.isabs(input_json):
+ input_json = os.path.join(os.getcwd(), input_json)
+ if not os.path.exists(input_json):
+ logging.error("compile_command_file not exists : %s", input_json)
+ return -1
+
+ sj = SplitJson(input_json)
+ sj.split_commands()
+
+
+if __name__ == "__main__":
+ cmd_parser = argparse.ArgumentParser(description="split compile commands json")
+ cmd_parser.add_argument(
+ '-i', '--input', dest='input_json', metavar='store', action='store',
+ help='json to split'
+ )
+ args = cmd_parser.parse_args()
+ sys.exit(main(args.input_json))