Skip to content

Conversation

altxtech
Copy link
Contributor

@altxtech altxtech commented Aug 29, 2025

Context

Closes Shopify#710

Changes

HIR

  • Added a new instruction NewRangeFixnum that mirrors NewRange but is specialized for Fixnum endpoints.
  • Marked as leaf and effect-free (unlike NewRange, which may call <=>).

Codegen

  • Added gen_new_range_fixnum, wired to the new instruction.
  • Uses gen_prepare_call_with_gc(asm, state) since range allocation may trigger GC, but does not call Ruby methods.
  • Emits a direct call to rb_range_new.

Optimization

  • Added optimize_ranges pass: conservatively rewrites NewRange into NewRangeFixnum when one or both ends are statically Fixnum literals (with guards added for the dynamic side if needed).
  • This covers the simple literal/guardable cases that can be proven cheaply.

At this point I haven’t added rewrites for parameter–parameter ranges.
From looking at how opt_plus works, it seems to rely on profiling info, but I don’t fully understand whether that same info is available for newrange.
Since I’m still new to this codebase (and to low-level Rust in general), I decided to keep the optimization conservative for now and get maintainer feedback before broadening it.

@altxtech
Copy link
Contributor Author

@tekknolagi

Could you take a look at this draft PR? Want to make sure this is the right direction.

@tekknolagi
Copy link
Contributor

I'm on vacation for the next two weeks but someone else on the team can give it a look!

@tekknolagi
Copy link
Contributor

cc @ruby/jit

@altxtech altxtech marked this pull request as ready for review August 30, 2025 19:01
@matzbot matzbot requested a review from a team August 30, 2025 19:01
zjit/src/hir.rs Outdated
@@ -2082,6 +2135,11 @@ impl Function {
worklist.push_back(high);
worklist.push_back(state);
}
&Insn::NewRangeFixnum { low, high, state, .. } => {
Copy link
Member

Choose a reason for hiding this comment

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

This can be stacked with NewRange like

            &Insn::NewRangeFixnum { low, high, state, .. } |
            &Insn::NewRange { low, high, state, .. } => {
                worklist.push_back(low);
                worklist.push_back(high);
                worklist.push_back(state);
            }

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed

zjit/src/hir.rs Outdated
@@ -6548,6 +6608,116 @@ mod opt_tests {
");
}

#[test]
fn test_optimize_range_fixnum_inclusive_literals() {
eval(r#"
Copy link
Member

Choose a reason for hiding this comment

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

I think none of the new tests new r# as there's no character needs escaping.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will check

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed

def test(a)
(a...10)
end
test(2); test(3)
Copy link
Member

Choose a reason for hiding this comment

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

Can you add these cases to test/ruby/test_zjit.rb too as integration tests? Remember to add call_threshold: 2 option so we actually run the optimzied HIR.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Tests added

@altxtech altxtech requested a review from st0012 September 1, 2025 21:04
@k0kubun k0kubun enabled auto-merge (squash) September 2, 2025 17:10
@k0kubun k0kubun merged commit c026627 into ruby:master Sep 2, 2025
86 checks passed
@altxtech altxtech deleted the altxtech/new-range-fixnum-instruction branch September 2, 2025 17:45
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.

ZJIT: Make HIR NewRangeFixnum instruction
4 participants