已开启
cj-barrier-opt: 修改BarrierNeed 算法 #596
睡觉对我很重要创建于 24 天前
cj-barrier-opt: 修改BarrierNeed 算法 #596
已开启
睡觉对我很重要创建于 24 天前
睡觉对我很重要
睡觉对我很重要仓颉Developer
24 天前

变更内容

重构 CJBarrierOptBarrierNeed 的 safepoint 路径分析(llvm/lib/Transforms/Scalar/CJBarrierOpt.cpp,+72 / -215,净减 143 行):

  • 移除 LoopInfo 依赖:legacy pass 的 getAnalysisUsage 不再 addRequired<LoopInfoWrapperPass> / addPreservedINITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass) 一并移除;new-PM run 不再消费 ModuleAnalysisManager
  • 重写 BarrierNeed::run() 算法:用「反向 BFS 求 CanReachEnd(从 End 往回标记能到达的 BB)+ 前向 worklist 单调 OR-join 不动点(SafepointFlow)」替换旧的「LoopInfo + SameParentLoop + loop-latch 扫描 + 反复 isPotentiallyReachable DFS」。新算法总体 O(V+E),旧算法因按 succ/pred 反复调用 DFS 近似 O(E·(V+E))。
  • BarriersCheck 构造与 optCJBarrierModule 同步去掉 LoopInfo 形参。

性能(合成压测)

third_party/generate_barrier_need_stress.py 生成:100 个 gc "cangjie" 函数 × 3 层嵌套循环 × 每层 4 菱形 = 7700 基本块;该 IR 用 @CJ_MCC_NewObject fresh malloc + 普通 memcpy 写含 GC ref 的 %record 进 fresh 对象,触发 barriersCheckFail → BarrierNeed 的真实路径;--safepoint-mode none 使其全遍历不 abort。opt --cj-barrier-opt -time-passes,取 CJBarrierOpt pass user time,各 5 轮:

版本 5 轮耗时(秒,升序)
重构前(HEAD~1) 0.0014 / 0.0052 / 0.0053 / 0.0056 / 0.0057
重构后(HEAD) 0.0009 / 0.0009 / 0.0010 / 0.0011 / 0.0011

中位数约 5× 提速。

等价性

llvm-lit llvm/test/Transforms/CJBarrierOpt/ 重构前后均 22/23 通过;对每个用例 opt --cj-barrier-opt -S 的输出,HEAD 与 HEAD~1 byte-identical(diff 为空)。唯一失败用例 barrierarray5.ll 与本次重构无关——源于更早的 int_cj_gcwrite_struct intrinsic 把 size 参数从固定 i64 改为重载 anyint,导致 intrinsic 名多 .i64 后缀,CHECK 未同步更新。

变更类型

请描述本次Pull Request变更类型(原因),请在对应类型的括号内填写Y

  • 新增需求(Y)
  • 问题修复( )
  • 构建过程或辅助工具变动()
  • 文档更新()

变更内容自检

编译器及标准库编译通过截图证明(如涉及新增需求、问题修复、构建过程变动需提供)

仅改 LLVM pass llvm/lib/Transforms/Scalar/CJBarrierOpt.cppninja -C <llvm-build> opt 增量编译通过(4 步重链);未触及仓颉编译器/标准库源码与构建。

测试用例本地自验证通过截图证明(如涉及新增需求、问题修复需提供)

  • llvm-lit llvm/test/Transforms/CJBarrierOpt/:22/23 通过(与重构前一致)。
  • 性能基准:python3 third_party/generate_barrier_need_stress.py --functions 100 --nested-loops 3 --diamonds 4 --exits 3 --merged-preds 4 --safepoint-mode none -o bench.ll && opt --cj-barrier-opt -time-passes -disable-output bench.ll

其他信息

关联 issue: https://gitcode.com/Cangjie/llvm-project/issues/185

likedislike
CLA协议签署
当前Pull Request的提交暂无外部代码贡献者
合并受阻
睡觉对我很重要睡觉对我很重要仓颉Developer
24 天前 关联了issue:[Feature]: 重构 CJBarrierOpt 的 BarrierNeed 算法以提升编译性能
cangjie-ci成员
24 天前 评论:

PR创建成功通知 | 感谢您的贡献 🎉

您好!系统已检测到您成功创建 Pull Request(PR),感谢您对项目的支持与参与!以下几点需要您着重关注:

一、PR必须关联Issue ❗️

触发门禁检查的必要步骤:在PR描述框输入Issue完整链接,完成Issue关联

请注意,一个 Issue 不能同时关联同一 base 仓库内同一个分支的多个开启状态的 PR

二、门禁触发规则 🔧

  1. 门禁类型判定:由Issue关联的PR所属代码仓数量决定
    • 关联多个代码仓PR:触发「多仓联合门禁」
    • 关联单个代码仓PR:触发「单仓门禁」
  2. 启动指令与检查范围:需主动回复指令:
    • 回复 "start build":执行Cangjie的主要基础检查,包含commit格式检查、静态告警分析、OAT开源声明检查、多平台构建、单元/集成测试等
    • 关联同一issue的多个PR,仅需在任意一个PR里回复触发一次门禁,该PR门禁通过后,所有PR都会添加Label和测试人
    • 每个pr只能同时运行一条CI流水线,如需重新启动,请先关闭运行中的,再评论触发门禁
    • Markdown修改仅触发文档类构建测试门禁,不会触发Cangjie的编译测试门禁
    • commit 信息格式请遵循:Conventional Commits 规范
    • 请保证每一条 commit 都已添加 Signed-Off-By 信息
    • 回复 "start build cov":执行覆盖率构建工程,生成该提交的增量代码覆盖率报告

三、合入条件 ⚠️

  • 满足最低评审人数,且评审问题需全部解决;
  • 禁止合入本人创建的PR,需由其他协作者操作;
  • 合并前确保关联流水线任务运行成功(build-test-passed)。

四、合并PR ✅

回复 "start merge",CI流水线会自动检查所有关联PR的状态、版本号标签、检视意见密度、兼容性,若所有PR都满足合并条件,则将会同时合并所有PR。若存在不满足合并条件的PR,则不会合并任何PR。

如果希望不进行兼容性相关的检测,请任一合法审查人复制以下内容,在 start merge 前提交评论:

本 pr 不需要兼容性相关检测,对于引发的任何兼容性问题(即由于本 pr 合入将导致用户需适配代码的话),由本人承担。

If you wish to avoid compatibility-related checks, please have any approver copy the following content and submit it as a comment before sending start merge:

This PR does not require compatibility-related checks. For any compatibility issues caused by this PR (i.e., if the integration of this PR will require users to adapt their code), I will take full responsibility.

五、补充说明 📢

likedislike
Ccangjie-ci维护者
24 天前 添加了label:1.3.0-alpha.01waiting-start-build
Ccangjie-ci维护者
24 天前 重置了测试状态
睡觉对我很重要睡觉对我很重要仓颉Developer
24 天前 修改标题为 “perf(cj-barrier-opt): 修改BarrierNeed 算法”,原标题为“perf(cj-barrier-opt): 重构 BarrierNeed 算法并移除 LoopInfo 依赖”
睡觉对我很重要
睡觉对我很重要成员23 天前进行代码检视1
llvm/lib/Transforms/Scalar/CJBarrierOpt.cpp
已过期
@@ -107,4 +94,2 @@
10794 }
10895 }
109- if (SameParentLoop != nullptr && isLoopLatch(BB, LoopLatches)) {
110- continue;
睡觉对我很重要
睡觉对我很重要23 天前评论:

原始逻辑太繁琐了 , 对于 遇到loop的情况, 并不是所有的都会用到 scanlooppath(),

likedislike
睡觉对我很重要
睡觉对我很重要成员23 天前进行代码检视1
llvm/lib/Transforms/Scalar/CJBarrierOpt.cpp
已过期
@@ -185,4 +142,0 @@
185- // If Succ is a node of the same big loop, Succ is a node of path.
186- // Otherwise, SuccLoop is a loop node of path.
187- if ((SuccLoop != nullptr && SameParentLoop != nullptr &&
188- SuccLoop != SameParentLoop) ||
睡觉对我很重要
睡觉对我很重要23 天前评论:

当 Begin 和 End 位于同一个共同 loop 时,并不会 使用scanpathloop()

likedislike
睡觉对我很重要
睡觉对我很重要成员23 天前进行代码检视1
llvm/lib/Transforms/Scalar/CJBarrierOpt.cpp
@@ -107,0 +86,4 @@
86+ SmallVector<BasicBlock *> ReachabilityWorklist;
87+ CanReachEnd.insert(EndBB);
88+ ReachabilityWorklist.push_back(EndBB);
89+ while (!ReachabilityWorklist.empty()) {
睡觉对我很重要
睡觉对我很重要23 天前评论:

原始的逻辑中, 复杂的地方在于 对于 loop的判断,对于 begin 跟end 是否 在同一个块中会分成两种情况。 新实现的逻辑 先 收集ReachabilityWorklist 去去掉 在同一个loop中, 这样会显得清爽很多。

likedislike
睡觉对我很重要
睡觉对我很重要成员
22 天前 评论:

start build

likedislike
Ccangjie-ci维护者
22 天前 删除了label:waiting-start-build
Ccangjie-ci维护者
22 天前 添加了label:CI-running
cangjie-ci成员
22 天前 评论:

CI门禁流水线已启动,正在后台运行中,您可以点击Pipeline Detail查看运行状态。
门禁工作流:

graph LR
    A[PR检测] --> B[联合构建]
    B[联合构建] --> C[测试运行]

检查内容包括

  • commitlint检查
  • 构建任务
    • linux x64、mac aarch64、windows x64
  • 测试任务
    • UT、HLT、LLT

门禁产物归档路径: obs://cangjie103/CangjieDaily/pub/ci/gate/main/llvm-project/596

likedislike
Ccangjie-ci维护者
22 天前 添加了label:commitlint-passedsign-off-passed
Ccangjie-ci维护者
22 天前 添加了label:OAT-passed
cangjie-ci成员
22 天前 评论:

Codecheck检查失败,共发现 11 个静态告警。

Cangjie/llvm-project PR #596

文件 行号 告警类型
llvm/lib/Transforms/Scalar/CJBarrierOpt.cpp 82 G.FMT.02-CPP 使用空格进行缩进,每次缩进4个空格
llvm/lib/Transforms/Scalar/CJBarrierOpt.cpp 90 G.FMT.02-CPP 使用空格进行缩进,每次缩进4个空格
llvm/lib/Transforms/Scalar/CJBarrierOpt.cpp 93 G.FMT.02-CPP 使用空格进行缩进,每次缩进4个空格
llvm/lib/Transforms/Scalar/CJBarrierOpt.cpp 145 G.FMT.02-CPP 使用空格进行缩进,每次缩进4个空格
llvm/lib/Transforms/Scalar/CJBarrierOpt.cpp 147 G.FMT.02-CPP 使用空格进行缩进,每次缩进4个空格
llvm/lib/Transforms/Scalar/CJBarrierOpt.cpp 149 G.FMT.02-CPP 使用空格进行缩进,每次缩进4个空格
llvm/lib/Transforms/Scalar/CJBarrierOpt.cpp 152 G.FMT.02-CPP 使用空格进行缩进,每次缩进4个空格
llvm/lib/Transforms/Scalar/CJBarrierOpt.cpp 154 G.FMT.02-CPP 使用空格进行缩进,每次缩进4个空格
llvm/lib/Transforms/Scalar/CJBarrierOpt.cpp 156 G.FMT.02-CPP 使用空格进行缩进,每次缩进4个空格
llvm/lib/Transforms/Scalar/CJBarrierOpt.cpp 159 G.FMT.02-CPP 使用空格进行缩进,每次缩进4个空格
llvm/lib/Transforms/Scalar/CJBarrierOpt.cpp 162 G.FMT.02-CPP 使用空格进行缩进,每次缩进4个空格

查看 Pipeline 详情

likedislike
Ccangjie-ci维护者
22 天前 删除了label:CI-running
Ccangjie-ci维护者
22 天前 添加了label:codecheck-failedwaiting-start-build
Ccangjie-ci维护者
22 天前 删除了label:waiting-start-build
Ccangjie-ci维护者
22 天前 删除了label:codecheck-failed
Ccangjie-ci维护者
22 天前 添加了label:CI-runningcodecheck-passed
Ccangjie-ci维护者
22 天前 通过测试
cangjie-ci成员
22 天前 评论:

您提交的 PR 已顺利通过全部门禁检查流程,当前状态符合合入标准✅。具体检查结果如下:

  • Commit 检查:代码提交信息规范性、完整性、Signed Off信息验证通过,无格式或逻辑问题✓;
  • 代码构建:编译过程无报错,依赖项加载正常,构建产物完整性达标🔧;
  • 测试验证:单元测试、集成测试等各类用例执行完毕,全部通过验证🧪。

目前该 PR 已完全具备合入条件,可按项目流程推进后续合入操作。感谢您的严谨开发与协作,期待代码顺利合入🎉!

likedislike
Ccangjie-ci维护者
22 天前 删除了label:CI-running
Ccangjie-ci维护者
22 天前 添加了label:build-test-passed
yanjsyanjs仓颉Developer
21 天前 将yanjs设为评审人
yanjsyanjs仓颉Developer
21 天前 通过了评审
睡觉对我很重要睡觉对我很重要仓颉Developer
8 天前 修改标题为 “cj-barrier-opt: 修改BarrierNeed 算法”,原标题为“perf(cj-barrier-opt): 修改BarrierNeed 算法”