From ce4d4b5f5b9035639bb75442864be858cbde6233 Mon Sep 17 00:00:00 2001 From: rain2133 <1370973498@qq.com> Date: Tue, 19 Aug 2025 01:08:05 +0800 Subject: [PATCH 1/6] =?UTF-8?q?[midend-phielimination]=E5=A2=9E=E5=8A=A0ph?= =?UTF-8?q?i=E6=8C=87=E4=BB=A4=E6=B6=88=E9=99=A4=E6=A3=80=E6=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../midend/Pass/Optimize/SysYIROptUtils.h | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/include/midend/Pass/Optimize/SysYIROptUtils.h b/src/include/midend/Pass/Optimize/SysYIROptUtils.h index 48d2f26..71c0532 100644 --- a/src/include/midend/Pass/Optimize/SysYIROptUtils.h +++ b/src/include/midend/Pass/Optimize/SysYIROptUtils.h @@ -109,6 +109,28 @@ public: } + // PHI指令消除相关方法 + static void eliminateRedundantPhisInFunction(Function* func){ + std::vector toDelete; + for (auto &bb : func->getBasicBlocks()) { + for (auto &inst : bb->getInstructions()) { + if (auto phi = dynamic_cast(inst.get())) { + auto incoming = phi->getIncomingValues(); + if (incoming.size() == 1) { + Value *singleVal = incoming[0].first; + inst->replaceAllUsesWith(singleVal); + toDelete.push_back(inst.get()); + } + } + else + break; // 只处理Phi指令 + } + } + for (auto *phi : toDelete) { + usedelete(phi); + } + } + //该实现参考了libdivide的算法 static std::pair computeMulhMagicNumbers(int divisor) { From db122cabbdbfb4ff5b49b79efb5e9d4322c26db0 Mon Sep 17 00:00:00 2001 From: rain2133 <1370973498@qq.com> Date: Tue, 19 Aug 2025 08:27:18 +0800 Subject: [PATCH 2/6] =?UTF-8?q?[midend-phielimination]=E6=B6=88=E9=99=A4?= =?UTF-8?q?=E5=8F=AA=E6=9C=89=E4=B8=80=E4=B8=AAincomingvalue=E7=9A=84phi?= =?UTF-8?q?=E6=8C=87=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/include/midend/Pass/Optimize/SysYIROptUtils.h | 10 ++++++++-- src/midend/Pass/Optimize/DCE.cpp | 1 + src/midend/Pass/Optimize/GVN.cpp | 2 +- .../Pass/Optimize/InductionVariableElimination.cpp | 1 + src/midend/Pass/Optimize/SCCP.cpp | 5 ++--- 5 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/include/midend/Pass/Optimize/SysYIROptUtils.h b/src/include/midend/Pass/Optimize/SysYIROptUtils.h index 71c0532..81062e1 100644 --- a/src/include/midend/Pass/Optimize/SysYIROptUtils.h +++ b/src/include/midend/Pass/Optimize/SysYIROptUtils.h @@ -110,14 +110,18 @@ public: // PHI指令消除相关方法 - static void eliminateRedundantPhisInFunction(Function* func){ + static bool eliminateRedundantPhisInFunction(Function* func){ + bool changed = false; std::vector toDelete; for (auto &bb : func->getBasicBlocks()) { for (auto &inst : bb->getInstructions()) { if (auto phi = dynamic_cast(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].first; + Value *singleVal = incoming[0].second; inst->replaceAllUsesWith(singleVal); toDelete.push_back(inst.get()); } @@ -128,7 +132,9 @@ public: } for (auto *phi : toDelete) { usedelete(phi); + changed = true; // 标记为已更改 } + return changed; // 返回是否有删除发生 } //该实现参考了libdivide的算法 diff --git a/src/midend/Pass/Optimize/DCE.cpp b/src/midend/Pass/Optimize/DCE.cpp index 06a4822..f89781e 100644 --- a/src/midend/Pass/Optimize/DCE.cpp +++ b/src/midend/Pass/Optimize/DCE.cpp @@ -74,6 +74,7 @@ void DCEContext::run(Function *func, AnalysisManager *AM, bool &changed) { } } } + changed |= SysYIROptUtils::eliminateRedundantPhisInFunction(func); // 如果有活跃指令,则标记为已更改 } // 判断指令是否是"天然活跃"的实现 diff --git a/src/midend/Pass/Optimize/GVN.cpp b/src/midend/Pass/Optimize/GVN.cpp index 09b67a1..047ae52 100644 --- a/src/midend/Pass/Optimize/GVN.cpp +++ b/src/midend/Pass/Optimize/GVN.cpp @@ -39,7 +39,7 @@ bool GVN::runOnFunction(Function *func, AnalysisManager &AM) { } std::cout << "=== GVN completed for function: " << func->getName() << " ===" << std::endl; } - + changed |= SysYIROptUtils::eliminateRedundantPhisInFunction(func); return changed; } diff --git a/src/midend/Pass/Optimize/InductionVariableElimination.cpp b/src/midend/Pass/Optimize/InductionVariableElimination.cpp index 8055efa..56bb22a 100644 --- a/src/midend/Pass/Optimize/InductionVariableElimination.cpp +++ b/src/midend/Pass/Optimize/InductionVariableElimination.cpp @@ -133,6 +133,7 @@ bool InductionVariableEliminationContext::run(Function* F, AnalysisManager& AM) printDebugInfo(); } + modified |= SysYIROptUtils::eliminateRedundantPhisInFunction(F); return modified; } diff --git a/src/midend/Pass/Optimize/SCCP.cpp b/src/midend/Pass/Optimize/SCCP.cpp index 8fbda0b..d0fa138 100644 --- a/src/midend/Pass/Optimize/SCCP.cpp +++ b/src/midend/Pass/Optimize/SCCP.cpp @@ -1357,9 +1357,8 @@ void SCCPContext::run(Function *func, AnalysisManager &AM) { bool changed_control_flow = SimplifyControlFlow(func); // 如果任何一个阶段修改了 IR,标记分析结果为失效 - if (changed_constant_propagation || changed_control_flow) { - // AM.invalidate(); // 假设有这样的方法来使所有分析结果失效 - } + bool changed = changed_constant_propagation || changed_control_flow; + changed |= SysYIROptUtils::eliminateRedundantPhisInFunction(func); } // SCCP Pass methods From 1d59e9e2566f69d76a162bd22cce00e39536b2f1 Mon Sep 17 00:00:00 2001 From: Lixuanwang Date: Tue, 19 Aug 2025 08:29:43 +0800 Subject: [PATCH 3/6] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=84=9A=E6=9C=AC?= =?UTF-8?q?=EF=BC=8C=E5=A2=9E=E5=BC=BA=E8=BE=93=E5=87=BA=E6=88=AA=E6=96=AD?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- script/runit-single.sh | 31 ++++++++++++++++++++++--------- script/runit.sh | 33 ++++++++++++++++++++++----------- 2 files changed, 44 insertions(+), 20 deletions(-) diff --git a/script/runit-single.sh b/script/runit-single.sh index bfbbcdc..786986f 100644 --- a/script/runit-single.sh +++ b/script/runit-single.sh @@ -20,18 +20,19 @@ QEMU_RISCV64="qemu-riscv64" # --- 初始化变量 --- EXECUTE_MODE=false -IR_EXECUTE_MODE=false # 新增 +IR_EXECUTE_MODE=false CLEAN_MODE=false OPTIMIZE_FLAG="" SYSYC_TIMEOUT=30 -LLC_TIMEOUT=10 # 新增 +LLC_TIMEOUT=10 GCC_TIMEOUT=10 EXEC_TIMEOUT=30 MAX_OUTPUT_LINES=20 +MAX_OUTPUT_CHARS=1000 SY_FILES=() PASSED_CASES=0 FAILED_CASES_LIST="" -INTERRUPTED=false # 新增 +INTERRUPTED=false # ================================================================= # --- 函数定义 --- @@ -50,22 +51,31 @@ show_help() { echo " -gct N 设置 gcc 交叉编译超时为 N 秒 (默认: 10)。" echo " -et N 设置 qemu 自动化执行超时为 N 秒 (默认: 30)。" echo " -ml N, --max-lines N 当输出对比失败时,最多显示 N 行内容 (默认: 20)。" + echo " -mc N, --max-chars N 当输出对比失败时,最多显示 N 个字符 (默认: 1000)。" echo " -h, --help 显示此帮助信息并退出。" echo "" echo "可在任何时候按 Ctrl+C 来中断测试并显示当前已完成的测例总结。" } +# 显示文件内容并根据行数和字符数截断的函数 display_file_content() { local file_path="$1" local title="$2" local max_lines="$3" + local max_chars="$4" # 新增参数 if [ ! -f "$file_path" ]; then return; fi echo -e "$title" local line_count + local char_count line_count=$(wc -l < "$file_path") + char_count=$(wc -c < "$file_path") + if [ "$line_count" -gt "$max_lines" ]; then 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 cat "$file_path" 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 ;; -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 ;; + -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 ;; -*) echo "未知选项: $1"; show_help; exit 1 ;; *) @@ -180,6 +191,8 @@ TOTAL_CASES=${#SY_FILES[@]} echo "SysY 单例测试运行器启动..." 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 "失败输出最大行数: ${MAX_OUTPUT_LINES}" +echo "失败输出最大字符数: ${MAX_OUTPUT_CHARS}" echo "" for sy_file in "${SY_FILES[@]}"; do @@ -260,8 +273,8 @@ for sy_file in "${SY_FILES[@]}"; do out_ok=1 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 - display_file_content "${EXPECTED_STDOUT_FILE}" " \e[36m--- 期望输出 ---\e[0m" "${MAX_OUTPUT_LINES}" - display_file_content "${output_actual_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}" "${MAX_OUTPUT_CHARS}" 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" else 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_actual_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}" "${MAX_OUTPUT_CHARS}" fi fi else @@ -301,4 +314,4 @@ for sy_file in "${SY_FILES[@]}"; do done # --- 打印最终总结 --- -print_summary \ No newline at end of file +print_summary diff --git a/script/runit.sh b/script/runit.sh index e27c905..c090415 100644 --- a/script/runit.sh +++ b/script/runit.sh @@ -27,11 +27,12 @@ LLC_TIMEOUT=10 GCC_TIMEOUT=10 EXEC_TIMEOUT=30 MAX_OUTPUT_LINES=20 +MAX_OUTPUT_CHARS=1000 TEST_SETS=() TOTAL_CASES=0 PASSED_CASES=0 FAILED_CASES_LIST="" -INTERRUPTED=false # 新增:用于标记是否被中断 +INTERRUPTED=false # ================================================================= # --- 函数定义 --- @@ -53,6 +54,7 @@ show_help() { echo " -gct N 设置 gcc 交叉编译超时为 N 秒 (默认: 10)。" echo " -et N 设置 qemu 执行超时为 N 秒 (默认: 30)。" echo " -ml N, --max-lines N 当输出对比失败时,最多显示 N 行内容 (默认: 20)。" + echo " -mc N, --max-chars N 当输出对比失败时,最多显示 N 个字符 (默认: 1000)。" echo " -h, --help 显示此帮助信息并退出。" echo "" echo "注意: 默认行为 (无 -e 或 -eir) 是将 .sy 文件同时编译为 .s (汇编) 和 .ll (IR),不执行。" @@ -60,18 +62,25 @@ show_help() { } -# 显示文件内容并根据行数截断的函数 +# 显示文件内容并根据行数和字符数截断的函数 display_file_content() { local file_path="$1" local title="$2" local max_lines="$3" + local max_chars="$4" # 新增参数 if [ ! -f "$file_path" ]; then return; fi echo -e "$title" local line_count + local char_count line_count=$(wc -l < "$file_path") + char_count=$(wc -c < "$file_path") + if [ "$line_count" -gt "$max_lines" ]; then 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 cat "$file_path" 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 ;; -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 ;; + -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 ;; *) echo "未知选项: $1"; show_help; exit 1 ;; esac @@ -204,6 +214,7 @@ echo "运行模式: ${RUN_MODE_INFO}" echo "${TIMEOUT_INFO}" if ${EXECUTE_MODE} || ${IR_EXECUTE_MODE}; then echo "失败输出最大行数: ${MAX_OUTPUT_LINES}" + echo "失败输出最大字符数: ${MAX_OUTPUT_CHARS}" fi echo "" @@ -298,8 +309,8 @@ while IFS= read -r sy_file; do [ "$test_logic_passed" -eq 1 ] && echo -e "\e[32m 标准输出测试成功\e[0m" else echo -e "\e[31m 标准输出测试失败\e[0m" - display_file_content "${EXPECTED_STDOUT_FILE}" " \e[36m---------- 期望输出 ----------\e[0m" "${MAX_OUTPUT_LINES}" - display_file_content "${output_actual_file_from_ir}" " \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}" "${MAX_OUTPUT_CHARS}" test_logic_passed=0 fi else @@ -308,8 +319,8 @@ while IFS= read -r sy_file; do echo -e "\e[32m 成功: 输出与参考输出匹配\e[0m" else echo -e "\e[31m 失败: 输出不匹配\e[0m" - display_file_content "${output_reference_file}" " \e[36m---------- 期望输出 ----------\e[0m" "${MAX_OUTPUT_LINES}" - display_file_content "${output_actual_file_from_ir}" " \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}" "${MAX_OUTPUT_CHARS}" test_logic_passed=0 fi fi @@ -375,8 +386,8 @@ while IFS= read -r sy_file; do [ "$test_logic_passed" -eq 1 ] && echo -e "\e[32m 标准输出测试成功\e[0m" else echo -e "\e[31m 标准输出测试失败\e[0m" - display_file_content "${EXPECTED_STDOUT_FILE}" " \e[36m---------- 期望输出 ----------\e[0m" "${MAX_OUTPUT_LINES}" - display_file_content "${output_actual_file_S}" " \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}" "${MAX_OUTPUT_CHARS}" test_logic_passed=0 fi else @@ -385,8 +396,8 @@ while IFS= read -r sy_file; do echo -e "\e[32m 成功: 输出与参考输出匹配\e[0m" else echo -e "\e[31m 失败: 输出不匹配\e[0m" - display_file_content "${output_reference_file}" " \e[36m---------- 期望输出 ----------\e[0m" "${MAX_OUTPUT_LINES}" - display_file_content "${output_actual_file_S}" " \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}" "${MAX_OUTPUT_CHARS}" test_logic_passed=0 fi fi From ad5f35c1a0816a142caaab8a242836ca23a3ec20 Mon Sep 17 00:00:00 2001 From: rain2133 <1370973498@qq.com> Date: Tue, 19 Aug 2025 08:56:51 +0800 Subject: [PATCH 4/6] =?UTF-8?q?[midend]=E6=9A=82=E6=97=B6=E4=BB=85?= =?UTF-8?q?=E7=94=A8=E4=BA=86=E9=AD=94=E6=95=B0=E4=BC=98=E5=8C=96=E9=99=A4?= =?UTF-8?q?=E6=B3=95=E7=9A=84=E6=89=8B=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Pass/Optimize/GlobalStrengthReduction.cpp | 14 +++++----- .../Pass/Optimize/LoopStrengthReduction.cpp | 26 ++++++++++--------- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/src/midend/Pass/Optimize/GlobalStrengthReduction.cpp b/src/midend/Pass/Optimize/GlobalStrengthReduction.cpp index e8254a2..404cf7b 100644 --- a/src/midend/Pass/Optimize/GlobalStrengthReduction.cpp +++ b/src/midend/Pass/Optimize/GlobalStrengthReduction.cpp @@ -671,13 +671,13 @@ bool GlobalStrengthReductionContext::reduceDivision(BinaryInst *inst) { } // x / c = x * magic_number (魔数乘法优化 - 使用libdivide算法) - if (isConstantInt(rhs, constVal) && constVal > 1 && constVal != (uint32_t)(-1)) { - // auto magicPair = computeMulhMagicNumbers(static_cast(constVal)); - Value* magicResult = createMagicDivisionLibdivide(inst, static_cast(constVal)); - replaceWithOptimized(inst, magicResult); - divisionOptCount++; - return true; - } + // if (isConstantInt(rhs, constVal) && constVal > 1 && constVal != (uint32_t)(-1)) { + // // auto magicPair = computeMulhMagicNumbers(static_cast(constVal)); + // Value* magicResult = createMagicDivisionLibdivide(inst, static_cast(constVal)); + // replaceWithOptimized(inst, magicResult); + // divisionOptCount++; + // return true; + // } return false; } diff --git a/src/midend/Pass/Optimize/LoopStrengthReduction.cpp b/src/midend/Pass/Optimize/LoopStrengthReduction.cpp index 0edbed4..33751df 100644 --- a/src/midend/Pass/Optimize/LoopStrengthReduction.cpp +++ b/src/midend/Pass/Optimize/LoopStrengthReduction.cpp @@ -661,9 +661,9 @@ bool StrengthReductionContext::replaceOriginalInstruction(StrengthReductionCandi case StrengthReductionCandidate::DIVIDE_CONST: { // 任意常数除法 - builder->setPosition(candidate->containingBlock, - candidate->containingBlock->findInstIterator(candidate->originalInst)); - replacementValue = generateConstantDivisionReplacement(candidate, builder); + // builder->setPosition(candidate->containingBlock, + // candidate->containingBlock->findInstIterator(candidate->originalInst)); + // replacementValue = generateConstantDivisionReplacement(candidate, builder); break; } @@ -683,17 +683,19 @@ bool StrengthReductionContext::replaceOriginalInstruction(StrengthReductionCandi ); // 检查原值是否为负数 - Value* zero = ConstantInteger::get(0); - Value* isNegative = builder->createICmpLTInst(candidate->inductionVar, zero); + Value* shift31condidata = builder->createBinaryInst( + Instruction::Kind::kSra, candidate->inductionVar->getType(), + candidate->inductionVar, ConstantInteger::get(31) + ); // 如果为负数,需要调整结果 - Value* adjustment = ConstantInteger::get(candidate->multiplier); - Value* adjustedTemp = builder->createAddInst(temp, adjustment); - - // 使用条件分支来模拟select操作 - // 为简化起见,这里先用一个更复杂但可工作的方式 - // 实际应该创建条件分支,但这里先简化处理 - replacementValue = temp; // 简化版本,假设大多数情况下不是负数 + Value* adjustment = builder->createAndInst(shift31condidata, maskConstant); + Value* adjustedTemp = builder->createAddInst(candidate->inductionVar, adjustment); + Value* adjustedResult = builder->createBinaryInst( + Instruction::Kind::kAnd, candidate->inductionVar->getType(), + adjustedTemp, maskConstant + ); + replacementValue = adjustedResult; } else { // 非负数的取模,直接使用位与 replacementValue = builder->createBinaryInst( From 8094fd57051edb080cfec6e925829c40f60b8cf9 Mon Sep 17 00:00:00 2001 From: rain2133 <1370973498@qq.com> Date: Tue, 19 Aug 2025 09:45:42 +0800 Subject: [PATCH 5/6] =?UTF-8?q?[midend]=E5=87=8F=E5=B0=91tmp=5Fcond?= =?UTF-8?q?=E7=9A=84=E5=86=B2=E7=AA=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/include/midend/IR.h | 1 + src/midend/IR.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/include/midend/IR.h b/src/include/midend/IR.h index 92539dc..9148edc 100644 --- a/src/include/midend/IR.h +++ b/src/include/midend/IR.h @@ -1007,6 +1007,7 @@ class PhiInst : public Instruction { void replaceIncomingBlock(BasicBlock *oldBlock, BasicBlock *newBlock, Value *newValue); void refreshMap() { blk2val.clear(); + vsize = getNumOperands() / 2; for (unsigned i = 0; i < vsize; ++i) { blk2val[getIncomingBlock(i)] = getIncomingValue(i); } diff --git a/src/midend/IR.cpp b/src/midend/IR.cpp index d35e16b..5ed1777 100644 --- a/src/midend/IR.cpp +++ b/src/midend/IR.cpp @@ -757,7 +757,7 @@ void BinaryInst::print(std::ostream &os) const { auto lhs_hash = std::hash{}(static_cast(getLhs())); auto rhs_hash = std::hash{}(static_cast(getRhs())); 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() << " "; printOperand(os, getLhs()); os << ", "; @@ -772,7 +772,7 @@ void BinaryInst::print(std::ostream &os) const { auto lhs_hash = std::hash{}(static_cast(getLhs())); auto rhs_hash = std::hash{}(static_cast(getRhs())); 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() << " "; printOperand(os, getLhs()); os << ", "; @@ -834,7 +834,7 @@ void CondBrInst::print(std::ostream &os) const { if (condName.empty()) { // 使用条件值地址的哈希值作为唯一标识 auto ptr_hash = std::hash{}(static_cast(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{}(static_cast(getThenBlock())); auto else_hash = std::hash{}(static_cast(getElseBlock())); 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 "; printOperand(os, condition); From d72601d9dbdbd1af73db62ea432e98c0152010bb Mon Sep 17 00:00:00 2001 From: Lixuanwang Date: Tue, 19 Aug 2025 15:08:00 +0800 Subject: [PATCH 6/6] =?UTF-8?q?=E5=8F=96=E6=B6=88=E8=B7=9F=E8=B8=AAperform?= =?UTF-8?q?ance=E6=B5=8B=E8=AF=95=E7=94=A8=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index c10e61c..32dccde 100644 --- a/.gitignore +++ b/.gitignore @@ -36,7 +36,7 @@ doxygen !/testdata/functional/*.out !/testdata/h_functional/*.out -!/testdata/performance/*.out +testdata/performance/ build/ .antlr .vscode/