-
-
Notifications
You must be signed in to change notification settings - Fork 159
fix(codegen): unbreak in-process RS4GC on inline asm and relocation-grown functions #8128
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
fc5e580
fix(codegen): optnone post-RS4GC relocation-bloated functions
cfb89a7
fix(codegen): reserve deep stacks for LLVM unit workers
69492b1
fix(codegen): exempt the inline-asm loop barrier from RS4GC
c9e271a
docs: changeset for the RS4GC inline-asm and compile-blowup fixes
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| ### Fixed | ||
|
|
||
| - Exempt the empty inline-asm loop-preservation barrier from | ||
| `rewrite-statepoints-for-gc`. RS4GC wrapped it into a `gc.statepoint` whose | ||
| callee is inline asm — IR the verifier rejects ("Cannot take the address of | ||
| an inline asm!"). The external `opt` path aborts on that; the in-process | ||
| path ran no post-rewrite verify and fed the broken module to ISel, where it | ||
| died as a bare SIGBUS with no diagnostic. The barrier now carries | ||
| `"gc-leaf-function"` at all three emission sites (an empty asm can never | ||
| reach a safepoint), and the in-process pipeline verifies after the rewrite | ||
| so a future invalid shape fails loudly instead of crashing the backend. | ||
|
|
||
| - Cap the in-process optimization cost of statepoint relocation fan-out. The | ||
| #4880 opt-tier decision is made from pre-rewrite sizes, but one 51k-line | ||
| minified-bundle closure grew 40x to 2.1M instructions under RS4GC and a | ||
| single `-Os` function pass then ran over an hour on it. Post-rewrite, | ||
| functions past 512k instructions (tunable via | ||
| `PERRY_LL_RS4GC_OPTNONE_INSTRS`, registered as a build-cache key) are | ||
| stamped `optnone`+`noinline`, so the pipeline skips exactly the exploded | ||
| functions and still optimizes their siblings; the affected unit now | ||
| finishes in ~21s. `optnone` gates only the middle-end, leaving the | ||
| statepoint lowering and compact GC map unchanged. | ||
|
|
||
| - Reserve 64 MiB stacks for LLVM codegen-unit workers. Pass and ISel | ||
| recursion scales with function size, and a relocation-grown function | ||
| overflowed the default 2 MiB worker stack — a guard-page SIGBUS with no | ||
| crash report. The reservation is address space, not resident memory. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
Repository: PerryTS/perry
Length of output: 1149
🏁 Script executed:
Repository: PerryTS/perry
Length of output: 26373
🏁 Script executed:
Repository: PerryTS/perry
Length of output: 50370
🌐 Web query:
LLVM LangRef optnone alwaysinline noinline incompatibility and Inkwell 0.9.0 FunctionValue remove_enum_attribute API💡 Result:
The LLVM function attributes optnone, alwaysinline, and noinline possess specific compatibility rules designed to enforce the behavior of optimization pipelines, particularly -O0 [1][2][3]. Incompatibility and Behavior: 1. optnone and alwaysinline: These attributes are fundamentally incompatible [1][2]. The optnone attribute indicates that a function should not be optimized, while alwaysinline mandates that the function be inlined [1][2][4]. The LLVM verifier will reject IR where both attributes are present on the same function [2]. 2. optnone and noinline: Historically, optnone implicitly requires or implies noinline to ensure the function is not inlined [1][5][3]. While optnone prevents most optimizations, alwaysinline callees are an exception and may still be inlined into an optnone function body [1][6]. 3. noinline and alwaysinline: These are explicitly incompatible and cannot coexist on the same function [2]. Inkwell 0.9.0 FunctionValue API: In Inkwell 0.9.0, the FunctionValue struct provides the remove_enum_attribute method to manage these attributes [7][8][9]. This method allows you to programmatically remove attributes from a function [7][10]. API Signature: pub fn remove_enum_attribute(self, loc: AttributeLoc, kind_id: u32) Usage: To use this method, you specify the AttributeLoc (e.g., AttributeLoc::Function) and the kind_id corresponding to the attribute you wish to remove [7][11]. Since LLVM attributes are internally represented as enum values, you must identify the correct kind_id for the attribute (e.g., alwaysinline or optnone) you intend to remove to resolve conflicts before the verifier is invoked [2][10][11]. It is important to note that if you are generating IR and encountering these conflicts, you should ensure your logic prevents the simultaneous application of incompatible attributes, as the LLVM verifier will trigger a fatal error if these rules are violated [2][12].
Citations:
Remove
alwaysinlinebefore demotion.An oversized function can carry
alwaysinlineafter RS4GC. Addingoptnoneandnoinlinethen creates invalid LLVM IR. RemovealwaysinlinewithFunctionValue::remove_enum_attribute, and add a regression fixture that verifies the module after demotion.🤖 Prompt for AI Agents