diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..cbd782bc --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,134 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +SysY 编译器课程实验 — a progressive compiler (Lab1–Lab6) for the SysY language (a C subset) targeting ARM64/AArch64. Built with C++17, CMake, and ANTLR4. + +## Build Commands + +### Prerequisites +```bash +# Install dependencies (Ubuntu 22.04 / WSL) +sudo apt install -y build-essential cmake git openjdk-11-jre llvm clang gcc-aarch64-linux-gnu qemu-user +``` + +### Generate ANTLR Lexer/Parser (required before first build) +```bash +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 +``` + +### Lab1 (frontend only — parse tree printing) +```bash +cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DCOMPILER_PARSE_ONLY=ON +cmake --build build -j "$(nproc)" +./build/bin/compiler --emit-parse-tree test/test_case/functional/simple_add.sy +``` + +### Full build (all labs, including IR gen, optimization, and codegen) +```bash +cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DCOMPILER_PARSE_ONLY=OFF +cmake --build build -j "$(nproc)" +``` + +## Compiler Usage + +```bash +# Competition format: compile to assembly +./build/bin/compiler -S -o output.s input.sy + +# With optimization +./build/bin/compiler -S -o output.s input.sy -O1 + +# Emit IR +./build/bin/compiler --emit-ir input.sy + +# Single test: compile, link, run with QEMU, and compare output +./scripts/verify_asm.sh test/test_case/functional/simple_add.sy --run + +# Same for IR path (uses llc + clang to compile/run) +./scripts/verify_ir.sh test/test_case/functional/simple_add.sy --run +``` + +### CLI Options +| Flag | Effect | +|------|--------| +| `-S` | Emit assembly (default when no mode specified) | +| `-o ` | Output file path | +| `-O`, `-O1`, `-O2`, `-O3` | Optimization level | +| `--emit-parse-tree` | Print ANTLR parse tree | +| `--emit-ir` | Print LLVM-style IR | +| `--emit-asm` | Print AArch64 assembly | +| `-h`, `--help` | Show help | + +## Testing + +### Main test harness +```bash +# Run all 2026test functional tests with optimization +./2026test.sh + +# Functional tests only, max 10 cases, stop on first failure +./2026test.sh -c functional -n 10 -x + +# Without optimization +./2026test.sh -O0 +``` + +### Legacy test scripts +```bash +./test1.sh # Lab1: syntax tree +./test2.sh # Lab2: IR generation +./test3.sh # Lab3: assembly generation +./test4.sh # Lab4: scalar optimization +./test5.sh # Lab5: register allocation +``` + +## Architecture + +### Compiler Pipeline +``` +SysY source (.sy) → ANTLR Lexer/Parser → AST (ANTLR parse tree) + → Sema (name resolution, type checking) → IR (LLVM-style, load/store form) + → IR Passes (Mem2Reg → LICM → ConstFold/Prop/DCE/CFG/CSE) → MIR (machine IR, AArch64) + → RegAlloc → FrameLowering → Peephole → AArch64 Assembly output +``` + +### Source Layout + +| Directory | Purpose | +|-----------|---------| +| `src/antlr4/SysY.g4` | ANTLR grammar for SysY language | +| `src/frontend/` | ANTLR driver + syntax tree printer (Lab1) | +| `src/sem/` | Semantic analysis: name binding, scope, type checking (Lab2 prep) | +| `src/irgen/` | IR generation via ANTLR visitor: Decl, Exp, Stmt, Func (Lab2) | +| `src/ir/` | LLVM-style IR: Value/User/Use hierarchy, Module/Function/BasicBlock, IRBuilder (Lab2) | +| `src/ir/passes/` | Scalar optimizations (Lab4): Mem2Reg, ConstFold, ConstProp, DCE, CFGSimplify, CSE, LICM | +| `src/ir/analysis/` | DominatorTree, LoopInfo | +| `src/mir/` | Machine IR + AArch64 backend (Lab3, Lab5): Lowering (IR→MIR), RegAlloc, FrameLowering, AsmPrinter | +| `src/mir/passes/` | MIR peephole pass | +| `src/utils/` | CLI argument parsing, logging | +| `src/include/` | **Build-time headers.** At build time CMake adds `src/include` as include path. | +| `include/` | **Platform-provided headers.** Gitignored — supplied externally by grading platform. Mirrors `src/include/`. | +| `sylib/` | SysY runtime library (sylib.c), linked into final executables | +| `scripts/` | verify_asm.sh, verify_ir.sh — single-case test helpers | +| `third_party/` | ANTLR jar + antlr4-runtime sources | +| `test/test_case/` | Reference test cases with expected outputs | + +### Key Design Patterns + +- **IR IR**: Lightweight LLVM-style IR with `Value → User → Instruction` class hierarchy and def-use chains via `Use` objects. `IRBuilder` appends instructions to a `BasicBlock`. The IR starts in load/store (alloca-based) form; `Mem2Reg` promotes allocas to SSA phi nodes. +- **MIR IR**: Lower-level, three-address machine IR using AArch64 opcodes and a union-like `Operand` (reg, vreg, imm, frame index, label, symbol). Purely a data container — no SSA, no def-use analysis. +- **ANTLR Visitor**: `IRGenImpl` extends the ANTLR-generated `SysYBaseVisitor` to walk the parse tree and emit IR. Each `visit*` method returns `std::any` (typically `ir::Value*`). +- **Pass infrastructure**: Each IR pass is a standalone function (`RunMem2Reg`, `RunDCE`, etc.) taking a `Module&`. `PassManager` and `PassManagerModule` orchestrate them with fixed-point iteration (serialize, compare, re-run until convergence). + +### Important Notes + +- The `#if COMPILER_PARSE_ONLY` macro in `main.cpp` guards all code beyond Lab1. The CMake option `COMPILER_PARSE_ONLY` controls whether `sem`, `irgen`, and `mir` subdirectories are built. +- `include/` is in `.gitignore` and absent from the build include path. It is provided externally by the grading platform. When editing headers, work in `src/include/`. +- The grammar `SysY.g4` defines the SysY language subset: `int`/`float`/`void` types, arrays, `const`, `if`/`else`/`while`/`break`/`continue`/`return`, and C-like expressions including logical short-circuit `&&`/`||`. +- Commit message convention: `(): ` where type ∈ {feat, fix, refactor, docs, test, chore} and scope ∈ {frontend, irgen, backend, test, doc}. diff --git a/指令数基线.md b/指令数基线.md index 3e7ba722..20f97d64 100644 --- a/指令数基线.md +++ b/指令数基线.md @@ -21,66 +21,66 @@ | 测试集标识 | 源基线(行) | 当前(行) | 备注 | |---|---|---|---| -| performance/01_mm1 | 335 | 313 | 比源基线少22行 | 比源基线少22行 | 比源基线少8行 | | -| performance/01_mm2 | 335 | 313 | 比源基线少22行 | 比源基线少22行 | 比源基线少8行 | | -| performance/01_mm3 | 335 | 313 | 比源基线少22行 | 比源基线少22行 | 比源基线少8行 | | -| performance/03_sort1 | 668 | 640 | 比源基线少28行 | 比源基线少28行 | 比源基线少14行 | | -| performance/03_sort2 | 668 | 640 | 比源基线少28行 | 比源基线少28行 | 比源基线少14行 | | -| performance/03_sort3 | 668 | 640 | 比源基线少28行 | 比源基线少28行 | 比源基线少14行 | | -| performance/conv2d-1 | 752 | 657 | 比源基线少95行 | 比源基线少95行 | 比源基线少20行 | | -| performance/conv2d-2 | 752 | 657 | 比源基线少95行 | 比源基线少95行 | 比源基线少20行 | | -| performance/conv2d-3 | 752 | 657 | 比源基线少95行 | 比源基线少95行 | 比源基线少20行 | | -| performance/crc1 | 328 | 290 | 比源基线少38行 | 比源基线少38行 | 比源基线少10行 | | -| performance/crc2 | 328 | 290 | 比源基线少38行 | 比源基线少38行 | 比源基线少10行 | | -| performance/crc3 | 328 | 290 | 比源基线少38行 | 比源基线少38行 | 比源基线少10行 | | -| performance/crypto-1 | 1967 | 1949 | 比源基线少18行 | 比源基线少18行 | 比源基线少14行 | | -| performance/crypto-2 | 1967 | 1949 | 比源基线少18行 | 比源基线少18行 | 比源基线少14行 | | -| performance/crypto-3 | 1967 | 1949 | 比源基线少18行 | 比源基线少18行 | 比源基线少14行 | | -| performance/fft0 | 658 | 619 | 比源基线少39行 | 比源基线少39行 | 比源基线少30行 | | -| performance/fft1 | 658 | 619 | 比源基线少39行 | 比源基线少39行 | 比源基线少30行 | | -| performance/fft2 | 658 | 619 | 比源基线少39行 | 比源基线少39行 | 比源基线少30行 | | -| performance/h-1-01 | 162 | 158 | 比源基线少4行 | 比源基线少4行 | 比源基线少2行 | | -| performance/h-1-02 | 162 | 158 | 比源基线少4行 | 比源基线少4行 | 比源基线少2行 | | -| performance/h-1-03 | 162 | 158 | 比源基线少4行 | 比源基线少4行 | 比源基线少2行 | | -| performance/h-10-01 | 349 | 335 | 比源基线少14行 | 比源基线少14行 | 比源基线少6行 | | -| performance/h-10-02 | 349 | 335 | 比源基线少14行 | 比源基线少14行 | 比源基线少6行 | | -| performance/h-10-03 | 349 | 335 | 比源基线少14行 | 比源基线少14行 | 比源基线少6行 | | -| performance/h-4-01 | 173 | 163 | 比源基线少10行 | 比源基线少10行 | 比源基线少6行 | | -| performance/h-4-02 | 173 | 163 | 比源基线少10行 | 比源基线少10行 | 比源基线少6行 | | -| performance/h-4-03 | 173 | 163 | 比源基线少10行 | 比源基线少10行 | 比源基线少6行 | | +| performance/01_mm1 | 335 | 310 | 比源基线少25行 | 比源基线少22行 | 比源基线少22行 | 比源基线少8行 | | +| performance/01_mm2 | 335 | 310 | 比源基线少25行 | 比源基线少22行 | 比源基线少22行 | 比源基线少8行 | | +| performance/01_mm3 | 335 | 310 | 比源基线少25行 | 比源基线少22行 | 比源基线少22行 | 比源基线少8行 | | +| performance/03_sort1 | 668 | 640 | 比源基线少28行 | 比源基线少28行 | 比源基线少28行 | 比源基线少14行 | | +| performance/03_sort2 | 668 | 640 | 比源基线少28行 | 比源基线少28行 | 比源基线少28行 | 比源基线少14行 | | +| performance/03_sort3 | 668 | 640 | 比源基线少28行 | 比源基线少28行 | 比源基线少28行 | 比源基线少14行 | | +| performance/conv2d-1 | 752 | 629 | 比源基线少123行 | 比源基线少95行 | 比源基线少95行 | 比源基线少20行 | | +| performance/conv2d-2 | 752 | 629 | 比源基线少123行 | 比源基线少95行 | 比源基线少95行 | 比源基线少20行 | | +| performance/conv2d-3 | 752 | 629 | 比源基线少123行 | 比源基线少95行 | 比源基线少95行 | 比源基线少20行 | | +| performance/crc1 | 328 | 290 | 比源基线少38行 | 比源基线少38行 | 比源基线少38行 | 比源基线少10行 | | +| performance/crc2 | 328 | 290 | 比源基线少38行 | 比源基线少38行 | 比源基线少38行 | 比源基线少10行 | | +| performance/crc3 | 328 | 290 | 比源基线少38行 | 比源基线少38行 | 比源基线少38行 | 比源基线少10行 | | +| performance/crypto-1 | 1967 | 1949 | 比源基线少18行 | 比源基线少18行 | 比源基线少18行 | 比源基线少14行 | | +| performance/crypto-2 | 1967 | 1949 | 比源基线少18行 | 比源基线少18行 | 比源基线少18行 | 比源基线少14行 | | +| performance/crypto-3 | 1967 | 1949 | 比源基线少18行 | 比源基线少18行 | 比源基线少18行 | 比源基线少14行 | | +| performance/fft0 | 658 | 605 | 比源基线少53行 | 比源基线少39行 | 比源基线少39行 | 比源基线少30行 | | +| performance/fft1 | 658 | 605 | 比源基线少53行 | 比源基线少39行 | 比源基线少39行 | 比源基线少30行 | | +| performance/fft2 | 658 | 605 | 比源基线少53行 | 比源基线少39行 | 比源基线少39行 | 比源基线少30行 | | +| performance/h-1-01 | 162 | 158 | 比源基线少4行 | 比源基线少4行 | 比源基线少4行 | 比源基线少2行 | | +| performance/h-1-02 | 162 | 158 | 比源基线少4行 | 比源基线少4行 | 比源基线少4行 | 比源基线少2行 | | +| performance/h-1-03 | 162 | 158 | 比源基线少4行 | 比源基线少4行 | 比源基线少4行 | 比源基线少2行 | | +| performance/h-10-01 | 349 | 329 | 比源基线少20行 | 比源基线少14行 | 比源基线少14行 | 比源基线少6行 | | +| performance/h-10-02 | 349 | 329 | 比源基线少20行 | 比源基线少14行 | 比源基线少14行 | 比源基线少6行 | | +| performance/h-10-03 | 349 | 329 | 比源基线少20行 | 比源基线少14行 | 比源基线少14行 | 比源基线少6行 | | +| performance/h-4-01 | 173 | 163 | 比源基线少10行 | 比源基线少10行 | 比源基线少10行 | 比源基线少6行 | | +| performance/h-4-02 | 173 | 163 | 比源基线少10行 | 比源基线少10行 | 比源基线少10行 | 比源基线少6行 | | +| performance/h-4-03 | 173 | 163 | 比源基线少10行 | 比源基线少10行 | 比源基线少10行 | 比源基线少6行 | | | performance/h-5-01 | 352 | 349 | 比源基线少3行 | 比源基线少3行 | 比源基线少10行 | | | performance/h-5-02 | 352 | 349 | 比源基线少3行 | 比源基线少3行 | 比源基线少10行 | | | performance/h-5-03 | 352 | 349 | 比源基线少3行 | 比源基线少3行 | 比源基线少10行 | | -| performance/h-8-01 | 504 | 502 | 比源基线少2行 | 比源基线少2行 | 比源基线少2行 | | -| performance/h-8-02 | 504 | 502 | 比源基线少2行 | 比源基线少2行 | 比源基线少2行 | | -| performance/h-8-03 | 504 | 502 | 比源基线少2行 | 比源基线少2行 | 比源基线少2行 | | -| performance/h-9-01 | 239 | 227 | 比源基线少12行 | 比源基线少12行 | 比源基线少2行 | | -| performance/h-9-02 | 239 | 227 | 比源基线少12行 | 比源基线少12行 | 比源基线少2行 | | -| performance/h-9-03 | 239 | 227 | 比源基线少12行 | 比源基线少12行 | 比源基线少2行 | | -| performance/huffman-01 | 893 | 849 | 比源基线少44行 | 比源基线少44行 | 比源基线少14行 | | -| performance/huffman-02 | 893 | 849 | 比源基线少44行 | 比源基线少44行 | 比源基线少14行 | | -| performance/huffman-03 | 893 | 849 | 比源基线少44行 | 比源基线少44行 | 比源基线少14行 | | -| performance/knapsack_naive-1 | 185 | 175 | 比源基线少10行 | 比源基线少10行 | 比源基线少10行 | | -| performance/knapsack_naive-2 | 185 | 175 | 比源基线少10行 | 比源基线少10行 | 比源基线少10行 | | -| performance/knapsack_naive-3 | 185 | 175 | 比源基线少10行 | 比源基线少10行 | 比源基线少10行 | | +| performance/h-8-01 | 504 | 502 | 比源基线少2行 | 比源基线少2行 | 比源基线少2行 | 比源基线少2行 | | +| performance/h-8-02 | 504 | 502 | 比源基线少2行 | 比源基线少2行 | 比源基线少2行 | 比源基线少2行 | | +| performance/h-8-03 | 504 | 502 | 比源基线少2行 | 比源基线少2行 | 比源基线少2行 | 比源基线少2行 | | +| performance/h-9-01 | 239 | 227 | 比源基线少12行 | 比源基线少12行 | 比源基线少12行 | 比源基线少2行 | | +| performance/h-9-02 | 239 | 227 | 比源基线少12行 | 比源基线少12行 | 比源基线少12行 | 比源基线少2行 | | +| performance/h-9-03 | 239 | 227 | 比源基线少12行 | 比源基线少12行 | 比源基线少12行 | 比源基线少2行 | | +| performance/huffman-01 | 893 | 829 | 比源基线少64行 | 比源基线少44行 | 比源基线少44行 | 比源基线少14行 | | +| performance/huffman-02 | 893 | 829 | 比源基线少64行 | 比源基线少44行 | 比源基线少44行 | 比源基线少14行 | | +| performance/huffman-03 | 893 | 829 | 比源基线少64行 | 比源基线少44行 | 比源基线少44行 | 比源基线少14行 | | +| performance/knapsack_naive-1 | 185 | 167 | 比源基线少18行 | 比源基线少10行 | 比源基线少10行 | 比源基线少10行 | | +| performance/knapsack_naive-2 | 185 | 167 | 比源基线少18行 | 比源基线少10行 | 比源基线少10行 | 比源基线少10行 | | +| performance/knapsack_naive-3 | 185 | 167 | 比源基线少18行 | 比源基线少10行 | 比源基线少10行 | 比源基线少10行 | | | performance/many_mat_cal-1 | 523 | 523 | | | performance/many_mat_cal-2 | 523 | 523 | | | performance/many_mat_cal-3 | 523 | 523 | | | performance/matmul1 | 450 | 450 | | | performance/matmul2 | 450 | 450 | | | performance/matmul3 | 450 | 450 | | -| performance/optimization_scheduling1 | 136 | 122 | 比源基线少14行 | 比源基线少14行 | 比源基线少6行 | | -| performance/optimization_scheduling2 | 136 | 122 | 比源基线少14行 | 比源基线少14行 | 比源基线少6行 | | -| performance/optimization_scheduling3 | 136 | 122 | 比源基线少14行 | 比源基线少14行 | 比源基线少6行 | | -| performance/shuffle0 | 485 | 472 | 比源基线少13行 | 比源基线少13行 | 比源基线少6行 | | -| performance/shuffle1 | 485 | 472 | 比源基线少13行 | 比源基线少13行 | 比源基线少6行 | | -| performance/shuffle2 | 485 | 472 | 比源基线少13行 | 比源基线少13行 | 比源基线少6行 | | -| performance/sl1 | 283 | 280 | 比源基线少3行 | 比源基线少3行 | 比源基线少8行 | | -| performance/sl2 | 283 | 280 | 比源基线少3行 | 比源基线少3行 | 比源基线少8行 | | -| performance/sl3 | 283 | 280 | 比源基线少3行 | 比源基线少3行 | 比源基线少8行 | | -| performance/transpose0 | 225 | 211 | 比源基线少14行 | 比源基线少14行 | 比源基线少4行 | | -| performance/transpose1 | 225 | 211 | 比源基线少14行 | 比源基线少14行 | 比源基线少4行 | | -| performance/transpose2 | 225 | 211 | 比源基线少14行 | 比源基线少14行 | 比源基线少4行 | | +| performance/optimization_scheduling1 | 136 | 122 | 比源基线少14行 | 比源基线少14行 | 比源基线少14行 | 比源基线少6行 | | +| performance/optimization_scheduling2 | 136 | 122 | 比源基线少14行 | 比源基线少14行 | 比源基线少14行 | 比源基线少6行 | | +| performance/optimization_scheduling3 | 136 | 122 | 比源基线少14行 | 比源基线少14行 | 比源基线少14行 | 比源基线少6行 | | +| performance/shuffle0 | 485 | 472 | 比源基线少13行 | 比源基线少13行 | 比源基线少13行 | 比源基线少6行 | | +| performance/shuffle1 | 485 | 472 | 比源基线少13行 | 比源基线少13行 | 比源基线少13行 | 比源基线少6行 | | +| performance/shuffle2 | 485 | 472 | 比源基线少13行 | 比源基线少13行 | 比源基线少13行 | 比源基线少6行 | | +| performance/sl1 | 283 | 264 | 比源基线少19行 | 比源基线少3行 | 比源基线少3行 | 比源基线少8行 | | +| performance/sl2 | 283 | 264 | 比源基线少19行 | 比源基线少3行 | 比源基线少3行 | 比源基线少8行 | | +| performance/sl3 | 283 | 264 | 比源基线少19行 | 比源基线少3行 | 比源基线少3行 | 比源基线少8行 | | +| performance/transpose0 | 225 | 207 | 比源基线少18行 | 比源基线少14行 | 比源基线少14行 | 比源基线少4行 | | +| performance/transpose1 | 225 | 207 | 比源基线少18行 | 比源基线少14行 | 比源基线少14行 | 比源基线少4行 | | +| performance/transpose2 | 225 | 207 | 比源基线少18行 | 比源基线少14行 | 比源基线少14行 | 比源基线少4行 | | ## 统计