首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >基于 LLVM 纯 PHP 编写的 PHP AOT 编译器

基于 LLVM 纯 PHP 编写的 PHP AOT 编译器

作者头像
Tinywan
发布2026-07-06 11:12:40
发布2026-07-06 11:12:40
180
举报
文章被收录于专栏:开源技术小栈开源技术小栈

Manticore 是由manticorephp/compiler 项目实现的PHP AOT 编译器(Ahead-Of-Time 编译器),全部用纯 PHP 编写,通过 LLVM IR 后端生成 arm64 / x86_64 的独立原生二进制文件。

它支持 PHP 8.5+ 的一个很大子集(类、接口、特性、枚举、匿名类、闭包、管道运算符|>、生成器、FFI 本地库绑定、文件 I/O 等),无 PHP 运行时,仅依赖 libc。编译器自身用 PHP 编写并能自编译成字节完全相同 的 fixpoint(自托管修复点)。

项目官网描述(直接翻译自 README.md 和相关文档):

Manticore 完全自托管的 PHP-to-native AOT 编译器。通过 LLVM IR 将 PHP 8.5+ 的一个大子集编译为独立原生二进制文件(arm64 / x86_64)——无 PHP 运行时无共享库,仅 libc编译器用 PHP 编写并将其编译成字节完全相同的 fixpoint。

理由(Rationale)

如果您只了解了黑暗力量的真正力量。 Manticore 是一个概念验证项目,旨在证明创建自托管 PHP 编译器的可行性。通过用 PHP 编写编译器并编译成字节完全相同的 fixpoint,Manticore 展示了构建完全自包含 PHP 运行时环境的潜力。

当前状态(Status)

  • 自托管 fixpoint 成立manticore build manticore.json 从 PHP 源代码重建编译器,gen2 和 gen3 发出字节完全相同的 IR。
  • AOT 测试套件 343/343 通过(tests/aot/)。
  • 差异校验 334/0 与 Zend PHP 解释器(PHP 8.5.3)匹配:普通可运行用例中输出完全相同。
  • 重建稳定:5×2 次冷/自重建,每份二进制均无构建间堆布局随机性。
  • 10–45× 比 Zend 更快(计算/算法),冷启动 ~24× 更快(见 Benchmark)。
  • 引用计数 + 写时复制(assoc + 对象)+ Bacon–Rajan 周期收集器 v1(可选,零开销除非调用gc_collect_cycles())。
  • Cargo 风格模块系统:manticore.json、.sig 模块接口、预构建 stdlib 对象、分发版编译器(bin/ + lib/,无源代码)。
  • 扩展系统(MVP):清单声明的原生库绑定——glue 编译进应用 +-l<lib> 链接(证明:zlib / crc32)。真实扩展(curl / xml / pdo)基于相同机制。
  • 广覆盖 PHP 8.5 表面:类/接口/特性/枚举、抽象+匿名类、晚静态绑定、魔术方法、闭包 + 管道、nowdoc、encapsed-string 插值、define/constants、生成器、异常、libc 文件 I/O。

基准测试

与 Zendphp 解释器(PHP 8.5.3)对比,Apple M1 Pro,-O2,每份程序均经字节校验匹配 Zend。每轮均为数据依赖 + $argc 种子(LLVM 优化器无法折叠)。

计算密集型(原生代码生成优势显著,跳过解释器的每条指令开销):

Benchmark

工作负载

php

manticore

Speedup

oop

2000 万个多态虚拟 area()(LCG 索引)

1.11 s

0.04 s

28×

fib

递归 fib,数据依赖深度 [30,33]

1.87 s

0.10 s

19×

closures

200 万个闭包构建 + 调用

0.18 s

0.01 s

18×

mathf

300 万次 sqrt + sin 累加

0.15 s

0.01 s

14×

loop

5000 万次数据依赖累加

0.68 s

0.06 s

11×

sieve

Eratosthenes 筛到 200 万

0.18 s

0.02 s

array

30 次构建 + 求和 50 万元素 vec

0.34 s

0.08 s

strcat

3000 万次字符串追加

0.38 s

0.12 s

算法(计算机语言基准游戏风格——浮点、紧循环、2D 数组):

Benchmark

php

manticore

Speedup

spectralnorm

0.45 s

0.01 s

44×

mandelbrot

0.26 s

0.03 s

matmul

0.07 s

0.01 s

dijkstra

0.14 s

0.02 s

nbody

0.16 s

0.04 s

库绑定(时间花在 PHP stdlib/prelude 上,收益较小):

Benchmark

工作负载

php

manticore

Speedup

funcarr

array_map / filter / reduce

0.15 s

0.02 s

wordcount

assoc map 构建 + 迭代

0.07 s

0.01 s

strops

strtoupper / str_replace 循环

0.08 s

0.03 s

2.7×

sort

sort() 3K ints × 200

0.11 s

0.05 s

2.2×

sprintf

sprintf 格式化循环

0.09 s

0.04 s

2.2×

explode

explode / implode 循环

0.14 s

0.14 s

1.0×

json

json_encode 循环

0.12 s

0.20 s

0.6×

  • 冷启动(echo "hello"):php 62 ms vs manticore2.6 ms(~24×)——无解释器/扩展初始化。
  • 编译时间:fib.php → 原生二进制 ~0.1 s(parse → MIR → LLVM → clang → link)。
  • 输出大小:简单程序链接为 ~50 KB 完全静态二进制(仅 libc);自托管编译器 ~2.9 MB。

需求

  • PHP 8.1+ (仅用于冷启动:Zend 运行编译器源代码生成第一个原生二进制;生成后的二进制不调用 PHP 运行时)。
  • clangcc 在 PATH 上(macOS 为 Xcode CLT,Debian/Ubuntu 为 build-essential)。

快速开始

代码语言:javascript
复制
# 冷启动:Zend 种子第一个原生编译器(无需二进制) bash bin/compile # → bin/manticore (~2.9 MB 静态二进制) # 之后,编译器自托管重建(Zend 种子仅用于冷启动) bash bin/build # 自托管:bin/manticore 编译 src/ bash bin/build --verify # + fixpoint + 测试套件闸门 # 编译并运行程序 bin/manticore compile path/to/app.php -o app && ./app # 从 stdin 读取 echo '<?php echo "hi\n";' | bin/manticore compile -o /tmp/hi && /tmp/hi

CLI 命令

命令

用途

compile-o

PHP 源代码 → 原生二进制(文件参数或 stdin)

build [manticore.json]

构建所有清单目标(库 + 应用)

dump-ast

解析 → 输出 AST

dump-mir

下推 → 输出带类型 MIR

dump-llvm-mir

完整 MIR 流水线 → 输出 LLVM IR

dump-llvm

同 dump-llvm-mir(AST 后端已移除)

dump-sig

输出模块接口 .sig(导出符号表)

version / help

标志:-o <out>-O<0|1|2|3|s|z>(clang 优化级别,默认-O2)、--emit-library(编译为独立.o@main)、--memory=rc|arena|hybridbuild 还支持--libs-only(仅构建库目标)。

模块系统(manticore.json)

Cargo 风格清单,构建多文件项目、链接预构建库、自重建编译器。完整用户指南:docs/modules.md

示例(标准库与编译器自身):

代码语言:javascript
复制
{ "libraries": [{ "name": "stdlib", "src": "src/Runtime", "output": "lib/manticore_stdlib.o", "runtime": true }], "applications": [{ "name": "compiler", "src": "src", "output": "bin/manticore", "entry": "src/zzz_entry.php", "stdlib": false }] }
  • **applications[]**:源目录、输出二进制、可选入口(顶层代码成为 main)、可选排除、可选库、可选stdlib: false(关闭总是开启的 stdlib 运行时)。
  • **libraries[]**:编译为<output>.o + <output>.o.sig 接口。runtime: true 的标准库库会被自动链接到每个应用。
  • .sig 文件:模块公开符号表,用于跨单元调用(无需重新解析依赖源)。分发版编译器仅需 bin/ + lib/manticore_stdlib.{o,sig}(无 PHP 源代码)。
  • 标准库是始终开启的运行时:每个compile /build 程序透明获得(无清单仪式)。可通过"stdlib": false 关闭(仅自托管编译器使用,因为它已嵌入src/Runtime)。
  • 原生库(zlib 等)通过 FFI 绑定:#[Library, Symbol] 属性编译为直接 C 调用;声明为清单extensions

完整类型映射与机制docs/ffi.md

编译器流水线

代码语言:javascript
复制
PHP 源代码 → Lexer (src/Lexer) tokens → Parser (src/Parser) AST (递归下降 + Pratt) → LowerFromAst ─┐ → ConstFold │ → DeadStore │ → InferTypes │ MIR (src/Compile/Mir) — 平面、带类型、类 SSA IR → NarrowReturns │ 唯一后端(AST 后端已移除) → InferEffects │ EmitLlvm 通过 src/Codegen/Llvm 助手构建 IR 文本。 → InferAllocKind │ → ApplyMemoryMode │ → InsertMemoryOps │ (rc retain/release/CoW 插入) → Verify ─┘ → EmitLlvm (src/Compile/Mir/Passes/EmitLlvm*) → LLVM IR 文本 → clang -c IR → 对象 → cc link 静态二进制(仅 libc)

内存模型(Memory Model)

完整指南 + 控制方式:docs/memory.md

  • 默认:hybrid(逃逸路由):Escape 分析(InferAllocKind)对每个分配分类:
    • Confined(不逃逸):arena(bump pointer,作用域退出时批量释放)。
    • Escaping:引用计数(heap rc)。
  • 引用计数:字符串、数组、对象带有 refcount;赋值/retain 增加,作用域退出/覆盖 drop;数组/对象属性使用写时复制(Zend 风格)。
  • 周期收集器 v1:Bacon–Rajan,可选,零开销(从未调用gc_collect_cycles() 的程序不支付任何代价)。
  • 分配模式(--memory / MANTICORE_MEMORY):hybrid(默认)、rc、arena(bump-pointer,作用域释放)。Escape 分析决定 arena(受限)还是 heap-rc(逃逸)。
  • 统一 PhpArray(vec + assoc 折叠)+ FNV 桶索引。

源代码布局(纯 PHP,每文件一个类/接口/特性/枚举,路径镜像 FQN):

  • bin/:构建脚本 + 输出二进制
  • lib/:预构建标准库对象 + .sig
  • src/Lexer/:分词器
  • src/Parser/:递归下降 + Pratt 解析器
  • src/Compile/:AST → MIR 下推、MIR 传递、EmitLlvm 后端
  • src/Codegen/Llvm/:低级 LLVM-IR 文本构建器
  • src/Runtime/:PHP 级 stdlib + 运行时助手(编译进二进制)+ libc/OS/Json 绑定
  • src/Ffi/:FFI 绑定属性
  • src/Os/:OS / syscall 层
  • src/Manticore/:驱动(Main.php)、Sig.php(模块接口)、构建命令
  • src/Cli/:CLI 分发
  • tools/:构建 + 闸门脚本
  • tests/aot/:主测试套件

自托管与闸门

  • bash tests/aot/run.sh:AOT 套件
  • bash tests/aot/run.sh -k hello:子串过滤
  • bash tools/difftest.sh:与php 差异校验
  • bash tools/selfhost_fixpoint.sh:fixpoint + 自托管套件 + 稳定性
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-07-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 开源技术小栈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 理由(Rationale)
  • 当前状态(Status)
  • 基准测试
  • 需求
  • 快速开始
  • CLI 命令
    • 模块系统(manticore.json)
    • 编译器流水线
    • 内存模型(Memory Model)
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档