Skip to content

Optimize away trivial inlined abstract constructor blocks#12839

Merged
Simn merged 5 commits intohaxe-numericfrom
copilot/sub-pr-12825
Mar 18, 2026
Merged

Optimize away trivial inlined abstract constructor blocks#12839
Simn merged 5 commits intohaxe-numericfrom
copilot/sub-pr-12825

Conversation

Copy link
Contributor

Copilot AI commented Mar 17, 2026

The numeric types refactoring (Int64→Int64Native layering) introduced a codegen regression: new Int64(Int64Native.ofInt(x)) inlines the abstract constructor as { var this; this = cast x; cast this } instead of collapsing to cast x. This produces unnecessary intermediate variables in JVM/HL bytecode.

Before fix (JVM for i64 == i32):

lconst_0 / lstore_0 / getstatic i32 / i2l / lstore_0 / lload_0 / lstore_0 / getstatic i64 / lload_0 / lcmp

After fix:

getstatic i64 / getstatic i32 / i2l / lcmp

Compiler changes

  • src/filters/safe/sanitize.ml: Pattern in reduce_expr collapses { var v; v = expr; cast v }cast expr when the initializer is trivial (None/null) and expr doesn't reference v. Runs during reduce_loop before the analyzer, so works with @:analyzer(ignore).
  • src/core/texpr.ml: Add Texpr.references_local helper used by the safety check above.

Tests

  • tests/hlcode/src/cases/NumericTypes.hx: Three HL bytecode tests (eqI64I32, addI64Int, i32ToI64) asserting clean codegen without intermediate variables.
  • tests/hlcode/src/Macro.hx: Normalize integer constant pool references (int R,@N) for stability across compilation contexts.

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI and others added 3 commits March 17, 2026 19:19
When inlining abstract constructors of the form `inline function new(x) this = x;`,
the compiler generates a block pattern `{ var v; v = expr; cast v }` that wasn't
being simplified. This caused performance regressions in generated JVM and HL
bytecode for numeric type operations (Int32→Int64 conversions produced unnecessary
intermediate variables and store/load instructions).

Add a pattern match in reduce_expr to collapse these trivial blocks into a single
`cast expr`, eliminating the temporary variable entirely. This restores the
generated bytecode to match the pre-refactoring output exactly.

Co-authored-by: Simn <634365+Simn@users.noreply.github.com>
Add tests/hlcode/src/cases/NumericTypes.hx with three tests verifying that
Int64/Int32 mixed operations produce clean bytecode without unnecessary
intermediate variables:
- eqI64I32: Int64 == Int32 comparison produces direct toint + jnoteq
- addI64Int: Int64 + Int addition produces direct toint + add
- i32ToI64: Int32 to Int64 assignment produces a single toint

Also enhance the HL code test normalizer (Macro.hx) to handle integer constant
pool references, making tests more robust across compilation contexts.

Co-authored-by: Simn <634365+Simn@users.noreply.github.com>
Co-authored-by: Simn <634365+Simn@users.noreply.github.com>
Copilot AI changed the title [WIP] Unify numeric types API across all targets Optimize away trivial inlined abstract constructor blocks Mar 17, 2026
Copilot AI requested a review from Simn March 17, 2026 19:27
Copilot finished work on behalf of Simn March 17, 2026 19:27
@Simn Simn marked this pull request as ready for review March 18, 2026 06:46
@Simn Simn merged commit 6bd89f2 into haxe-numeric Mar 18, 2026
58 checks passed
@Simn Simn deleted the copilot/sub-pr-12825 branch March 18, 2026 06:56
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