Compare commits

...

8 Commits

12 changed files with 104 additions and 48 deletions

2
.gitignore vendored
View File

@ -36,7 +36,7 @@ doxygen
!/testdata/functional/*.out !/testdata/functional/*.out
!/testdata/h_functional/*.out !/testdata/h_functional/*.out
!/testdata/performance/*.out testdata/performance/
build/ build/
.antlr .antlr
.vscode/ .vscode/

View File

@ -20,18 +20,19 @@ QEMU_RISCV64="qemu-riscv64"
# --- 初始化变量 --- # --- 初始化变量 ---
EXECUTE_MODE=false EXECUTE_MODE=false
IR_EXECUTE_MODE=false # 新增 IR_EXECUTE_MODE=false
CLEAN_MODE=false CLEAN_MODE=false
OPTIMIZE_FLAG="" OPTIMIZE_FLAG=""
SYSYC_TIMEOUT=30 SYSYC_TIMEOUT=30
LLC_TIMEOUT=10 # 新增 LLC_TIMEOUT=10
GCC_TIMEOUT=10 GCC_TIMEOUT=10
EXEC_TIMEOUT=30 EXEC_TIMEOUT=30
MAX_OUTPUT_LINES=20 MAX_OUTPUT_LINES=20
MAX_OUTPUT_CHARS=1000
SY_FILES=() SY_FILES=()
PASSED_CASES=0 PASSED_CASES=0
FAILED_CASES_LIST="" FAILED_CASES_LIST=""
INTERRUPTED=false # 新增 INTERRUPTED=false
# ================================================================= # =================================================================
# --- 函数定义 --- # --- 函数定义 ---
@ -50,22 +51,31 @@ show_help() {
echo " -gct N 设置 gcc 交叉编译超时为 N 秒 (默认: 10)。" echo " -gct N 设置 gcc 交叉编译超时为 N 秒 (默认: 10)。"
echo " -et N 设置 qemu 自动化执行超时为 N 秒 (默认: 30)。" echo " -et N 设置 qemu 自动化执行超时为 N 秒 (默认: 30)。"
echo " -ml N, --max-lines N 当输出对比失败时,最多显示 N 行内容 (默认: 20)。" echo " -ml N, --max-lines N 当输出对比失败时,最多显示 N 行内容 (默认: 20)。"
echo " -mc N, --max-chars N 当输出对比失败时,最多显示 N 个字符 (默认: 1000)。"
echo " -h, --help 显示此帮助信息并退出。" echo " -h, --help 显示此帮助信息并退出。"
echo "" echo ""
echo "可在任何时候按 Ctrl+C 来中断测试并显示当前已完成的测例总结。" echo "可在任何时候按 Ctrl+C 来中断测试并显示当前已完成的测例总结。"
} }
# 显示文件内容并根据行数和字符数截断的函数
display_file_content() { display_file_content() {
local file_path="$1" local file_path="$1"
local title="$2" local title="$2"
local max_lines="$3" local max_lines="$3"
local max_chars="$4" # 新增参数
if [ ! -f "$file_path" ]; then return; fi if [ ! -f "$file_path" ]; then return; fi
echo -e "$title" echo -e "$title"
local line_count local line_count
local char_count
line_count=$(wc -l < "$file_path") line_count=$(wc -l < "$file_path")
char_count=$(wc -c < "$file_path")
if [ "$line_count" -gt "$max_lines" ]; then if [ "$line_count" -gt "$max_lines" ]; then
head -n "$max_lines" "$file_path" head -n "$max_lines" "$file_path"
echo -e "\e[33m[... 输出已截断,${line_count} 行 ...]\e[0m" echo -e "\e[33m[... 输出因行数过多 (${line_count}) 而截断 ...]\e[0m"
elif [ "$char_count" -gt "$max_chars" ]; then
head -c "$max_chars" "$file_path"
echo -e "\n\e[33m[... 输出因字符数过多 (共 ${char_count} 字符) 而截断 ...]\e[0m"
else else
cat "$file_path" cat "$file_path"
fi fi
@ -131,6 +141,7 @@ while [[ "$#" -gt 0 ]]; do
-gct) if [[ -n "$2" && "$2" =~ ^[0-9]+$ ]]; then GCC_TIMEOUT="$2"; shift 2; else echo "错误: -gct 需要一个正整数参数。" >&2; exit 1; fi ;; -gct) if [[ -n "$2" && "$2" =~ ^[0-9]+$ ]]; then GCC_TIMEOUT="$2"; shift 2; else echo "错误: -gct 需要一个正整数参数。" >&2; exit 1; fi ;;
-et) if [[ -n "$2" && "$2" =~ ^[0-9]+$ ]]; then EXEC_TIMEOUT="$2"; shift 2; else echo "错误: -et 需要一个正整数参数。" >&2; exit 1; fi ;; -et) if [[ -n "$2" && "$2" =~ ^[0-9]+$ ]]; then EXEC_TIMEOUT="$2"; shift 2; else echo "错误: -et 需要一个正整数参数。" >&2; exit 1; fi ;;
-ml|--max-lines) if [[ -n "$2" && "$2" =~ ^[0-9]+$ ]]; then MAX_OUTPUT_LINES="$2"; shift 2; else echo "错误: --max-lines 需要一个正整数参数。" >&2; exit 1; fi ;; -ml|--max-lines) if [[ -n "$2" && "$2" =~ ^[0-9]+$ ]]; then MAX_OUTPUT_LINES="$2"; shift 2; else echo "错误: --max-lines 需要一个正整数参数。" >&2; exit 1; fi ;;
-mc|--max-chars) if [[ -n "$2" && "$2" =~ ^[0-9]+$ ]]; then MAX_OUTPUT_CHARS="$2"; shift 2; else echo "错误: --max-chars 需要一个正整数参数。" >&2; exit 1; fi ;;
-h|--help) show_help; exit 0 ;; -h|--help) show_help; exit 0 ;;
-*) echo "未知选项: $1"; show_help; exit 1 ;; -*) echo "未知选项: $1"; show_help; exit 1 ;;
*) *)
@ -180,6 +191,8 @@ TOTAL_CASES=${#SY_FILES[@]}
echo "SysY 单例测试运行器启动..." echo "SysY 单例测试运行器启动..."
if [ -n "$OPTIMIZE_FLAG" ]; then echo "优化等级: ${OPTIMIZE_FLAG}"; fi if [ -n "$OPTIMIZE_FLAG" ]; then echo "优化等级: ${OPTIMIZE_FLAG}"; fi
echo "超时设置: sysyc=${SYSYC_TIMEOUT}s, llc=${LLC_TIMEOUT}s, gcc=${GCC_TIMEOUT}s, qemu=${EXEC_TIMEOUT}s" echo "超时设置: sysyc=${SYSYC_TIMEOUT}s, llc=${LLC_TIMEOUT}s, gcc=${GCC_TIMEOUT}s, qemu=${EXEC_TIMEOUT}s"
echo "失败输出最大行数: ${MAX_OUTPUT_LINES}"
echo "失败输出最大字符数: ${MAX_OUTPUT_CHARS}"
echo "" echo ""
for sy_file in "${SY_FILES[@]}"; do for sy_file in "${SY_FILES[@]}"; do
@ -260,8 +273,8 @@ for sy_file in "${SY_FILES[@]}"; do
out_ok=1 out_ok=1
if ! diff -q <(tr -d '[:space:]' < "${output_actual_file}") <(tr -d '[:space:]' < "${EXPECTED_STDOUT_FILE}") >/dev/null 2>&1; then if ! diff -q <(tr -d '[:space:]' < "${output_actual_file}") <(tr -d '[:space:]' < "${EXPECTED_STDOUT_FILE}") >/dev/null 2>&1; then
echo -e "\e[31m 标准输出测试失败。\e[0m"; out_ok=0 echo -e "\e[31m 标准输出测试失败。\e[0m"; out_ok=0
display_file_content "${EXPECTED_STDOUT_FILE}" " \e[36m--- 期望输出 ---\e[0m" "${MAX_OUTPUT_LINES}" display_file_content "${EXPECTED_STDOUT_FILE}" " \e[36m--- 期望输出 ---\e[0m" "${MAX_OUTPUT_LINES}" "${MAX_OUTPUT_CHARS}"
display_file_content "${output_actual_file}" " \e[36m--- 实际输出 ---\e[0m" "${MAX_OUTPUT_LINES}" display_file_content "${output_actual_file}" " \e[36m--- 实际输出 ---\e[0m" "${MAX_OUTPUT_LINES}" "${MAX_OUTPUT_CHARS}"
fi fi
if [ "$ret_ok" -eq 1 ] && [ "$out_ok" -eq 1 ]; then echo -e "\e[32m 返回码与标准输出测试成功。\e[0m"; else is_passed=0; fi if [ "$ret_ok" -eq 1 ] && [ "$out_ok" -eq 1 ]; then echo -e "\e[32m 返回码与标准输出测试成功。\e[0m"; else is_passed=0; fi
@ -271,8 +284,8 @@ for sy_file in "${SY_FILES[@]}"; do
echo -e "\e[32m 标准输出测试成功。\e[0m" echo -e "\e[32m 标准输出测试成功。\e[0m"
else else
echo -e "\e[31m 标准输出测试失败。\e[0m"; is_passed=0 echo -e "\e[31m 标准输出测试失败。\e[0m"; is_passed=0
display_file_content "${output_reference_file}" " \e[36m--- 期望输出 ---\e[0m" "${MAX_OUTPUT_LINES}" display_file_content "${output_reference_file}" " \e[36m--- 期望输出 ---\e[0m" "${MAX_OUTPUT_LINES}" "${MAX_OUTPUT_CHARS}"
display_file_content "${output_actual_file}" " \e[36m--- 实际输出 ---\e[0m" "${MAX_OUTPUT_LINES}" display_file_content "${output_actual_file}" " \e[36m--- 实际输出 ---\e[0m" "${MAX_OUTPUT_LINES}" "${MAX_OUTPUT_CHARS}"
fi fi
fi fi
else else

View File

@ -27,11 +27,12 @@ LLC_TIMEOUT=10
GCC_TIMEOUT=10 GCC_TIMEOUT=10
EXEC_TIMEOUT=30 EXEC_TIMEOUT=30
MAX_OUTPUT_LINES=20 MAX_OUTPUT_LINES=20
MAX_OUTPUT_CHARS=1000
TEST_SETS=() TEST_SETS=()
TOTAL_CASES=0 TOTAL_CASES=0
PASSED_CASES=0 PASSED_CASES=0
FAILED_CASES_LIST="" FAILED_CASES_LIST=""
INTERRUPTED=false # 新增:用于标记是否被中断 INTERRUPTED=false
# ================================================================= # =================================================================
# --- 函数定义 --- # --- 函数定义 ---
@ -53,6 +54,7 @@ show_help() {
echo " -gct N 设置 gcc 交叉编译超时为 N 秒 (默认: 10)。" echo " -gct N 设置 gcc 交叉编译超时为 N 秒 (默认: 10)。"
echo " -et N 设置 qemu 执行超时为 N 秒 (默认: 30)。" echo " -et N 设置 qemu 执行超时为 N 秒 (默认: 30)。"
echo " -ml N, --max-lines N 当输出对比失败时,最多显示 N 行内容 (默认: 20)。" echo " -ml N, --max-lines N 当输出对比失败时,最多显示 N 行内容 (默认: 20)。"
echo " -mc N, --max-chars N 当输出对比失败时,最多显示 N 个字符 (默认: 1000)。"
echo " -h, --help 显示此帮助信息并退出。" echo " -h, --help 显示此帮助信息并退出。"
echo "" echo ""
echo "注意: 默认行为 (无 -e 或 -eir) 是将 .sy 文件同时编译为 .s (汇编) 和 .ll (IR),不执行。" echo "注意: 默认行为 (无 -e 或 -eir) 是将 .sy 文件同时编译为 .s (汇编) 和 .ll (IR),不执行。"
@ -60,18 +62,25 @@ show_help() {
} }
# 显示文件内容并根据行数截断的函数 # 显示文件内容并根据行数和字符数截断的函数
display_file_content() { display_file_content() {
local file_path="$1" local file_path="$1"
local title="$2" local title="$2"
local max_lines="$3" local max_lines="$3"
local max_chars="$4" # 新增参数
if [ ! -f "$file_path" ]; then return; fi if [ ! -f "$file_path" ]; then return; fi
echo -e "$title" echo -e "$title"
local line_count local line_count
local char_count
line_count=$(wc -l < "$file_path") line_count=$(wc -l < "$file_path")
char_count=$(wc -c < "$file_path")
if [ "$line_count" -gt "$max_lines" ]; then if [ "$line_count" -gt "$max_lines" ]; then
head -n "$max_lines" "$file_path" head -n "$max_lines" "$file_path"
echo -e "\e[33m[... 输出已截断,${line_count} 行 ...]\e[0m" echo -e "\e[33m[... 输出因行数过多 (${line_count}) 而截断 ...]\e[0m"
elif [ "$char_count" -gt "$max_chars" ]; then
head -c "$max_chars" "$file_path"
echo -e "\n\e[33m[... 输出因字符数过多 (共 ${char_count} 字符) 而截断 ...]\e[0m"
else else
cat "$file_path" cat "$file_path"
fi fi
@ -151,6 +160,7 @@ while [[ "$#" -gt 0 ]]; do
-gct) if [[ -n "$2" && "$2" =~ ^[0-9]+$ ]]; then GCC_TIMEOUT="$2"; shift 2; else echo "错误: -gct 需要一个正整数参数。" >&2; exit 1; fi ;; -gct) if [[ -n "$2" && "$2" =~ ^[0-9]+$ ]]; then GCC_TIMEOUT="$2"; shift 2; else echo "错误: -gct 需要一个正整数参数。" >&2; exit 1; fi ;;
-et) if [[ -n "$2" && "$2" =~ ^[0-9]+$ ]]; then EXEC_TIMEOUT="$2"; shift 2; else echo "错误: -et 需要一个正整数参数。" >&2; exit 1; fi ;; -et) if [[ -n "$2" && "$2" =~ ^[0-9]+$ ]]; then EXEC_TIMEOUT="$2"; shift 2; else echo "错误: -et 需要一个正整数参数。" >&2; exit 1; fi ;;
-ml|--max-lines) if [[ -n "$2" && "$2" =~ ^[0-9]+$ ]]; then MAX_OUTPUT_LINES="$2"; shift 2; else echo "错误: --max-lines 需要一个正整数参数。" >&2; exit 1; fi ;; -ml|--max-lines) if [[ -n "$2" && "$2" =~ ^[0-9]+$ ]]; then MAX_OUTPUT_LINES="$2"; shift 2; else echo "错误: --max-lines 需要一个正整数参数。" >&2; exit 1; fi ;;
-mc|--max-chars) if [[ -n "$2" && "$2" =~ ^[0-9]+$ ]]; then MAX_OUTPUT_CHARS="$2"; shift 2; else echo "错误: --max-chars 需要一个正整数参数。" >&2; exit 1; fi ;;
-h|--help) show_help; exit 0 ;; -h|--help) show_help; exit 0 ;;
*) echo "未知选项: $1"; show_help; exit 1 ;; *) echo "未知选项: $1"; show_help; exit 1 ;;
esac esac
@ -204,6 +214,7 @@ echo "运行模式: ${RUN_MODE_INFO}"
echo "${TIMEOUT_INFO}" echo "${TIMEOUT_INFO}"
if ${EXECUTE_MODE} || ${IR_EXECUTE_MODE}; then if ${EXECUTE_MODE} || ${IR_EXECUTE_MODE}; then
echo "失败输出最大行数: ${MAX_OUTPUT_LINES}" echo "失败输出最大行数: ${MAX_OUTPUT_LINES}"
echo "失败输出最大字符数: ${MAX_OUTPUT_CHARS}"
fi fi
echo "" echo ""
@ -298,8 +309,8 @@ while IFS= read -r sy_file; do
[ "$test_logic_passed" -eq 1 ] && echo -e "\e[32m 标准输出测试成功\e[0m" [ "$test_logic_passed" -eq 1 ] && echo -e "\e[32m 标准输出测试成功\e[0m"
else else
echo -e "\e[31m 标准输出测试失败\e[0m" echo -e "\e[31m 标准输出测试失败\e[0m"
display_file_content "${EXPECTED_STDOUT_FILE}" " \e[36m---------- 期望输出 ----------\e[0m" "${MAX_OUTPUT_LINES}" display_file_content "${EXPECTED_STDOUT_FILE}" " \e[36m---------- 期望输出 ----------\e[0m" "${MAX_OUTPUT_LINES}" "${MAX_OUTPUT_CHARS}"
display_file_content "${output_actual_file_from_ir}" " \e[36m---------- 实际输出 ----------\e[0m" "${MAX_OUTPUT_LINES}" display_file_content "${output_actual_file_from_ir}" " \e[36m---------- 实际输出 ----------\e[0m" "${MAX_OUTPUT_LINES}" "${MAX_OUTPUT_CHARS}"
test_logic_passed=0 test_logic_passed=0
fi fi
else else
@ -308,8 +319,8 @@ while IFS= read -r sy_file; do
echo -e "\e[32m 成功: 输出与参考输出匹配\e[0m" echo -e "\e[32m 成功: 输出与参考输出匹配\e[0m"
else else
echo -e "\e[31m 失败: 输出不匹配\e[0m" echo -e "\e[31m 失败: 输出不匹配\e[0m"
display_file_content "${output_reference_file}" " \e[36m---------- 期望输出 ----------\e[0m" "${MAX_OUTPUT_LINES}" display_file_content "${output_reference_file}" " \e[36m---------- 期望输出 ----------\e[0m" "${MAX_OUTPUT_LINES}" "${MAX_OUTPUT_CHARS}"
display_file_content "${output_actual_file_from_ir}" " \e[36m---------- 实际输出 ----------\e[0m" "${MAX_OUTPUT_LINES}" display_file_content "${output_actual_file_from_ir}" " \e[36m---------- 实际输出 ----------\e[0m" "${MAX_OUTPUT_LINES}" "${MAX_OUTPUT_CHARS}"
test_logic_passed=0 test_logic_passed=0
fi fi
fi fi
@ -375,8 +386,8 @@ while IFS= read -r sy_file; do
[ "$test_logic_passed" -eq 1 ] && echo -e "\e[32m 标准输出测试成功\e[0m" [ "$test_logic_passed" -eq 1 ] && echo -e "\e[32m 标准输出测试成功\e[0m"
else else
echo -e "\e[31m 标准输出测试失败\e[0m" echo -e "\e[31m 标准输出测试失败\e[0m"
display_file_content "${EXPECTED_STDOUT_FILE}" " \e[36m---------- 期望输出 ----------\e[0m" "${MAX_OUTPUT_LINES}" display_file_content "${EXPECTED_STDOUT_FILE}" " \e[36m---------- 期望输出 ----------\e[0m" "${MAX_OUTPUT_LINES}" "${MAX_OUTPUT_CHARS}"
display_file_content "${output_actual_file_S}" " \e[36m---------- 实际输出 ----------\e[0m" "${MAX_OUTPUT_LINES}" display_file_content "${output_actual_file_S}" " \e[36m---------- 实际输出 ----------\e[0m" "${MAX_OUTPUT_LINES}" "${MAX_OUTPUT_CHARS}"
test_logic_passed=0 test_logic_passed=0
fi fi
else else
@ -385,8 +396,8 @@ while IFS= read -r sy_file; do
echo -e "\e[32m 成功: 输出与参考输出匹配\e[0m" echo -e "\e[32m 成功: 输出与参考输出匹配\e[0m"
else else
echo -e "\e[31m 失败: 输出不匹配\e[0m" echo -e "\e[31m 失败: 输出不匹配\e[0m"
display_file_content "${output_reference_file}" " \e[36m---------- 期望输出 ----------\e[0m" "${MAX_OUTPUT_LINES}" display_file_content "${output_reference_file}" " \e[36m---------- 期望输出 ----------\e[0m" "${MAX_OUTPUT_LINES}" "${MAX_OUTPUT_CHARS}"
display_file_content "${output_actual_file_S}" " \e[36m---------- 实际输出 ----------\e[0m" "${MAX_OUTPUT_LINES}" display_file_content "${output_actual_file_S}" " \e[36m---------- 实际输出 ----------\e[0m" "${MAX_OUTPUT_LINES}" "${MAX_OUTPUT_CHARS}"
test_logic_passed=0 test_logic_passed=0
fi fi
fi fi

View File

@ -1007,6 +1007,7 @@ class PhiInst : public Instruction {
void replaceIncomingBlock(BasicBlock *oldBlock, BasicBlock *newBlock, Value *newValue); void replaceIncomingBlock(BasicBlock *oldBlock, BasicBlock *newBlock, Value *newValue);
void refreshMap() { void refreshMap() {
blk2val.clear(); blk2val.clear();
vsize = getNumOperands() / 2;
for (unsigned i = 0; i < vsize; ++i) { for (unsigned i = 0; i < vsize; ++i) {
blk2val[getIncomingBlock(i)] = getIncomingValue(i); blk2val[getIncomingBlock(i)] = getIncomingValue(i);
} }

View File

@ -109,6 +109,34 @@ public:
} }
// PHI指令消除相关方法
static bool eliminateRedundantPhisInFunction(Function* func){
bool changed = false;
std::vector<Instruction *> toDelete;
for (auto &bb : func->getBasicBlocks()) {
for (auto &inst : bb->getInstructions()) {
if (auto phi = dynamic_cast<PhiInst *>(inst.get())) {
auto incoming = phi->getIncomingValues();
if(DEBUG){
std::cout << "Checking Phi: " << phi->getName() << " with " << incoming.size() << " incoming values." << std::endl;
}
if (incoming.size() == 1) {
Value *singleVal = incoming[0].second;
inst->replaceAllUsesWith(singleVal);
toDelete.push_back(inst.get());
}
}
else
break; // 只处理Phi指令
}
}
for (auto *phi : toDelete) {
usedelete(phi);
changed = true; // 标记为已更改
}
return changed; // 返回是否有删除发生
}
//该实现参考了libdivide的算法 //该实现参考了libdivide的算法
static std::pair<int, int> computeMulhMagicNumbers(int divisor) { static std::pair<int, int> computeMulhMagicNumbers(int divisor) {

View File

@ -757,7 +757,7 @@ void BinaryInst::print(std::ostream &os) const {
auto lhs_hash = std::hash<const void*>{}(static_cast<const void*>(getLhs())); auto lhs_hash = std::hash<const void*>{}(static_cast<const void*>(getLhs()));
auto rhs_hash = std::hash<const void*>{}(static_cast<const void*>(getRhs())); auto rhs_hash = std::hash<const void*>{}(static_cast<const void*>(getRhs()));
size_t combined_hash = inst_hash ^ (lhs_hash << 1) ^ (rhs_hash << 2); size_t combined_hash = inst_hash ^ (lhs_hash << 1) ^ (rhs_hash << 2);
std::string tmpName = "tmp_icmp_" + std::to_string(combined_hash % 1000000); std::string tmpName = "tmp_icmp_" + std::to_string(combined_hash % 1000000007);
os << "%" << tmpName << " = " << getKindString() << " " << *getLhs()->getType() << " "; os << "%" << tmpName << " = " << getKindString() << " " << *getLhs()->getType() << " ";
printOperand(os, getLhs()); printOperand(os, getLhs());
os << ", "; os << ", ";
@ -772,7 +772,7 @@ void BinaryInst::print(std::ostream &os) const {
auto lhs_hash = std::hash<const void*>{}(static_cast<const void*>(getLhs())); auto lhs_hash = std::hash<const void*>{}(static_cast<const void*>(getLhs()));
auto rhs_hash = std::hash<const void*>{}(static_cast<const void*>(getRhs())); auto rhs_hash = std::hash<const void*>{}(static_cast<const void*>(getRhs()));
size_t combined_hash = inst_hash ^ (lhs_hash << 1) ^ (rhs_hash << 2); size_t combined_hash = inst_hash ^ (lhs_hash << 1) ^ (rhs_hash << 2);
std::string tmpName = "tmp_fcmp_" + std::to_string(combined_hash % 1000000); std::string tmpName = "tmp_fcmp_" + std::to_string(combined_hash % 1000000007);
os << "%" << tmpName << " = " << getKindString() << " " << *getLhs()->getType() << " "; os << "%" << tmpName << " = " << getKindString() << " " << *getLhs()->getType() << " ";
printOperand(os, getLhs()); printOperand(os, getLhs());
os << ", "; os << ", ";
@ -834,7 +834,7 @@ void CondBrInst::print(std::ostream &os) const {
if (condName.empty()) { if (condName.empty()) {
// 使用条件值地址的哈希值作为唯一标识 // 使用条件值地址的哈希值作为唯一标识
auto ptr_hash = std::hash<const void*>{}(static_cast<const void*>(condition)); auto ptr_hash = std::hash<const void*>{}(static_cast<const void*>(condition));
condName = "const_" + std::to_string(ptr_hash % 100000); condName = "const_" + std::to_string(ptr_hash % 1000000007);
} }
// 组合指令地址、条件地址和目标块地址的哈希来确保唯一性 // 组合指令地址、条件地址和目标块地址的哈希来确保唯一性
@ -843,7 +843,7 @@ void CondBrInst::print(std::ostream &os) const {
auto then_hash = std::hash<const void*>{}(static_cast<const void*>(getThenBlock())); auto then_hash = std::hash<const void*>{}(static_cast<const void*>(getThenBlock()));
auto else_hash = std::hash<const void*>{}(static_cast<const void*>(getElseBlock())); auto else_hash = std::hash<const void*>{}(static_cast<const void*>(getElseBlock()));
size_t combined_hash = inst_hash ^ (cond_hash << 1) ^ (then_hash << 2) ^ (else_hash << 3); size_t combined_hash = inst_hash ^ (cond_hash << 1) ^ (then_hash << 2) ^ (else_hash << 3);
std::string uniqueSuffix = std::to_string(combined_hash % 1000000); std::string uniqueSuffix = std::to_string(combined_hash % 1000000007);
os << "%tmp_cond_" << condName << "_" << uniqueSuffix << " = icmp ne i32 "; os << "%tmp_cond_" << condName << "_" << uniqueSuffix << " = icmp ne i32 ";
printOperand(os, condition); printOperand(os, condition);

View File

@ -74,6 +74,7 @@ void DCEContext::run(Function *func, AnalysisManager *AM, bool &changed) {
} }
} }
} }
changed |= SysYIROptUtils::eliminateRedundantPhisInFunction(func); // 如果有活跃指令,则标记为已更改
} }
// 判断指令是否是"天然活跃"的实现 // 判断指令是否是"天然活跃"的实现

View File

@ -39,7 +39,7 @@ bool GVN::runOnFunction(Function *func, AnalysisManager &AM) {
} }
std::cout << "=== GVN completed for function: " << func->getName() << " ===" << std::endl; std::cout << "=== GVN completed for function: " << func->getName() << " ===" << std::endl;
} }
changed |= SysYIROptUtils::eliminateRedundantPhisInFunction(func);
return changed; return changed;
} }

View File

@ -671,13 +671,13 @@ bool GlobalStrengthReductionContext::reduceDivision(BinaryInst *inst) {
} }
// x / c = x * magic_number (魔数乘法优化 - 使用libdivide算法) // x / c = x * magic_number (魔数乘法优化 - 使用libdivide算法)
if (isConstantInt(rhs, constVal) && constVal > 1 && constVal != (uint32_t)(-1)) { // if (isConstantInt(rhs, constVal) && constVal > 1 && constVal != (uint32_t)(-1)) {
// auto magicPair = computeMulhMagicNumbers(static_cast<int>(constVal)); // // auto magicPair = computeMulhMagicNumbers(static_cast<int>(constVal));
Value* magicResult = createMagicDivisionLibdivide(inst, static_cast<int>(constVal)); // Value* magicResult = createMagicDivisionLibdivide(inst, static_cast<int>(constVal));
replaceWithOptimized(inst, magicResult); // replaceWithOptimized(inst, magicResult);
divisionOptCount++; // divisionOptCount++;
return true; // return true;
} // }
return false; return false;
} }

View File

@ -133,6 +133,7 @@ bool InductionVariableEliminationContext::run(Function* F, AnalysisManager& AM)
printDebugInfo(); printDebugInfo();
} }
modified |= SysYIROptUtils::eliminateRedundantPhisInFunction(F);
return modified; return modified;
} }

View File

@ -661,9 +661,9 @@ bool StrengthReductionContext::replaceOriginalInstruction(StrengthReductionCandi
case StrengthReductionCandidate::DIVIDE_CONST: { case StrengthReductionCandidate::DIVIDE_CONST: {
// 任意常数除法 // 任意常数除法
builder->setPosition(candidate->containingBlock, // builder->setPosition(candidate->containingBlock,
candidate->containingBlock->findInstIterator(candidate->originalInst)); // candidate->containingBlock->findInstIterator(candidate->originalInst));
replacementValue = generateConstantDivisionReplacement(candidate, builder); // replacementValue = generateConstantDivisionReplacement(candidate, builder);
break; break;
} }
@ -683,17 +683,19 @@ bool StrengthReductionContext::replaceOriginalInstruction(StrengthReductionCandi
); );
// 检查原值是否为负数 // 检查原值是否为负数
Value* zero = ConstantInteger::get(0); Value* shift31condidata = builder->createBinaryInst(
Value* isNegative = builder->createICmpLTInst(candidate->inductionVar, zero); Instruction::Kind::kSra, candidate->inductionVar->getType(),
candidate->inductionVar, ConstantInteger::get(31)
);
// 如果为负数,需要调整结果 // 如果为负数,需要调整结果
Value* adjustment = ConstantInteger::get(candidate->multiplier); Value* adjustment = builder->createAndInst(shift31condidata, maskConstant);
Value* adjustedTemp = builder->createAddInst(temp, adjustment); Value* adjustedTemp = builder->createAddInst(candidate->inductionVar, adjustment);
Value* adjustedResult = builder->createBinaryInst(
// 使用条件分支来模拟select操作 Instruction::Kind::kAnd, candidate->inductionVar->getType(),
// 为简化起见,这里先用一个更复杂但可工作的方式 adjustedTemp, maskConstant
// 实际应该创建条件分支,但这里先简化处理 );
replacementValue = temp; // 简化版本,假设大多数情况下不是负数 replacementValue = adjustedResult;
} else { } else {
// 非负数的取模,直接使用位与 // 非负数的取模,直接使用位与
replacementValue = builder->createBinaryInst( replacementValue = builder->createBinaryInst(

View File

@ -1357,9 +1357,8 @@ void SCCPContext::run(Function *func, AnalysisManager &AM) {
bool changed_control_flow = SimplifyControlFlow(func); bool changed_control_flow = SimplifyControlFlow(func);
// 如果任何一个阶段修改了 IR标记分析结果为失效 // 如果任何一个阶段修改了 IR标记分析结果为失效
if (changed_constant_propagation || changed_control_flow) { bool changed = changed_constant_propagation || changed_control_flow;
// AM.invalidate(); // 假设有这样的方法来使所有分析结果失效 changed |= SysYIROptUtils::eliminateRedundantPhisInFunction(func);
}
} }
// SCCP Pass methods // SCCP Pass methods