lzkk
|
b3187edbbf
|
perf(mir): MIR 清扫——%2指令精简 + 算术select死代码消除
- %2快速路径:and+cmp+csneg ge(3指令)替代 negs+and+and+csneg mi(4指令)
- 穿透Inline中 icmp ne(zext(cmp),0) 冗余链,消除算术select的mov+cmp+cset冗余
- Madd折叠前移:Mul唯一用户是Add时跳过,由Add的Madd统一处理
- Div/Mod/And/Or常量提前处理,避免emit不消费的死MovImm
门禁:functional 99/100(95_float预存失败),h_functional 40/40
|
3 days ago |
lzkk
|
1b9c8cc40d
|
fix(mir): 修复全局变量 .bss/.data 段反复切换——统一分组输出
之前每个零初始化全局变量都会在 .bss → .data 之间切换一次,
大数组(12MB BSS)的 .data 插入可能导致链接器内存布局异常。
现在先输出全部 .bss 段,再输出 .data 段,消除无用的段切换。
这可能是 many_mat_cal-1/3 在平台 100MB 限制下 WA 的根因。
|
3 days ago |
lzkk
|
d9ebea6668
|
perf(ir): if-else→mul select 转换 + 死BB清理,使多BB函数可内联
- TryConvertIfElseToSelect 将 3-5 BB 的 if-else-return 转为单 BB
- 算术 select: fv + (tv-fv)*zext(cmp),仅支持 i32
- 转换后清理死 BB(const_cast erase),使 IsInlineable 识别
- float 函数安全跳过(IsFloat32 + IsInt32 守卫)
- max()→f()→loop_test() 级联内联成功,热循环零函数调用
- 门禁: functional 2预存失败, h_functional 0失败
|
3 days ago |
lzkk
|
40eb6784d3
|
perf(ir): 添加 And/Or 操作码 + if-else→select 转换框架
- IR 层添加 And/Or BinaryInst 支持(IRPrinter/LoopInfo/Lowering 全覆盖)
- MIR 层已有 AndRR/OrRR,直接映射
- Inline.cpp 添加 TryConvertIfElseToSelect:将 3-BB if-else-return
函数转为单 BB 算术 select(fv + (tv-fv)*zext(cmp)),使其可被内联
- 转换逻辑已实现,与快门禁兼容(functional+h_functional 0 失败)
|
3 days ago |
lzkk
|
4403dc08b8
|
perf(mir): 常量除法魔法数优化——smull+asr 替代 sdiv
实现 Hacker's Delight 有符号除法魔法数算法,将 x/C 替换为乘法逆元序列。
32/60 性能测试受益,sdiv 全部消除(仅剩变量除法无法优化)。
- M 为正(MSB=0):smull + asr #(32+s) + sub 符号修正
- M 为负(MSB=1):smull + lsr #32 + add + asr #s + sub 修正
- ModRR 同样受益:q = magic_div(x,C); r = x - q*C (msub)
- 添加 Umull 操作码(与 Smull 对称,为后续优化预留)
- 性能分 33→55(+65%),几何平均 0.55→0.55(因 gcc ref 更多成功运行)
|
3 days ago |
lzkk
|
635f01bd48
|
perf(mir): 添加 Lsr64RR 支持——64位逻辑右移,为常量除法优化铺路
|
3 days ago |
lzkk
|
422f1848fc
|
perf(mir): Lowering 直接生成 AddShiftRR——x+(x*2^n) → add x,x,lsl#n
在 Lowering 阶段检测 Add 的某个操作数是 Mul by 幂次方常量,
直接发射 AddShiftRR 而非分开发射 ShlRR+AddRR。
配合 Peephole 残余合并,共生成 5 处 add lsl。
|
3 days ago |
lzkk
|
8d0c5ebcd0
|
perf(mir): 添加 AddShiftRR/SubShiftRR 支持——lsl+add 合并为 add lsl
- MIR.h: 新增 AddShiftRR/SubShiftRR 操作码(4 操作数: dst, src1, src2, shift)
- RegAlloc: 更新 def/use 分析
- AsmPrinter: 发射 add/sub dst, src1, src2, lsl #shift
- Peephole: 相邻 ShlRR+AddRR/SubRR → AddShiftRR/SubShiftRR
为后续在 Lowering 阶段直接生成移位操作数铺路。
|
3 days ago |
lzkk
|
e1944acc6b
|
perf(mir): Peephole 增强——StoreGlobal→LoadGlobal 跨指令转发 + 冗余 adrp 消除
全局变量前向替换不再只检查相邻指令,可跨越不冲突的中间指令扫描。
添加冗余 adrp 检测(同一符号+同一寄存器,中间无重定义则删除)。
|
3 days ago |
lzkk
|
00c489f0be
|
perf(mir): 消除 Mul 幂次方优化产生的死 MovImm——先检测后发射 rhs
x*2^n 优化为 lsl 时,先检测常量是否幂次方再决定是否发射 rhs,
避免先发射 MovImm 再被 ShlRR 覆盖的死代码。
crypto 1458→1449,crc 303→297。
|
3 days ago |
lzkk
|
4179f40264
|
perf(mir): leaf 函数省略帧指针——无调用+无栈帧时跳过 stp/ldp x29,x30
crypto 1482→1458(-24 指令),crc 306→303。
|
3 days ago |
lzkk
|
10a59110eb
|
perf: 函数内联 + csneg 取模优化,crypto 1.76x→1.69x
- IR 保守内联:纯算术单 BB leaf 函数自底向上迭代内联
- MIR 取模优化:x%2^n 用 negs+and+and+csneg(6→4 指令)
- 添加 CondCode::MI/PL 支持 csneg 的 mi/pl 条件码
- 修正 NegRR 发射 negs(设标志位)供 csneg 使用
|
3 days ago |
lzkk
|
2f1d7dc856
|
perf(ir): 保守函数内联——纯算术单BB leaf 函数自底向上迭代内联
只内联无副作用(无 Load/Store/GEP)的单基本块 leaf 函数。
InsertBefore 保持 BB 结构不变,支持级联收敛(_and→_xor→_or)。
已验证 140/140 功能测试通过,为后续 MIR 层优化铺路。
|
3 days ago |
lzkk
|
feab5508a8
|
fix(irgen): starttime/stoptime 函数名恢复为 _sysy_starttime/_sysy_stoptime
平台运行时库期望 _sysy_starttime(int) 和 _sysy_stoptime(int) 签名,
之前错误地生成 starttime(void) / stoptime(void),
导致所有程序链接到错误函数而崩溃返回 1。
恢复队友原版:下划线前缀 + 行号参数。
|
3 days ago |
lzkk
|
56b37ac060
|
chore: 删除死代码——LinearScanAlloc/GreedyAlloc/InstLiveness(共2072行)
三个文件未被 CMakeLists 引用、无头文件、无 MIR.h 声明、无调用方。
当前唯一寄存器分配器为 RegAlloc.cpp。
|
3 days ago |
lzkk
|
862c1bfe7b
|
第一次优化
|
3 days ago |
lzkk
|
1149d53d42
|
chore: 移除 LICM.cpp 空桩——实现已在 LoopInfo.cpp (ir_analysis)
|
3 days ago |
lzkk
|
0eb1cf4a7f
|
chore: 移除空桩文件(PassManager.cpp/ConstEval.cpp)从构建
这些文件仅含注释或include,无实际代码。
|
3 days ago |
lzkk
|
5d43539290
|
chore: 代码彻底清理——删除死代码、旧备份、生成文件
删除:
- warning/ src.bak.full/ llvm/ docs/superpowers/ (95MB+ 磁盘释放)
- Inline.cpp (621行,从未正确集成)
- PassManagerModule 死类 + 3个未使用pass声明 (PassManager.h)
- RunStrengthReduction/RunLoopUnrolling/RunLoopFission (LoopInfo.cpp 805行)
- FindInductionVars/AllUsesInLoop/IsSRLoopInvariantValue 死辅助函数
- 生成文件: Error.txt results.csv/json time_opt.txt settings.json
更新 .gitignore 防止未来污染
|
3 days ago |
lzkk
|
39e4dada13
|
perf(mir): 添加 Madd(乘加)指令——sum+a*b → madd sum,a,b,sum
限制:仅折合非常量乘数(常量有 shift 优化更优)。
SSA 单使用 Mul 被跳过,由 Add 处统一发射 Madd。
|
4 days ago |
lzkk
|
035f83b209
|
fix(mir): 模2^n AND优化——修复 x<0 且 x%2^n==0 时的零值错误
-4%2 应得 0,但 AND+符号修正路径算出 -2。
增加 cmp masked,#0; csel dst,wzr,temp,EQ 零值保护。
平台无 -O 时该路径被触发,导致 48_assign_complex_expr WA。
|
4 days ago |
lzkk
|
2cfc9e2fc8
|
perf(mir): MIR预分配 MovImm 转发——消除常数二次传递
mov v1,#N; mov v2,v1(v1 无其他使用)→ mov v2,#N
matmul -3.3%, optim_sched -10.2%, 01_mm -4.4%。33基线更新。
|
4 days ago |
lzkk
|
bf5956e3cc
|
perf(mir): Pettis-Hansen 基本块重排序——链合并+频率排序
基于 CFG 回边检测 + 块频率估计,贪心合并链使热路径 fallthrough。
huffman -10, h-8 -9(-2.6%), crypto -13。21基线更新。
|
4 days ago |
lzkk
|
c277aa2226
|
perf(mir): 帧槽按大小重排序——小槽优先获得 ldur 范围内偏移
4字节标量优先分配,大数组靠后,使热访问在 [-256,0] 的 ldur 范围。
crypto -176(-10.3%),消除大量 mov x13,x29 + sub 地址计算链。
|
4 days ago |
lzkk
|
f65fe9fc20
|
perf(mir): 扩展缩放寻址到 EmitStatement Load 路径(ptr/float/int)
h-8 -58(-14.6%), sort -66(-10.7%), h-5 -35(-10.9%), crypto -43, shuffle -37
24 基线更新,此轮优化累计巨大收益。
|
4 days ago |
lzkk
|
be3a5640ee
|
perf(mir): AArch64 缩放寻址——GEP+Load/Store 直接生成 ldr/str [base, idx, uxtw #2]
消除数组访问中的 sxtw+shl+add 链,替换为单条缩放寻址指令。
crypto -76(-4.2%), shuffle -39(-8.3%), sort -22(-3.4%), matmul -16(-4.3%)
|
4 days ago |
lzkk
|
3ece3d09f4
|
perf(mir): CMP常量lhs交换——mov+cmp优化为cmp#imm+条件翻转
|
4 days ago |
lzkk
|
e826f9ee57
|
perf(mir): 负除数模2^n同样使用AND优化
|
4 days ago |
lzkk
|
421df18c81
|
perf(mir): 模2^n运算优化——AND+符号修正替代 Msub
x % 2^n: (x & (2^n-1)) + cmp + csel 替代 asr+msub
huffman -20, crypto -33, crc -13, h-9 -7
|
4 days ago |
lzkk
|
2a67ef0f06
|
perf(mir): FixFallThrough——CondBr 条件反转消除冗余 Br
块尾 CondBr+Br 模式:当 CondBr 目标是下个块时,反转条件交换目标并删除 Br。
huffman -7, matmul -2.6%, h-10 -3.0%, many_mat_cal -3.1%。
|
4 days ago |
lzkk
|
667c342c51
|
perf(mir): Lowering 立即数折叠——AddRR/SubRR/CmpRR 常量 rhs 直接用 Imm
值 0-4095 可直接嵌入 add/sub/cmp,省去一条 MovImm。
配合 IR 迭代常量折叠生效。
|
4 days ago |
lzkk
|
d51cbc49f1
|
perf(mir): RegAlloc 偏置着色调和(copy_edges coalescing)
收集 MovReg 两端 vreg 为 copy_edges,逆向着色时优先选源操作数颜色。
减少无意义 MovReg 残留,全用例改善(matmul -3.5%, h-10 -3.5%)。
|
4 days ago |
lzkk
|
9095cbe0db
|
perf(ir): 启用 LICM + 迭代优化循环(ConstFold/ConstProp/CSE/DCE 收敛)
管线从 Mem2Reg+ConstFold+DCE+CFGSimplify 升级为:
Mem2Reg+LICM+(ConstFold+ConstProp+CFGSimplify+CSE+DCE)×10收敛
huffman -6.4%, crypto -5.6%, h-8 -11.7%, crc -7.6%
|
4 days ago |
lzkk
|
1993380d4a
|
chore: 移除 git 冲突残留文件
|
4 days ago |
lzkk
|
ee3b42ac40
|
feat(opt): 切换至队友代码基线——100%功能正确
Chaitin-Briggs 图着色寄存器分配,K=16无需spill。
IRGen starttime/stoptime 修复(去掉 _sysy_ 前缀和 lineno 参数)。
此提交为后续优化工作的安全起点。
|
4 days ago |
lzkk
|
bfe105c2cd
|
fix(mir): 别名无条件冲突 + per-round reserve防指针失效
两个安全修复:
1. GPR32/GPR64别名检查移除segments.empty()条件
Wn/Xn是同一硬件寄存器,GPR32和GPR64 vreg在同一phys_reg上总是冲突
2. 每轮EnhancerIntervals后reserve*16,防止push_back导致reg_assignments_指针失效
当前正确率:94% (94/100)
|
4 days ago |
lzkk
|
d6f42a2a2e
|
fix(mir): 回退到稳定版本——PhysReg映射+spill reload+别名无条件冲突
稳定在94%正确率。包含三个关键修复:
1. PhysReg映射修正: Ptr +31, Float +62, FP_ALLOCATABLE排除S0-S1
2. Spill reload为每次use创建新vreg
3. GPR32/GPR64别名无条件冲突
Mem2Reg交互问题(65_color, 94_nested_loops)已精确诊断为:
高寄存器压力→未分配vreg→共享回退寄存器X16→地址计算错误→SIGSEGV
完整修复需要LLVM SplitKit级别的活范围区域分裂。
|
4 days ago |
lzkk
|
0f1b545568
|
fix(mir): 分配顺序改为FirstUsePos + 别名无条件冲突 + per-round reserve
三处改进:
1. 新vreg按FirstUsePos升序分配(指令顺序),确保重叠vreg在干涉检查时可见
替代之前的Length()排序(弦图最优序近似)
2. GPR32/GPR64别名无条件冲突(移除segments.empty()条件)
3. 每轮EnhancerIntervals后reserve *16 防止push_back指针失效
Mem2Reg问题已精确诊断:高寄存器压力下,多个Ptr vreg的重叠段未被子涉检
测捕获,导致地址计算base和index共享同一物理寄存器。
当前正确率:94% (94/100),剩余2个Mem2Reg交互失败+4个预存缺陷。
|
4 days ago |
lzkk
|
83228a8123
|
fix(mir): GPR32/GPR64别名检查移除segments.empty()条件
Wn和Xn是同一硬件寄存器(如W12和X12),GPR32和GPR64 vreg
在同一phys_reg上总是冲突,无论segments是否为空。
原代码要求!segments.empty(),导致某些情况下别名冲突被漏检。
参考: AArch64寄存器别名机制,Wn为Xn的低32位
|
4 days ago |
lzkk
|
5fb106bde8
|
fix(mir): LLVM两遍分配 + 间隙分裂 + Assign安全网
改进:
1. 两遍分配(Pass1短活范围优先→Pass2延迟vreg驱逐/分裂)
— SSA弦图完美消除序近似:短范围先分配,长范围获得清晰干涉图
2. TrySplit改间隙分裂:在连续use间最大间隙处分裂,替代简单中点切分
— 参考 LLVM tryLocalSplit()
3. Assign返回bool + ForceAssign(预填跳过检查)
— 防止非法分配通过的安全网
诊断:Mem2Reg开启时,CheckInterference在某些情况下漏过重叠检测,
导致冲突vreg分配到同一物理寄存器。具体触发条件待进一步定位。
当前正确率:94% (94/100)
|
4 days ago |
lzkk
|
508f9d8ddc
|
fix(mir): TrySplit引用失效修复 + LLVM Defer机制
Three fixes:
1. TrySplit: 参数从 LiveInterval& 改为 vreg索引,避免 push_back 使引用失效
— 旧代码在 intervals.push_back() 后继续使用 li 引用(UB),高寄存器压力下导致
段错误
2. LLVM Defer机制: 首次无法分配时将 vreg 推迟到堆尾(RS_New→RS_Deferred)
— 让更小范围先分配以获得更清晰干涉图
— 参考: llvm/lib/CodeGen/RegAllocGreedy.cpp selectOrSplit()
3. LiveInterval 新增 deferred_count 字段追踪推迟状态
诊断: 65_color/94_nested_loops 在 Mem2Reg 开启时失败,关闭时通过。
Mem2Reg 消除栈分配(alloca→SSA),增加同时活跃 vreg 数量,触发高压 spill。
根因追踪到 TrySplit 的引用失效(与之前 heap 指针失效同类 bug)。
当前: 94% (94/100),剩余6失败详见 project_greedy_alloc_progress.md
|
4 days ago |
lzkk
|
80dc583143
|
fix(mir): PhysReg映射修正 + spill reload分配独立vreg——避免寄存器冲突
三处关键修复:
1. PhysReg映射偏移修正:Ptr +32→+31 (Wn→Xn)、Float +64→+62 (Sn-index→Sn)
— 原偏移使Ptr映射到X(n+1),如W12→X13,与AsmPrinter scratch X13冲突
2. FP_ALLOCATABLE排除S0-S1(参数/返回值寄存器),对应+62映射
3. Spill reload为每次use创建新vreg(LLVM InlineSpiller风格)
— 旧方案所有溢出vreg共享回退寄存器W16/X16,同时活跃时互相覆盖
参考:LLVM LiveRegMatrix foreachUnit + InlineSpiller reload
正确率:90% → 94%(修复64_calculator/65_color/85_long_code/88_many_params2/96_matrix_add)
|
4 days ago |
lzkk
|
ddaf8831a2
|
fix(mir): CMakeLists.txt 改用 GreedyAlloc.cpp 替代 LinearScanAlloc.cpp
|
4 days ago |
lzkk
|
da1e456133
|
feat(mir): 实现 LLVM-style 贪婪寄存器分配器 —— 统一架构
核心变更:
- MIR.h: 增强 LiveInterval(VNInfo/UsePosition/Segment)+ LiveRegMatrix + RegClass
- GreedyAlloc.cpp: TryAssign/TryAnyFreeReg/TryEvict/TrySplit 贪婪分配 + RewriteSpills
- InstLiveness.cpp: EnhanceIntervals 前向 pass + ComputeInstLiveness 适配
- MIRBasicBlock.cpp: InsertInst/ReplaceVReg API
- main.cpp: 切换至 RunGreedyRegAlloc
- RegAlloc.cpp/LinearScanAlloc.cpp: #if 0 隔离
架构:优先级队列驱动分配(每轮全新分配),TryEvict 无条件驱逐,
StoreStack+LoadStack 溢出重写,区间分裂处理高寄存器压力。
功能测试通过率: 53/100(剩余 47 例需调试溢出重写循环)
|
4 days ago |
lzkk
|
0a29e6ac42
|
fix(mir): AsmPrinter 函数调用后失效帧基址缓存——修复 92_register_alloc
Call 指令仅失效了 ADRP 缓存但未失效帧基址缓存(x13)。x13 是 caller-saved
寄存器,被调用破坏后后续栈访问使用垃圾地址。影响所有含函数调用的大栈帧函数。
修复: InvalidateFrameBase() 添加到 Opcode::Call 分支。
|
5 days ago |
lzkk
|
363b809736
|
fix(mir): 大栈帧 asm 输出 x13 缓存失效 + 叶函数栈参数偏移修复 + IR 数组初始化阈值降低
- AsmPrinter: 大偏移量 movz/movk 路径中使用 x13 后失效帧基址缓存和 ADRP 缓存
- FrameLowering: 叶函数(仅保存 x29)栈参数偏移从 16 修正为 8
- IRGenDecl: 数组初始化阈值从 10000 降至 256,避免大数组 IR 膨胀导致后端超时
|
5 days ago |
lzkk
|
120d7197d8
|
fix(mir): 线性扫描活变量分析 def 位置记录 + callee-saved 寄存器限定 + CLI 标志修复
- InstLiveness: 反向扫描中记录 def vreg 的区间起点,修复 phi copy 的 MovReg
def 位置未被区间覆盖导致寄存器分配不一致的 bug(25_while_if 死循环)
- LinearScanAlloc: GP_ALLOCATABLE 限定为 callee-saved 寄存器(x19-x28),
避免跨函数调用时 caller-saved 寄存器被破坏导致段错误(54_hidden_var)
- CLI: 修复 --regalloc= 标志 strncmp 长度 off-by-one(12→11)
|
5 days ago |
lzkk
|
e1777c9eab
|
fix(ir): CSE 安全门禁——非 SSA 函数跳过 Load/GEP CSE
- 当 alloca 数量 > 24(Mem2Reg 跳过)时,跳过 Load 和 GEP 的 CSE
- 修复 27_scope5 优化 bug(非 SSA 代码中 Load CSE 错误合并不同作用域变量)
- 86_long_code2 不受影响(仅 1 个 alloca,Load/GEP CSE 正常启用)
|
5 days ago |
lzkk
|
28c336728d
|
fix(mir): 线性扫描区间分裂修复 + 多定义点 vreg 跳过逻辑修复
- 区间分裂: last.end = cur.start (而非 cur.end),确保 save point 之后寄存器值正确
- 多定义点 vreg: 改为按区间覆盖检查,支持 phi-copy 插入的多定义场景
- 30_many_dimensions 已修复(19D 嵌套循环输出正确)
- 25_while_if 循环变量映射仍有 bug,待进一步修复
|
5 days ago |
lzkk
|
fbea91986d
|
feat(mir): 指令级活变量分析 + CLI/构建集成
- InstLiveness: 三阶段算法(块级 fixpoint + 指令反向扫描 + 区间构建)
- 支持 phi-copy 插入环境(非严格 SSA):union 区间
- CLI.h 添加 regalloc 字段,支持 --regalloc=linear/graphcoloring
|
5 days ago |