-
-
Notifications
You must be signed in to change notification settings - Fork 159
fix(codegen): announce the kept object on the statepoint compile arm #8097
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
Changes from all commits
bd20b75
4f4b209
6571ddf
ea497d4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| `compiler-output-regression` is capturing again. All 11 of its workloads failed | ||
| with the same error — "PERRY_LLVM_KEEP_IR did not report a retained object | ||
| path" — so none of them reached the behaviour the gate exists to measure. | ||
|
|
||
| `PERRY_LLVM_KEEP_IR` promises that intermediates are retained *and* their | ||
| locations printed; the harness recovers them by parsing `kept object:` off the | ||
| compile log. The in-process backend has two success arms: the byte-returning | ||
| arm writes the object and announces it, while the statepoint arm — taken | ||
| whenever the plan asks for `-S`, so the ordinary path on every statepoint | ||
| target — assembles straight to `plan.obj_path` and keeps the scratch dir. That | ||
| arm retained the object correctly but never announced it, and the harness went | ||
| blind the moment statepoints became the default backend. | ||
|
|
||
| The statepoint arm now announces the kept object too; retention was already | ||
| correct, so this restores the reporting half of the contract rather than | ||
| changing what is kept. | ||
|
|
||
| `keep_ir_retains_the_whole_scratch_dir` only ever ran with `native_roots: | ||
| false`, so the arm serving every statepoint target had no coverage; | ||
| `keep_ir_retains_the_whole_scratch_dir_under_native_roots` now runs the same | ||
| contract through it. | ||
|
|
||
| With the report restored the gate failed one step later, the same way and for | ||
| the same reason: the compile plan records `clang_path` for the analysis | ||
| re-compile to reuse, and the in-process backend records the string | ||
| `(in-process)` where a driver path would go. The harness's fallback was written | ||
| for a MISSING value, and a non-empty placeholder is truthy, so it went straight | ||
| to `subprocess.run` — `FileNotFoundError: '(in-process)'`. The harness now | ||
| treats the placeholder as "no driver recorded" and falls back to the clang it | ||
| already resolved; a genuinely recorded driver still wins. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -265,6 +265,40 @@ fn keep_ir_retains_the_whole_scratch_dir() { | |
| let _ = fs::remove_dir_all(&root); | ||
| } | ||
|
|
||
| #[test] | ||
| fn keep_ir_retains_the_whole_scratch_dir_under_native_roots() { | ||
| // The `native_roots: false` case above exercises the byte-returning arm. | ||
| // Under statepoints the plan asks for `-S`, so a DIFFERENT arm handles the | ||
| // compile: it writes assembly, assembles to `plan.obj_path`, and keeps the | ||
| // scratch dir. That arm is the ordinary path on every statepoint target, | ||
| // and it was the untested one — which is how it came to retain the object | ||
| // without ever printing `kept object:` (#8087). | ||
| let Some(root) = temp_root_if_clang_available("keep-native-roots") else { | ||
| return; | ||
| }; | ||
| let policy = TempFilePolicy { | ||
| keep: true, | ||
| debug_symbols: false, | ||
| }; | ||
| if compile_ll_to_object_in(&root, &test_ir(11), None, policy, true).is_err() { | ||
| // A host whose assembler cannot serve the compact-map rewrite is not a | ||
| // failure of this contract; skip rather than assert on a missing tool. | ||
| let _ = fs::remove_dir_all(&root); | ||
| return; | ||
|
Comment on lines
+283
to
+287
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win Do not convert compilation failures into skipped tests. The 🤖 Prompt for AI Agents |
||
| } | ||
|
|
||
| let left = entries(&root); | ||
| assert_eq!(left.len(), 1, "expected one kept scratch dir: {left:?}"); | ||
| let kept = entries(&root.join(&left[0])); | ||
| for want in [".ll", ".o"] { | ||
| assert!( | ||
| kept.iter().any(|n| n.ends_with(want)), | ||
| "PERRY_LLVM_KEEP_IR must retain the {want} under native roots: {kept:?}" | ||
| ); | ||
| } | ||
| let _ = fs::remove_dir_all(&root); | ||
| } | ||
|
|
||
| #[test] | ||
| fn debug_symbols_do_not_change_the_temp_file_lifetime() { | ||
| // #7144 question (b), answered by measurement rather than by inheriting the | ||
|
|
||
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 | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
Repository: PerryTS/perry
Length of output: 18127
🏁 Script executed:
Repository: PerryTS/perry
Length of output: 13288
🏁 Script executed:
Repository: PerryTS/perry
Length of output: 15659
🏁 Script executed:
Repository: PerryTS/perry
Length of output: 520
Make the backend selection explicit in this test.
compile_ll_to_object_inselects in-process LLVM whenPERRY_LLVM_INPROCESSis unset and the default feature is enabled. It selects clang only for0,off, orfalse. Line 283 therefore inherits the process environment and does not deterministically cover either backend. Select the intended backend explicitly; the dedicated in-process test already callscompile_ll_inprocess_indirectly.🤖 Prompt for AI Agents