potatolint:给土豆级硬件的指令优化建议

这是两个 peephole linter,给土豆级硬件用的:扫一遍汇编,指出哪些地方有更划算的写法。
目标 ISA 都不再新,却还有机器在跑 —— 而编译器的默认调优早已不是为它们做的。

一个扫 ARMv5TE 汇编,一个扫 Pentium 与 pre-P6(P5、Cyrix、K6)以及 Pentium 4 的 x86 汇编。

它们找的是在目标 CPU 上划不来的序列。只要划不来就值得看一眼,指令条数多少不是重点。

判据不靠个人经验,全部锚在 gcc 的权威源上,分三类:

  • gcc 明确写下的怪癖。gcc/config/i386/x86-tune.def 里的 X86_TUNE_* 标志,那些「避开某条指令」的条目。
  • cost table 对比。一条指令在目标 CPU 上的开销,对比 Pentium II(x86)或 Cortex-A8(ARMv7-A)这两个基线。
  • 原理上该避免的行为。长流水线上分支预测代价这一类行为谓词。

为什么是 census 而不是 gate

工具输出一份清单,不直接判定失败。

同一条指令在目标 CPU 上更贵,不等于这段代码就该改。改写要证明的东西在工具看不到的地方:改完之后原来被依赖的标志位是不是已经死了,对齐是不是还成立,时序有没有被别的指令补上。这些只有读代码的人能证明。

所以两个 linter 都是普查,不是闸门。报告「看这里」,判断留给读的人。

例外有两处,都在 ARM 那个里:--isa 是 ISA 门,-a 里的 Extended Asm 契约检查也算。这两处不存在权衡。指令集里没有的指令,或者写错的约束契约,就是错,没有可商量的余地。

构成

每个 linter 自成项目,彼此不共享代码。Python,加一张模式规则表,加两组测试:单元测试用合成的指令序列,集成测试用真实反汇编夹具。各自带 Makefile 与 pyproject.toml。

两个脚本各自在自己的目录里跑:

1
2
python3 armv5telint.py arm.dis
python3 pentiumlint.py obj.wdis

两个目录各自 make test,跑全部模块的测试。

项目在 https://github.com/lunzima/potatolint,许可 MIT。代码与文档里出现的处理器、架构与设备名称是各自所有者的商标。

评论

点击下面的按钮加载评论框。评论提交后需经确认,不会立即显示。