Skip to content

Expose function cloning and local IR transformation utilities - #56

Merged
xushiwei merged 2 commits into
xgo-dev:xgofrom
zhouguangyuan0718:codex/ir-cloning-go-api-20261007
Oct 10, 2026
Merged

xushiwei merged 2 commits into
xgo-dev:xgofrom
zhouguangyuan0718:codex/ir-cloning-go-api-20261007

Conversation

@zhouguangyuan0718

@zhouguangyuan0718 zhouguangyuan0718 commented Oct 7, 2026 •

Copy link
Copy Markdown

Go clients cannot currently clone a function, retain a mandatory tail-call boundary, or clean up a specialized CFG through the bindings. Expose LLVM's existing cloning and local IR utilities so clients can implement transformations in Go without a custom pass.

The API copies functions with their attributes and remapped debug scopes, folds local instructions and terminators, removes unreachable blocks, reads/rebuilds inline assembly properties, converts metadata values, changes a subprogram's linker name, and looks up symbols of any global kind. Tail-call kinds distinguish musttail from optional hints. The C++ layer uses generic LLVM APIs and contains no client transformation policy.

Narrowing conversions validate null/wrong-kind inputs at the C boundary and return failures that Go reports as descriptive, recoverable panics. Unreachable-block removal requires a function definition; cloning still accepts declarations. Invalid tail-call enum values are rejected without mutation, and compile-time assertions keep the Go constants aligned with LLVM. Inline assembly strings explicitly borrow InlineAsm storage through StringRef across both the older std::string& and newer StringRef APIs. AsMetadata documents and tests constant, argument, instruction, and MetadataAsValue inputs.

Tests verify independent function/debug cloning, declaration attributes, PHI cleanup, external references, symbol lookup including aliases, metadata identity, inline-assembly flags and length-carrying strings, all four tail-call IR spellings, and recoverable invalid-input handling. The new invalid-input regression aborts in C++ on the prior commit and passes with the checked boundary. Full binding tests pass locally with LLVM 19 and 22 on macOS/arm64 and Linux/amd64; the remote matrix covers LLVM 14–22.

Needed for the Go implementation of xgo-dev/llgo#2748.

@fennoai fennoai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review summary

This adds a clean, well-tested set of Go bindings for IR cloning and local transformation utilities missing from llvm-c. The wrappers correctly reuse existing helpers (boolToLLVMBool), follow the (receiver) (named return) style of ir.go, pair C.CString with defer C.free, and use length-carrying string accessors (StringRef(Name, Len) / C.GoStringN) rather than relying on NUL termination. Test coverage is strong: it verifies the original is unmodified, debug-info linkage names stay independent, external refs/attributes survive cloning, declaration clones keep attributes, round-trips tail-call kinds and inline-asm properties, and re-verifies the module.

The findings below are mostly minor. The most substantive is the unchecked unwrap<T>() casts at the cgo boundary; the rest are robustness/clarity notes.

Verified: the repo targets LLVM 14–22 (LLVM 22 is the default via build tags), so the InlineAsm::getAsmString() return-type change (LLVM 21+ returns StringRef by value) is relevant. I confirmed with the referenced upstream headers that the current const auto & binding is not a dangling-pointer bug — lifetime extension keeps it alive and .data() points into the InlineAsm's persistent storage in both regimes — but see the inline note on clarity.

Inline comments below.

Comment thread transforms.cpp Outdated
Comment thread transforms.cpp Outdated
Comment thread transforms.go
Comment thread transforms.go Outdated
Comment thread transforms_test.go Outdated
@xushiwei
xushiwei merged commit d0029d8 into xgo-dev:xgo Oct 10, 2026
28 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants