Pull Request已成功合入, 合并人@openeuler-ci-bot
(感谢 haibaoo 的贡献)变更摘要
本 PR 回移 GCC trunk 中 GIMPLE switch loop unswitching 的实现及相关后续修复,核心改动集中在 gcc/tree-ssa-loop-unswitch.cc:将原先仅处理循环不变 if 条件的逻辑重写为同时支持 gswitch,引入 unswitch_predicate 缓存、gimple_ranger 值域查询、predicate path 简化机制,并重构统一代码增长预算与 hottest predicate 优先选择策略;同时回移类型转换、异常 SSA、CFG dominator 更新和 guard hoisting 等修复,移除 max-unswitch-level 参数并新增 21 个测试、调整 3 个已有 dump 扫描项。
主要改动
- 新增
switch循环解开关支持:find_unswitching_predicates_for_bb现在同时识别gcond与gswitch,将 switch 的非 default 边(含 case range)转换为unswitch_predicate并按gimple_uid缓存,支持基于循环不变switchindex 的 loop unswitching。 - 重构成本模型与 hottest 优先选择:
tree_unswitch_single_loop对同一原始循环维护统一budget,通过evaluate_loop_insns_for_predicate计算 true/false 两个版本的指令数,并按 profile count 优先选择最热的 predicate;本地修复让预选的 hottest predicate 也经过check_predicate的统一预算检查。 - 引入 Ranger 值域与 predicate path 简化:新增
gimple_ranger、predicate_path及evaluate_control_stmt_using_entry_checks、simplify_loop_version,利用值域和符号等价折叠gcond、标记不可达 switch 边,并在clean_up_after_unswitching中删除不可达边且重新计算 dominator 信息。 - 参数与调试项调整:删除
param_max_unswitch_level及其在gcc/params.opt、gcc/doc/invoke.texi中的定义和文档,并新增loop_unswitchdebug counter。 - 辅助修复与测试补充:
gcc/tree-cfg.cc的gimple_lv_add_condition_to_bb在插入前先对cond_expr调用force_gimple_operand_gsi_1,修复 guard hoisting 中条件语句的插入位置;gcc/cfgloopmanip.cc移除bb->aux = 0以免覆盖新成本信息;新增 21 个测试文件并调整 3 个 dump 扫描项的大小写。


Welcome To openEuler Community
Hey @qq_56722097 , thanks for your contribution to the community.
Bot Usage Manual
I'm the Bot here serving you. You can find the instructions on how to interact with me at Here . That means you can comment below every pull request or issue to trigger Bot Commands.
Contact Guide
If you have any questions, please contact the SIG: Compiler ,
and any of the maintainers: @SegFault, @alexanderbill, @cf-zhao, @chenzheng1030, @eastb233, @kuenking111_admin, @li-yancheng, @wangqiang95, @wd-gitcode ,
and any of the committers: @huang-xiaoquan, @huzife, @lin-4682, @xiongzhou4 .


门禁正在运行, 您可以通过以下链接查看实时门禁检查结果.
若您对门禁结果含义不清晰或者遇到问题不知如何解决,可参考门禁指导手册
门禁入口及编码规范检查: multiarch/openeuler/trigger/gcc/100/console


| Check Name | Build Result | 详情 | Build Details | |
|---|---|---|---|---|
| check_code | ❌FAILED | • CodeCheck检查发现代码缺陷,请查看报告: https://www.openlibing.com/apps/entryCheckDashCode/MR_0205ffe168ff4c7980b122df31043530/6469105bb58f4f0ab4303b17310a774d?projectId=300024&codeHostingPlatformFlag=gitcode | #100 | |
| check_package_license | ✅SUCCESS | |||
| x86_64 | check_build | ✅SUCCESS | #108 | |
| aarch64 | check_build | ✅SUCCESS | #100 | |


通过 Pass
AI 代码审阅
优点
- 该 PR 回移的是 GCC 上游
GIMPLE switchloop unswitching 功能,整体结构清晰:引入unswitch_predicate、Ranger 值域信息、统一预算和 hottest-first 选择,符合上游演进方向。 gcc/tree-cfg.cc中先通过force_gimple_operand_gsi_1将条件转换为合法 GIMPLE,再插入新条件,修改点集中,修复意图明确。- 新增测试覆盖较全,包括 signed/unsigned switch、range case、fallthrough、default edge、运行时副作用次数等;其中
loop-unswitch-18.c为运行时测试,能验证优化前后语义一致性。 gcc/dbgcnt.def新增loop_unswitchdebug counter,便于后续二分定位该 pass 的变换问题。gcc/doc/invoke.texi与gcc/params.opt对max-unswitch-level的删除保持一致,未发现文档与参数定义不同步。- PR 描述给出了 baseline 与 patched 回归测试对比,新增 PASS 与存量 FAIL 统计清晰,验证信息充分。
变更文件覆盖检查
| 文件 | 审查结果 |
|---|---|
gcc/cfgloopmanip.cc |
no proven issue;删除 bb->aux = 0 与新的 aux 生命周期管理相关,但本文件上下文未完全展示,未发现可见 diff 中的确定性缺陷 |
gcc/dbgcnt.def |
no proven issue;新增 counter 位置符合字母顺序 |
gcc/doc/invoke.texi |
no proven issue;仅删除 max-unswitch-level 文档 |
gcc/params.opt |
no proven issue;参数定义删除与文档一致,影响构建期生成的参数列表和用户命令行兼容性 |
gcc/testsuite/g++.dg/opt/pr105802.C |
no proven issue;新增编译回归用例 |
gcc/testsuite/g++.dg/tree-ssa/pr107876-2.C |
no proven issue;编译与 dump 扫描用例 |
gcc/testsuite/g++.dg/tree-ssa/pr107876.C |
no proven issue;编译与 dump 扫描用例 |
gcc/testsuite/gcc.dg/alias-10.c |
no proven issue;仅 dump 文本大小写适配 |
gcc/testsuite/gcc.dg/loop-unswitch-1.c |
no proven issue;仅 dump 文本大小写适配 |
gcc/testsuite/gcc.dg/loop-unswitch-10.c |
optional suggestion;存在 defaut: 拼写,疑似应为 default: |
gcc/testsuite/gcc.dg/loop-unswitch-11.c |
optional suggestion;同上 |
gcc/testsuite/gcc.dg/loop-unswitch-12.c |
no proven issue |
gcc/testsuite/gcc.dg/loop-unswitch-13.c |
no proven issue |
gcc/testsuite/gcc.dg/loop-unswitch-14.c |
optional suggestion;存在 defaut: 拼写,疑似应为 default: |
gcc/testsuite/gcc.dg/loop-unswitch-15.c |
no proven issue |
gcc/testsuite/gcc.dg/loop-unswitch-16.c |
no proven issue |
gcc/testsuite/gcc.dg/loop-unswitch-17.c |
no proven issue |
gcc/testsuite/gcc.dg/loop-unswitch-18.c |
no proven issue;运行时断言值经核查与循环副作用次数一致 |
gcc/testsuite/gcc.dg/loop-unswitch-7.c |
no proven issue |
gcc/testsuite/gcc.dg/loop-unswitch-8.c |
no proven issue |
gcc/testsuite/gcc.dg/loop-unswitch-9.c |
no proven issue |
gcc/testsuite/gcc.dg/pr105763.c |
no proven issue |
gcc/testsuite/gcc.dg/pr105770.c |
no proven issue |
gcc/testsuite/gcc.dg/torture/20220518-1.c |
no proven issue |
gcc/testsuite/gcc.dg/torture/20220518-2.c |
no proven issue |
gcc/testsuite/gcc.dg/torture/20220525-1.c |
no proven issue |
gcc/testsuite/gcc.dg/torture/pr111917.c |
no proven issue |
gcc/testsuite/gcc.dg/tree-ssa/loop-6.c |
no proven issue;仅 dump 文本大小写适配 |
gcc/tree-cfg.cc |
no proven issue;force_gimple_operand_gsi_1 修复合理 |
gcc/tree-ssa-loop-unswitch.cc |
no proven issue in visible diff;但该文件 diff 被截断,未能审查后续约 900 行核心实现和成本逻辑 |
需要修改的问题
未发现明确必须修改的问题。
可优化建议
-
Suggestion: 将
gcc/testsuite/gcc.dg/loop-unswitch-10.c、loop-unswitch-11.c、loop-unswitch-14.c中的defaut:更正为default:。- Reason: 从上下文看,这里显然是想给
switch提供一个不可达的 default 分支并调用__builtin_unreachable()。拼成defaut:只是一个普通 label,并不会成为switch的 default edge,因此测试语义与注释/意图不一致,且无法覆盖“default 不可达”的路径。 - Example:
switch (order) { case 0: ... break; ... default: __builtin_unreachable (); }
- Reason: 从上下文看,这里显然是想给
-
Suggestion: 确认移除
--param max-unswitch-level的用户可见兼容性是否需要额外说明。- Reason:
params.opt中删除该参数后,已有构建脚本、调优配置或用户命令行若显式传入--param max-unswitch-level=N,可能直接报错。上游移除通常可接受,但作为发行版 backport,建议确认是否需要 release note 或兼容性提示。 - Example: 暂不提供代码修改;如果关注兼容性,可保留为 deprecated/ignored 参数,并在文档中注明不再生效。
- Reason:
审阅结论
Severity: 通过
Conclusion: 建议通过
结论说明:
基于当前可见 diff,未发现确定性的编译错误、运行时语义错误或必须阻断合入的缺陷。gcc/tree-ssa-loop-unswitch.cc 是本次变更的核心文件,但 diff 被截断,后半部分 tree_unswitch_single_loop 的预算计算、CFG 简化、Ranger value-range 使用等关键逻辑未能完整审查;在 PR 自述的自举和 deja 回归通过的前提下,本次审阅不阻断合入。建议合入前顺手修正测试中 defaut 拼写,并确认移除 max-unswitch-level 参数对下游用户的影响。
Review metadata:
- PR: #391
- Latest commit:
bf5a9bd4886dd197880e65dc7af567b0d412e13c - Changed lines: 1940
- Review mode: focused
- Reviewed files: 30/30


/lgtm
/approve


PR功能描述 / 为什么需要这个合入:
回移 GCC trunk 中 GIMPLE switch loop unswitching 的实现及相关后续修复。
原有 loop unswitching 主要处理循环中的不变
if条件。本 PR 增加对循环不变switchindex 的支持:预先收集循环中的 unswitch predicates,复制循环后使用 Ranger 提供的值域信息简化各个版本中的
switch和条件分支。同时重构 unswitch 成本模型,对同一个原始循环的所有 unswitch 机会使用统一的代码增长预算,并优先选择 profile count 最高的条件,避免先处理收
益较低的分支。
本 PR 还回移了 switch unswitching 后续发现的类型转换、异常 SSA、CFG dominator 更新和 guard hoisting 修复,并增加 EulerGCC 本地预算修复,
防止 hottest predicate 绕过正常的循环复制成本检查。
希望检视人员了解的内容:
本 PR 包含以下 8 个 GCC 上游提交:
主要上游修改包括:
switchindex 进行 loop unswitching。switch和条件语句。本 PR 包含一个 EulerGCC 本地 bugfix:
hottest-first 实现会直接选中最热 predicate,但原逻辑没有为该 predicate 计算两个特化循环的大小,因此可能绕过统一的代码增长预算。
本地修复让预选的 hottest predicate 和普通 DFS predicate 共用相同的成本计算及预算检查。当复制后的两个循环超过预算时,不再执行该次
unswitch。
本 PR 包含一个 EulerGCC 本地运行时测试
loop-unswitch-18.c,覆盖:本 PR 共新增 21 个测试文件,并调整 3 个已有 loop-unswitch dump 测试。相关上游问题包括:
核心修改位于 GCC 通用 GIMPLE loop unswitching Pass,不包含 AArch64 或 x86 后端专用功能修改。验证在 x86_64-linux-gnu 上完成。
Checklist:
PR格式
功能验证
修改涉及后端架构
patched:
回归测试通过。本 PR 新增 switch loop unswitching、后续 bugfix 及本地预算和运行时测试,因此 expected PASS 数量有所增加。
baseline:
patched:
contrib/compare_tests未发现新增 FAIL:gcc.sum新增 75 个预期 PASS。g++.sum新增 19 个预期 PASS。gfortran.sum没有变化。Unswitching调整为unswitching而被新的扫描项替代,不是测试回归。gnu++98模式下按预期标记为 UNSUPPORTED。