12 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
语言规范
主要使用中文交流、写注释、写文档和 commit message。代码标识符(变量名、函数名、类名)和文件名使用英文。
项目概述
SysY → ARM64/AArch64 编译器,CMake + C++17 + ANTLR 4.13.2。2026 编译系统设计赛(华为毕昇杯)ARM 赛道参赛项目。
构建
# 首次:生成 ANTLR Lexer/Parser
mkdir -p build/generated/antlr4
java -jar third_party/antlr-4.13.2-complete.jar -Dlanguage=Cpp -visitor -no-listener \
-Xexact-output-dir -o build/generated/antlr4 src/antlr4/SysY.g4
# 全量构建
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DCOMPILER_PARSE_ONLY=OFF
cmake --build build -j "$(nproc)"
可执行文件:./build/bin/compiler
编译器 CLI(比赛格式)
compiler -S -o output.s input.sy # 汇编输出(比赛标准)
compiler -S -o output.s input.sy -O # 带优化
compiler --emit-ir input.sy # 打印 IR
compiler --emit-parse-tree input.sy # 打印语法树
架构
编译管线:SysY → [frontend] ANTLR 语法树 → [sem] 语义分析 → [irgen] IR 生成 → [ir/passes] IR 优化 → [mir/Lowering] MIR 降级 → [mir/RegAlloc] 寄存器分配 → [mir/FrameLowering] 栈帧 → [mir/peephole] 窥孔 → [mir/AsmPrinter] AArch64 汇编
源码目录:
src/frontend/— ANTLR 驱动、语法树打印src/sem/— Sema、SymbolTable、ConstEvalsrc/irgen/— 语法树 → LLVM IR 翻译src/ir/— IR 数据结构(Module→Function→BasicBlock→Instruction),passes/ 含 Mem2Reg/CFGSimplify/ConstFold/ConstProp/DCE/CSE/LICMsrc/mir/— 机器 IR(MachineModule→MachineFunction→MachineBasicBlock→MachineInstr),Lowering/RegAlloc/FrameLowering/AsmPrinter/Peepholesrc/include/— 各模块头文件
关键设计:IR 类型支持 void/i1/i32/float/i32*/float*;MIR 操作数为 PhysReg/VReg/Imm/FrameIndex/Label/Symbol;-O 触发所有 IR pass;GP 可分配集含 x16/x17;xzr/wzr 为零寄存器,sp 为栈指针。
一、安全第一:编译器优化的生存法则
竞赛红线(零容忍,违反即取消成绩)
- 禁止投机优化:不得识别特定函数名、字符串、输入特征来激活优化
- 禁止硬编码结果:不得对计算结果预设答案
- 禁止依赖 UB:不得假设数组不越界、除法不溢出等
- 优化必须通用:对所有合法 SysY2026 程序语义保持
段错误预防(从历史故障中提炼的高危区)
| 区域 | 常见根因 | 预防规则 |
|---|---|---|
| 寄存器分配 | 合并后颜色/degree 不一致 | 合并后总是重算 degree;不修改遍历中的容器 |
| 栈帧 | 大偏移量(>12KB)ldr/str 溢出 | 大栈帧必须用 movz/movk 合成偏移 |
| 活变量分析 | 干涉 vreg 错误复用同一寄存器 | shift 链等密集 def-use 模式需保守干涉边(block defs>20 时全干涉) |
| spill | 无限 spill 循环 | 大函数(>120 vregs)限制 spill 轮次 ≤5 |
| 活跃合并 | 干涉图边不完整 | Briggs 保守测试:邻居 degree≥K 计数 < K |
| 迭代器 | move_adj 自环导致失效 | 合并前检查 u != v,清理后验证 |
优化安全性自检清单
实现任何优化变换时必须确认:
- 对所有合法 SysY2026 程序,语义是否保持?
- 副作用顺序是否保持?(Load/Store/Call 不能重排跨越彼此)
- 浮点语义是否保持?(不能随意重关联)
- 是否有针对特定测试用例的投机判断?(有则违规)
修改范围限制
- 一次只改一个 pass 或一个模块
- 寄存器分配和 IR 优化不能混在一次改动中
- 改 MIR 层前先确认 IR 层正确性基线
二、性能北极星:指令数驱动的开发循环
核心循环(不可跳步)
假设 → 测量基线 → 实现 → 正确性验证 → 性能测量 → 决策
↑ |
└──────────── 回退或调整 ←─────────────────────────────┘
| 步骤 | 命令/动作 |
|---|---|
| 假设 | 写一句话:「改 X,预期指令数减少 Y 条」 |
| 基线 | ./count_asm.sh |
| 实现 | 写代码 |
| 正确性 | ./2026test.sh -c functional -x && ./2026test.sh -c h_functional -x |
| 性能 | ./count_asm.sh |
| 决策 | 对比基线,判断合并/调整/回退 |
指令数作为核心指标
指令数(wc -l 汇编)无测量噪声、可复现。目标硬件 Cortex-A53 为顺序核,指令数与运行时间相关性较高。指令数减少是积极信号但非绝对保证。
性能退化门禁
| 规模 | 动作 |
|---|---|
| 大面积退化(>5 用例) | 阻止合并,分析根因 |
| 少量退化(2-5 用例,<5%) | 标记关注,分析根因,记录到 commit |
| 零散退化(1-2 用例,<2%) | 可容忍,注明到 commit |
| 零退化 + 改善 | 理想,更新基线,合并 |
基线管理
指令数基线.md 记录历史最低值,count_asm.sh 自动维护——新值更低时才更新。性能改善 commit 须附带基线更新。
三、AI 协作协议
任务规模 → 流程映射
| 规模 | 特征 | 流程 |
|---|---|---|
| 轻量 | 单文件、阈值调整、明显 bug(<30 分钟) | 直接改 → 快门禁 → commit |
| 中量 | 跨文件、新 pass、算法改动(1-4 小时) | brainstorming → 计划 → 实现 → 快门禁 → 中门禁 |
| 重量 | 寄存器分配重构、IR 框架(多日) | office-hours → GSD 全流程 → 全门禁 → extract-learnings |
提示词模式
- 先说为什么再说做什么:告诉 AI 目标(「减少 spill 代码量」)而非操作(「修改 spillCost 函数」)
- 先计划后代码:要求 AI 先提变更计划,审查通过后再写代码。即使是「简单」改动
- 显式约束前置:一次性给出所有约束(红线、修改范围、语义安全要求)
- 小 diff(≤200 行):大改动分步进行;大 diff 的审查成本超过生成收益
AI 不能做的事
- 不能自行验证自己生成的代码——必须通过编译器运行和测试脚本等外部工具验证
- 不能决定核心算法设计——可以建议和实现,最终设计由人审查
- 不能跳过门禁——任何改动都必须过测试
- AI 生成的测试不能作为唯一的正确性验证——需要独立的外部 oracle(.out 对比)
DeepSeek 特化策略
- 开启 thinking mode:复杂推理任务使用
reasoning_effort: max - 利用上下文缓存:同一文件反复读取几乎免费,大胆多次参考已有代码
- 分割大 prompt:DeepSeek 在独立小任务上表现最好
- C++ 代码 double-check:DeepSeek 在系统编程上偏弱,指针/迭代器/内存操作需额外验证
MCP 使用铁律
| 场景 | 工具 | 不要 |
|---|---|---|
| 查找符号 | codegraph_search |
不要 grep |
| 调用关系 | codegraph_callers/callees |
不要手动 Read 追踪 |
| 改动影响 | codegraph_impact |
不要猜测 |
| 代码区探索 | codegraph_explore(一次) |
不要逐个 codegraph_node |
| 字面量搜索 | grep |
不要用 codegraph 搜 |
| PR 管理 | gh create_pr/create_review |
不要手动 |
四、三层门禁
数据集优先级
- 一级:
2026test/(竞赛官方,有 .out,每次必跑) - 二级:
test_merged/、testdata2022/、testdata2024/(历史回归,关键节点跑)
快门禁(每次 commit 前,~2 分钟)
./2026test.sh -c functional -x && ./2026test.sh -c h_functional -x
通过标准:0 失败。失败则阻止 commit。
中门禁(每次 merge 前,~10 分钟)
./2026test.sh -c functional -x
./2026test.sh -c h_functional -x
./2026test.sh -c performance -x
./count_asm.sh
通过标准:0 功能失败 + 指令数无大面积退化。
全门禁(关键节点,~30 分钟)
./2026test.sh # 全量
# 历史数据集回归
for f in test_merged/**/*.sy; do
./scripts/verify_asm.sh "$f" --run -O || echo "FAIL: $f"
done
触发条件:寄存器分配重构、IR 框架改动、赛前验证。
门禁纪律
- 绝不跳过门禁——改动能通过门禁才是真的「完成」
- 功能测试失败时绝不进入性能测量——先修正确性
- 门禁失败后修复再跑——不允许「先合并后修复」
五、代码与 Git 规范
命名
- 变量:
snake_case;函数/类:PascalCase;成员变量:snake_case_ - 标识符和文件名用英文
中文规范
注释、commit message、文档、错误信息用中文。IR/MIR 调试打印用英文。
// 使用 Briggs 保守测试而非 George,因为 O(k) vs O(k^2)
if (HasMovePair(u)) ReactivatePairs(u);
Git
格式:<type>(<scope>): <中文简述>。一 commit 一逻辑变更。不提交编译或测试失败的代码。功能分支开发,master 保护。
六、自进化机制
触发条件
- 故障驱动:段错误、性能退化、测试失败 → 诊断根因 → 可预防则更新本规范
- 成功固化:新优化方法被验证有效 → 记录模式
- 定期审查:每两周 review 本规范,删除过时规则,强化有效规则
操作流程
故障发生 → 根因分析(中文 ≤100 字)
→ 可预防?
├─ 是 → 更新 CLAUDE.md 或 memory
└─ 否 → 只记录
有效性度量
- 同类 bug 是否再次出现
- 门禁是否在 commit 前拦截了问题
- 指令数趋势是否持续改善
七、Skill & MCP 最优编排
仅保留有用的工具
本项目是 C++ 编译器,以下可用工具有价值:
- MCP:codegraph(代码智能,始终预加载),github 通过 ToolSearch 按需加载或直接用 gh CLI
- 流程 skill:brainstorming、writing-plans、TDD、verification-before-completion、systematic-debugging
- 门禁 skill:gsd-code-review、review
- 战略 skill(仅多日架构决策):gsd-discuss/plan/execute-phase、office-hours、gsd-extract-learnings、ship
ToolSearch 机制(ENABLE_TOOL_SEARCH: true):非预授权的 MCP 工具 schema 延迟加载,调用时通过 ToolSearch 按需获取,减少 token 消耗。
以下已禁用或忽略:qa/browse/benchmark/canary(Web)、figma/react-bits/chrome(已通过 disabledMcpjsonServers 禁用)、cso/security-review(Web 安全)、impeccable/design-*(前端)
三种模式
快刀(<30 分钟)
codegraph_context → 直接改 → 快门禁 → commit
只用 Superpowers 战术层。示例:调阈值、修明显 bug。
标准优化(1-4 小时)
brainstorming → writing-plans → TDD → 快门禁 → gsd-code-review → 中门禁 → commit
brainstorming 是强制的——「太简单不需要设计」是反模式。
重器(多日)
office-hours → gsd-discuss → gsd-plan → gsd-execute(内含 TDD 循环)
→ 全门禁 → gsd-code-review → gsd-extract-learnings → ship
只在 3-4 个关键架构点使用。编译器反馈循环很快,偏向执行而非过度计划。
最高 ROI 组合
bug 发现 → codegraph_impact(影响范围)
→ gh create_issue(用 impact 结果作 body)
→ brainstorming(设计方案)
→ TDD(先写会失败的测试)
→ 实现 → verification(快门禁)
→ gh create_pr
每一步都有外部信号验证,避免 AI 自说自话。
自进化闭环
gsd-extract-learnings → 更新 CLAUDE.md/memory
↑ ↓
全门禁验证 下次任务自动加载
↑ ↓
实现优化 AI 知道上次的教训