You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nudt-compiler-cpp/scripts/verify_ir.sh

157 lines
3.7 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#!/usr/bin/env bash
# ./scripts/verify_ir.sh test/test_case/functional/simple_add.sy test/test_result/function/ir --run
set -euo pipefail
if [[ $# -lt 1 ]]; then
echo "用法: $0 <input.sy> [output_dir] [--run] [-O]" >&2
exit 1
fi
out_dir="test/test_result/ir"
run_exec=false
optimize=false
input=""
while [[ $# -gt 0 ]]; do
case "$1" in
--run)
run_exec=true
;;
-O|--optimize)
optimize=true
;;
-*)
echo "未知选项: $1" >&2
exit 1
;;
*)
if [[ -z "$input" ]]; then
input="$1"
else
out_dir="$1"
fi
;;
esac
shift
done
if [[ -z "$input" ]]; then
echo "未指定输入文件" >&2
exit 1
fi
input_dir=$(dirname "$input")
if [[ ! -f "$input" ]]; then
echo "输入文件不存在: $input" >&2
exit 1
fi
compiler="./build/bin/compiler"
if [[ ! -x "$compiler" ]]; then
echo "未找到编译器: $compiler ,请先构建(如: mkdir -p build && cd build && cmake .. && make -j" >&2
exit 1
fi
mkdir -p "$out_dir"
base=$(basename "$input")
stem=${base%.sy}
out_file="$out_dir/$stem.ll"
stdin_file="$input_dir/$stem.in"
expected_file="$input_dir/$stem.out"
# 记录编译开始时间
compile_start=$(date +%s%N)
if [[ "$optimize" == true ]]; then
"$compiler" -O --emit-ir "$input" > "$out_file"
else
"$compiler" --emit-ir "$input" > "$out_file"
fi
# 记录编译结束时间
compile_end=$(date +%s%N)
compile_time=$(( ($compile_end - $compile_start) / 1000000 ))
if [[ "$run_exec" == true ]]; then
if ! command -v llc >/dev/null 2>&1; then
echo "未找到 llc无法运行 IR。请安装 LLVM。" >&2
exit 1
fi
if ! command -v clang >/dev/null 2>&1; then
echo "未找到 clang无法链接可执行文件。请安装 LLVM/Clang。" >&2
exit 1
fi
obj="$out_dir/$stem.o"
exe="$out_dir/$stem"
stdout_file="$out_dir/$stem.stdout"
actual_file="$out_dir/$stem.actual.out"
sylib_obj="$out_dir/sylib.o"
# 记录链接开始时间
link_start=$(date +%s%N)
if [[ ! -f "$sylib_obj" ]]; then
gcc -c sylib/sylib.c -o "$sylib_obj"
fi
llc -O0 -filetype=obj "$out_file" -o "$obj"
clang "$obj" "$sylib_obj" -o "$exe"
# 记录链接结束时间
link_end=$(date +%s%N)
link_time=$(( ($link_end - $link_start) / 1000000 ))
# 记录执行开始时间
exec_start=$(date +%s%N)
set +e
if [[ -f "$stdin_file" ]]; then
(ulimit -s 65536 && "$exe" < "$stdin_file" > "$stdout_file")
else
(ulimit -s 65536 && "$exe" > "$stdout_file")
fi
status=$?
set -e
# 记录执行结束时间
exec_end=$(date +%s%N)
exec_time=$(( ($exec_end - $exec_start) / 1000000 ))
# 保存运行时间到文件(只保存执行时间,不包含编译和链接时间)
time_file="$out_dir/${stem}_time.txt"
echo "$exec_time" > "$time_file"
# 保存输出(用于比对)
{
cat "$stdout_file"
# 确保 stdout 以换行结尾
if [[ -s "$stdout_file" ]] && (( $(tail -c 1 "$stdout_file" | wc -l) == 0 )); then
printf '\n'
fi
printf '%s\n' "$status"
} > "$actual_file"
# 比对输出
if [[ -f "$expected_file" ]]; then
temp_expected="$out_dir/$stem.expected.tmp"
temp_actual="$out_dir/$stem.actual.tmp"
tr -d '\r' < "$expected_file" > "$temp_expected"
tr -d '\r' < "$actual_file" > "$temp_actual"
if [[ -s "$temp_expected" ]] && (( $(tail -c 1 "$temp_expected" | wc -l) == 0 )); then
if [[ -s "$temp_actual" ]] && (( $(tail -c 1 "$temp_actual" | wc -l) == 1 )); then
truncate -s -1 "$temp_actual"
fi
fi
if diff -u "$temp_expected" "$temp_actual" > /dev/null 2>&1; then
rm -f "$temp_expected" "$temp_actual"
else
echo "输出不匹配: $expected_file" >&2
rm -f "$temp_expected" "$temp_actual"
exit 1
fi
fi
fi