Skip to content

[Lang] Attach only a cheap source header per AST node - #857

Closed
hughperkins wants to merge 1 commit into
mainfrom
hp/po-ast-pos-header
Closed

[Lang] Attach only a cheap source header per AST node#857
hughperkins wants to merge 1 commit into
mainfrom
hp/po-ast-pos-header

Conversation

@hughperkins

Copy link
Copy Markdown
Collaborator

This is change 2 of #804 (@duburcqa), split out on its own so it can land independently of that PR's other change.
The code is Alexis's; this PR adds only the measurement below.

What

ASTTransformerBase.__call__ attaches source-position info to every generated IR node, and did so via
get_pos_info, which builds a TextWrapper-formatted source-line-plus-caret hint. That formatting therefore ran
for every stmt/expr node of every kernel compilation.

The eager per-node path now attaches only the cheap File "...", line N, in fn header (get_pos_header). The full
hint is still produced on the actual compile-error path -- the except handler in the same function calls
get_pos_info -- so compile-error messages are unchanged.

Why split it out

#804 pairs this with an unrelated change to _inside_class (replacing an O(len(sys.modules)) scan with a
linecache lookup). The two are independent, and on the workload below only this one matters, so separating them
lets this land on its own merits.

Impact

Measured on a kernel-build-heavy workload (a qipc solver step, ~130 offloaded tasks), timing the first step after
editing one kernel. Variants were interleaved over a single unchanged build with only this file swapped between
cells, so no rebuild and no exposure to a neighbouring job on the node; each figure is one full cold-warm-edit
cycle against a fresh cache.

variant rep 1 rep 2
unpatched 10.77 s 10.58 s
this PR 6.54 s 6.60 s
full #804 (this + the _inside_class change) 6.52 s 6.52 s

So this change is worth ~4.1 s of the ~4.2 s that #804 delivers here; the _inside_class scan is 0.05 s on this
workload, within noise. #804's own suite-wide measurement attributes most of its win to this change as well
(
-10% of Scene.build out of -12.5% combined).

Testing

test_exception.py, test_syntax_errors.py, test_nested_kernel_error.py and test_ast_refactor.py -- the suites
that assert on error-message text -- give 161 passed both with and without the change, on the same build.

Made with Cursor

ASTTransformer attached full source-position info to every generated IR node via get_pos_info, which builds a
TextWrapper-formatted source-line-plus-caret hint for each node. That formatting ran for every AST node of every
kernel compilation and dominated the Python side of a kernel build. The eager per-node path now attaches only the
cheap 'File "...", line N, in fn' header; the full hint is still produced on the actual compile-error path, so
compile-error messages are unchanged.

This is change 2 of #804, split out on its own.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 362c37c119

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

# hint (get_pos_info) here means running TextWrapper for every AST node of every kernel compilation,
# which dominates kernel build time. The full hint is still produced on the actual compile-error path
# below (get_pos_info in the except handler), so error messages are unchanged.
info = ctx.get_pos_header(node) if isinstance(node, (ast.stmt, ast.expr)) else ""

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve full source hints for backend diagnostics

When a diagnostic is emitted after AST conversion, it does not re-enter this except handler; backend paths such as bounds/type-check assertions and debug overflow reporting concatenate stmt->get_tb() from the IR. Because the IR now stores only this header, those user-facing messages lose the source line/caret that get_pos_info() used to provide, so compile/runtime diagnostics emitted from transforms or codegen are no longer unchanged.

Useful? React with 👍 / 👎.

@github-actions

Copy link
Copy Markdown

@github-actions

Copy link
Copy Markdown

@github-actions

Copy link
Copy Markdown

@hughperkins

hughperkins commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator Author

Agent wrote:

Closing this: the change is not behaviour-preserving, and my claim above that "error messages are unchanged" was
wrong.

The per-node source info is not read only by the compile-error path. It is embedded in DebugInfo and surfaces in
runtime diagnostics, so dropping the source-line-plus-caret hint from it changes user-visible messages.
test_overflow.py asserts the offending line appears in the overflow message:

assert 'return a + b' in 'Addition overflow detected in File ".../test_overflow.py", line 64, in foo:\n\n'

Reproduced on CPU against the same build: main 130 passed, this branch 64 failed. CI caught it on the Mac CPU jobs.

#858 takes the same hotspot by memoising get_pos_info instead, which is byte-identical by construction and so
keeps test_overflow.py green. It also measures a little better on the workload I care about, since it removes the
per-node formatting entirely rather than replacing it with a cheaper format.

@github-actions

Copy link
Copy Markdown

@github-actions

Copy link
Copy Markdown

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