Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ _testmain.go
/doc/articles/wiki/*.bin
/goinstall.log
/last-change
/llvm/
/src/cmd/vendor/github.com/goallc/go-llvm/llvm
/src/cmd/vendor/github.com/goallc/go-llvm/libLLVMGoALLC.a.stamp
/misc/cgo/life/run.out
/misc/cgo/stdio/run.out
/misc/cgo/testso/main
Expand Down
133 changes: 79 additions & 54 deletions GOALLC.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,27 +74,30 @@ Remote:

路径:`/Volumes/Disk1/00.Work/00.Code/goallc/go-llvm`

- 上游:`tinygo-org/go-llvm` 的 `main`
- LLVM 23 集成通过 GoALLC PR #2 进入 `master`
- 合并后的 `master` 提交为 `7467f945baac`
- Go 仓库依赖版本为
`v0.0.0-20260726171243-7467f945baac`
- 以 TinyGo 上游 `185673e` 为基础,重放 GoALLC 的 module path 和静态
链接改动
- 由 `tinygo.org/x/go-llvm` 派生
- 上游代码已经支持 LLVM 14--22;本轮为 LLVM 23 增加相同的版本选择和
系统安装配置
- 本项目把 module path 改成 `github.com/goallc/go-llvm`
- 无版本 build tag 时默认选择 LLVM 23;项目内静态 payload 改为显式
`staticllvm` build tag
- Linux 使用 apt.llvm.org 的 LLVM 23 当前快照 suite;Homebrew 当前仍以
LLVM 22 为未版本化公式,因此 macOS 的 LLVM 23 验证使用本地源码构建
- Go 仓库中的 vendored binding 已同步上述更新
- personal lowering 分支额外增加了 `goallc_ext.go`,包装
`LLVMPrintModuleToFile`、`LLVMSetValueName2` 和 opaque pointer type

当前 `go-llvm/llvm/` 只包含 4 个 `.gitignore`,没有实际 LLVM headers、
libraries 或 binaries。默认静态构建因此不是开箱即用的。
- 由 `tinygo.org/x/go-llvm` 派生,module path 为
`github.com/goallc/go-llvm`;
- LLVM 23 基础兼容及当前清理方案已进入 `master`,HEAD 为
`33267b8eb4a0`;
- 本项目只支持 GoALLC 定制 LLVM,不再支持系统预安装 LLVM、
`byollvm`,也不保留 LLVM 14--22 的兼容配置;
- LLVM API 版本和链接模式是两个正交、必选的 build-tag 维度:
`llvm23` 与 `dynamicllvm`/`staticllvm`;后续 LLVM 24 只新增
`llvm24` 版本层;
- 路径与版本、链接模式解耦。所有 cgo include/link 路径固定写为
`${SRCDIR}/llvm/include` 和 `${SRCDIR}/llvm/lib`;
- `llvm` 不入库,由调用方提供软链接。Go 工具链的 `cmd/dist` 根据
`-llvm-dir` 创建或更新该链接;
- 动态模式链接 payload 中的 `libLLVM`;静态模式只链接 binding
`${SRCDIR}` 下由 `cmd/dist` 聚合的 `libLLVMGoALLC.a`;
- 没有生成 Go 文件,没有 `LLVMROOT`,也不把路径塞进普通 cgo 的
`CGO_CPPFLAGS`、`CGO_LDFLAGS` 或全局动态库环境;
- `goallc_ext.go` 已从 Go vendor 私有补丁收回 binding 仓库。
- 自动 CI 暂时只做源码格式检查,不再为每个 PR 从源码冷构建 LLVM;
项目发布预构建 LLVM payload 后,CI 将直接下载 artifact 并恢复动态、
静态两种 binding 测试。

Go 仓库依赖 go-llvm `master` 的 pseudo-version:
`v0.0.0-20260727072003-33267b8eb4a0`。

### 2.3 `llvm-project`

Expand All @@ -113,6 +116,9 @@ Remote:
- 基于本地 `official/release/23.x` 的 `ce6af707aac8`
- LLVM 版本文件为 `23.1.0`
- GoObj 主题分支在 release base 上有 24 笔提交
- 原聚合静态库方案的 GoALLC PR #2 已关闭;其 feature 分支已用
`e31213b5750d` 撤回全部源码改动,相对 `llvm23.1.master` 的净 diff
为零。静态聚合职责已移到 Go `cmd/dist`

本轮已恢复 Clang、LLDB 和 MLGO 测试夹具中的既有 symlink/file-type
变化,源码工作区目前干净。旧的 25 GB 构建目录已删除,并从空目录重新完成
Expand Down Expand Up @@ -181,9 +187,10 @@ symbol、relocation、aux data、function metadata、stack map 和反汇编内

- 保留了 LLVM C API 的主要 IR、target、bitcode、DIBuilder、pass、
execution engine 等 Go 封装;
- 支持 LLVM 14--21 的 build tag;
- 改用 GoALLC module path;
- 增加项目内静态 LLVM 目录和生成静态链接 flags 的机制;
- 只保留当前 LLVM 23 API,并以独立 build tag 为 LLVM 24 迁移预留扩展点;
- 版本选择、链接模式和 payload 路径互不耦合;
- 动态、静态配置完全由代码 build tag 隔离,不生成配置源文件;
- 静态模式使用一个 `libLLVMGoALLC.a`,不在 binding 中计算组件依赖;
- 允许把 binding 直接 vendor 到 `src/cmd/vendor`,供 `cmd/compile`
内部使用;
- bootstrap build 通过 `compiler_bootstrap` stub 避免第一阶段直接依赖
Expand Down Expand Up @@ -321,20 +328,24 @@ Go SSA 分支形成于 LLVM Go ABI 工作之前,目前:

- Go checkout:官方 `release-branch.go1.27` 的 `go1.27rc2`;
- bootstrap Go:Go 1.26.5;
- vendored/standalone binding:LLVM 23 为默认版本
- vendored/standalone binding:显式选择 `llvm23`
- LLVM source/build:23.1.0git;
- 本轮通过 `byollvm,llvm23` build tags、显式 include/library 路径和
`libLLVM` 共享库直接使用 LLVM build tree。
- LLVM payload 默认位于 `$GOROOT/llvm`,也可用 `-llvm-dir` 指定;
- LLVM API 默认版本为 23,也可用 `-llvm-version` 显式指定;
- 默认通过 payload 中的 `libLLVM` 动态链接;`-llvm-link=static` 让
`cmd/dist` 使用 payload 的
`llvm-config` 与 `llvm-ar` 生成 binding 本地的 `libLLVMGoALLC.a`。

当前 LLVM 由 macOS 26 SDK 构建,而 Go 1.27 工具链默认链接目标为 macOS
16,因此链接时会产生 deployment-target 警告。构建和 smoke test
成功,但后续应在 CMake 配置中显式统一最低 macOS 版本。

`cmd/dist` 还用一个恒为 true 的 `buildGoallc` 强制所有工具走 external
link。这是早期 bring-up 手段,后续应缩小到真正依赖 LLVM 的 compiler
阶段和受支持平台。本轮新增 `GOALLC_LLVM_BUILD_TAGS`,因为 `cmd/dist`
会清空调用者的 `GOFLAGS`;它只把指定 tags 注入 toolchain2/3,bootstrap
仍使用 `compiler_bootstrap` stub。
阶段和受支持平台。`cmd/dist` 现在根据参数自行注入
`llvm23,dynamicllvm` 或 `llvm23,staticllvm`;bootstrap 仍使用
`compiler_bootstrap` stub。LLVM 的 include 和 link 参数只存在于
binding 的代码配置中,不与普通 cgo 构建的外部环境变量混用。

## 6. 当前验证状态

Expand All @@ -348,16 +359,14 @@ link。这是早期 bring-up 手段,后续应缩小到真正依赖 LLVM 的 co
- 新构建产物为 LLVM `23.1.0git`、Debug、assertions enabled,包含 X86
和 AArch64,并生成约 302 MB 的 `libLLVM.23.1git.dylib`;
- 8 个 X86/AArch64 GoObj MC/CodeGen 定向测试全部通过;
- `go-llvm` 已获取 `tinygo-org/go-llvm` 当前 `main`,上游新增版本明确到
LLVM 22;
- 在上游 `185673e` 上重放 GoALLC 改动,并补齐 LLVM 23 的 branch opcode、
branch type query、build tags 和 config;
- standalone `go-llvm` 使用新 LLVM 23 头文件和共享库,在显式
`byollvm,llvm23` 和默认无版本标签两种模式下完成全测试;
- GoALLC PR #2 CI 通过 Linux LLVM 14--23、Fedora LLVM 19--21 和
macOS LLVM 14--22;Linux LLVM 23 同时验证默认无版本标签模式;
- 更新后的 binding 已同步到 Go vendor,并保留 `goallc_ext.go`;
- Go 三阶段工具链集成构建成功,`bin/go version` 为
- 旧方案曾由 LLVM 的 `LLVMGoALLC` target 生成聚合库;当前方案已把
聚合职责移到 `cmd/dist`,LLVM 源码不再需要该项目专用 target;
- standalone `go-llvm` 在不设置外部 `CGO_*` 参数的情况下,以
`llvm23,dynamicllvm` 和 `llvm23,staticllvm` 完成全测试;
- 更新后的 binding 已同步到 Go vendor,`goallc_ext.go` 不再是 vendor
私有差异;
- Go 三阶段工具链在默认动态模式和 `-llvm-link=static` 模式下均构建
成功,`bin/go version` 为
`go1.27rc2 darwin/arm64`,`compile -h` 包含 `-enablellvm`;
- `go test cmd/dist`、`go test cmd/compile/internal/ssa cmd/objview` 通过;
- 最小 `Add(int64, int64)` 包经 `compile -enablellvm` 同时生成 Go archive
Expand All @@ -382,12 +391,13 @@ rebase 后曾通过:

- Go:`official/release-branch.go1.27`,当前 `go1.27rc2`;
- LLVM:`release/23.x` 上的 GoObj 分支 `llvm23.1.master`;
- binding:GoALLC `go-llvm/master`,默认 LLVM 23。
- binding:GoALLC `go-llvm` PR #3,显式 LLVM 23。

### 7.1 已完成的版本迁移

1. LLVM 23 分支和共享库 clean build 已完成。
2. binding 已补齐 LLVM 22/23 C API 差异、默认版本、平台路径和 CI。
2. binding 已清理为定制 LLVM 23、固定 `${SRCDIR}/llvm` payload 和正交
build tags。
3. Go 的 6 笔既有提交已重放到 Go 1.27 release branch。
4. vendored binding、dist build tags 和 Go 1.27 vet 兼容性已更新。
5. 三阶段 bootstrap、核心测试和最小 IR verifier smoke test 已恢复。
Expand Down Expand Up @@ -453,37 +463,52 @@ cmake -S llvm -B llvm/cmake-build-debug -G Ninja \
ninja -C llvm/cmake-build-debug -j6
```

在 macOS 上用 build tree 配置 cgo
准备统一的 LLVM payload 布局

```sh
goallc_llvm_build=/Volumes/Disk1/00.Work/00.Code/goallc/llvm-project/llvm/cmake-build-debug
export CGO_CPPFLAGS="-I$goallc_llvm_build/include -I$goallc_llvm_build/../include"
export CGO_CXXFLAGS="-std=c++17"
export CGO_LDFLAGS="-L$goallc_llvm_build/lib -Wl,-rpath,$goallc_llvm_build/lib -lLLVM -L/opt/homebrew/lib -lz -lzstd -lxml2 -lm"
$GOROOT/llvm/bin/llvm-config
$GOROOT/llvm/bin/llvm-ar
$GOROOT/llvm/include/llvm-c/Core.h
$GOROOT/llvm/lib/libLLVM.dylib # dynamic
$GOROOT/llvm/lib/libLLVM*.a # static component archives
```

不要把 LLVM build 目录全局写入 `DYLD_LIBRARY_PATH`;这会让 Homebrew 的
clang 等 LLVM 工具误加载该开发版共享库。`cmd/compile` 的链接命令已经写入
build-tree rpath。
payload rpath。

验证 standalone binding:

```sh
cd /Volumes/Disk1/00.Work/00.Code/goallc/go-llvm
GOCACHE=/private/tmp/goallc-gocache \
go test -tags='byollvm llvm23' ./...
ln -s /Volumes/Disk1/00.Work/00.Code/goallc/go/llvm llvm
go test -tags='llvm23 dynamicllvm' ./...
# staticllvm 需要先由 Go 的 cmd/dist 在 binding ${SRCDIR} 聚合静态库
go test -tags='llvm23 staticllvm' ./...
```

构建 Go 集成工具链:

```sh
cd /Volumes/Disk1/00.Work/00.Code/goallc/go/src
GOROOT_BOOTSTRAP=/opt/homebrew/Cellar/go/1.26.5/libexec \
GOCACHE=/private/tmp/goallc-toolchain-gocache \
GOALLC_LLVM_BUILD_TAGS=byollvm,llvm23 \
./make.bash
./make.bash
./make.bash -llvm-dir=/path/to/llvm -llvm-version=23 -llvm-link=dynamic
./make.bash -llvm-dir=/path/to/llvm -llvm-version=23 -llvm-link=static
```

`cmd/dist` 使用显式 `-llvm-dir`,未指定时使用 `$GOROOT/llvm`。LLVM
版本和链接方式同样只接受 `-llvm-version` 与 `-llvm-link` 参数,不读取
项目专用环境变量。它验证 payload 版本和所选链接库,再原子更新
`$GOROOT/src/cmd/vendor/github.com/goallc/go-llvm/llvm` 软链接。真实目录对
binding 不可见,binding 始终只使用 `${SRCDIR}/llvm`。

静态模式下,`cmd/dist` 通过 payload 的 `llvm-config --link-static
--libfiles` 获取标准 LLVM component archives,再通过 `llvm-ar -M`
聚合为
`$GOROOT/src/cmd/vendor/github.com/goallc/go-llvm/libLLVMGoALLC.a`。
它用 LLVM 版本、组件列表以及输入归档的路径、大小和修改时间缓存结果;
LLVM 源码和构建系统本身不包含 GoALLC 专用静态库 target。

最小 IR smoke test:

```sh
Expand Down
Loading