Skip to content

perf(codegen): initialize only the two LLVM backends Perry can emit for - #7350

Merged
proggeramlug merged 2 commits into
mainfrom
perf/llvm-inprocess-target-set
Aug 4, 2026
Merged

perf(codegen): initialize only the two LLVM backends Perry can emit for#7350
proggeramlug merged 2 commits into
mainfrom
perf/llvm-inprocess-target-set

Conversation

@proggeramlug

@proggeramlug proggeramlug commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Target::initialize_all() references every LLVM target's init symbol, so the static link pulls in all ~20 backends.

perry binary size
no feature 25.7 MB
feature, initialize_all() 185.9 MB (+160.1)
feature, AArch64 + X86 98.9 MB (+73.2)

−86.9 MB — 47% of the whole feature build — for backends nothing can reach.

It was inkwell's convenient default in #7301 rather than a considered choice, and the feature was opt-in so nobody paid for it. That changes now that making llvm-inprocess standard is on the table: this is the difference between a 186 MB compiler and a 99 MB one.

Why two backends is the honest set. Every triple the compile driver can produce is aarch64 (Apple platforms, Android, Linux gnu/musl/ohos, and watchOS's ILP32 arm64_32 — still the AArch64 backend) or x86 (x86_64, x86_64h, i686). The lone riscv64gc string in the tree is a unit-test assertion in gc_map.rs, not an emission target, and wasm has its own crate (perry-codegen-wasm) that never reaches this backend.

Fails loudly, never silently. An uninitialized triple errors at Target::from_triple ("no LLVM target for …"). A new test asserts all ten driver-producible triples resolve, so adding an architecture without initializing its backend fails in cargo-test rather than at a user's compile.

Verified on the 81-module zod dependency corpus: text, transport and native modes all compile; native output byte-identical to text; RS4GC probe 09 compiles.

Summary by CodeRabbit

  • Bug Fixes
    • Improved compilation compatibility across supported target platforms.
    • Supported AArch64 and x86 targets now resolve reliably during compilation.
    • Unsupported platform targets continue to produce clear, immediate failures.
    • Added coverage to help ensure supported platform configurations remain functional.

`Target::initialize_all()` references every LLVM target's init symbol, so
the static link pulls in all ~20 backends. Measured on the `perry`
binary built with the llvm-inprocess feature:

    no feature                 25.7 MB
    feature, initialize_all   185.9 MB   (+160.1)
    feature, AArch64 + X86     98.9 MB   (+73.2)

-86.9 MB, 47% of the whole feature build, for backends nothing can
reach. It was inkwell's convenient default in #7301 rather than a
considered choice, and the feature was opt-in so nobody paid for it --
which matters now that making it standard is on the table.

Perry's LLVM target surface is exactly two architectures: every triple
the compile driver can produce is aarch64 (Apple platforms, Android,
Linux gnu/musl/ohos, and watchOS's ILP32 arm64_32, still the AArch64
backend) or x86 (x86_64, x86_64h, i686). The lone riscv64gc string is a
unit-test assertion in gc_map.rs, not an emission target, and wasm has
its own crate that never reaches this backend.

Fails loudly, never silently: an uninitialized triple errors at
Target::from_triple. A new test asserts all ten driver-producible
triples resolve, so adding an architecture without its backend fails in
cargo-test rather than at a user's compile.

Verified on the 81-module zod corpus: text, transport and native modes
all compile, native output byte-identical to text, RS4GC probe 09
compiles.
@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d2f5d57b-cd11-4344-9523-2e4f03d3feaa

📥 Commits

Reviewing files that changed from the base of the PR and between 094552c and fe72135.

📒 Files selected for processing (1)
  • crates/perry-codegen/src/inprocess.rs

📝 Walkthrough

Walkthrough

LLVM initialization now registers only AArch64 and x86 targets. A regression test verifies representative Apple, Linux, Android, and Windows triples.

Changes

LLVM target initialization

Layer / File(s) Summary
Target backend registration and triple coverage
crates/perry-codegen/src/inprocess.rs
global_init explicitly initializes AArch64 and x86 backends. A regression test checks representative supported triples and preserves failure for unsupported triples.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

  • PerryTS/perry#7301: Modifies the LLVM target initialization in inprocess.rs that this change narrows.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description explains the change and results, but it omits the required template sections for changes, related issue, test plan, and checklist. Use the repository template headings and add the related issue, test commands or completed test checklist, and contributor checklist.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: limiting LLVM initialization to the AArch64 and X86 backends.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch perf/llvm-inprocess-target-set

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/perry-codegen/src/inprocess.rs`:
- Around line 406-434: Update the triple list in
every_supported_triple_resolves_to_an_initialized_backend to include
arm64_32-apple-watchos, ensuring the ILP32 watchOS target is verified as
resolving to an initialized backend when supported. Preserve the existing
global_init and assertion behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: ef3e4f35-feac-4e93-8f87-b3eb00a32ad4

📥 Commits

Reviewing files that changed from the base of the PR and between 54c0283 and 094552c.

📒 Files selected for processing (1)
  • crates/perry-codegen/src/inprocess.rs

Comment thread crates/perry-codegen/src/inprocess.rs
CodeRabbit's catch. The comment claims watchOS's ILP32 arm64_32 is still
the AArch64 backend and therefore covered, but the test never asserted
it -- the one triple in the list whose coverage is not obvious from its
name. Verified: it resolves.
@proggeramlug
proggeramlug merged commit 6d47506 into main Aug 4, 2026
8 of 13 checks passed
@proggeramlug
proggeramlug deleted the perf/llvm-inprocess-target-set branch August 4, 2026 07:19
proggeramlug added a commit that referenced this pull request Aug 4, 2026
…ly linked (#7353)

Perry now links LLVM 22 statically and ships self-contained. We own the
assumption rather than pushing it onto the user, and there is no "install
a compatible clang" step left to get wrong.

It is load-bearing, not a preference. The explicit statepoint bridge is
gone (#7348), so RS4GC is the only native-root backend, and RS4GC cannot
round-trip its IR through an external `opt` plus a different clang
(#7339). Keeping this opt-in meant the only working statepoint path was
behind a flag nobody sets.

Two defaults flip together, because either alone is half a feature:

  * `llvm-inprocess` becomes a default cargo feature.
  * `inprocess_requested()` defaults to ON -- but only iff the backend is
    actually compiled in. Defaulting to `true` unconditionally would route
    every compile in a `--no-default-features` build into the
    not-built-in stub and fail it outright. Verified both ways.

`PERRY_LLVM_INPROCESS=0` reverts to the clang subprocess for bisection,
and `--no-default-features` still builds the text path.

CI: a new `.github/actions/setup-llvm22` composite action, referenced from
all 44 toolchain steps across 18 workflows. One definition rather than 44
inline recipes, because the three platforms need three different sources
and only one is obvious -- Ubuntu 24.04's own llvm-dev is 18, and
chocolatey's `llvm` is the clang toolchain with no llvm-config.exe and
none of the static libs. Every arm asserts the major version.

Size: 98.9 MB, not the 185.9 MB this would have cost before #7350 --
`initialize_all()` was linking ~18 backends nothing can reach.

Also fixed, surfaced by the flip: PERRY_LLVM_KEEP_IR promises the whole
scratch dir including the .o. The clang path got that free because the
object is a file; in-process returns bytes and silently dropped it,
degrading a debugging aid exactly when someone is debugging.

Verified on the 81-module zod corpus with no env set: compiles, output
byte-identical to the clang path, and PERRY_RS4GC=1 now compiles a
try-carrying probe with no further flags. 605 codegen tests pass.

Co-authored-by: Ralph Küpper <ralph@skelpo.com>
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.

1 participant