Commit graph

547 commits

Author SHA1 Message Date
Max Bernstein
2899ff172c
ZJIT: Only specialize direct positional-positional calls (#13899)
This is temporary until we have a unified calling convention.
2025-07-15 13:39:02 -04:00
Alan Wu
3922a14a22 ZJIT: Make lir::Opnd::const_ptr take any pointer to save on casts 2025-07-14 22:11:24 -04:00
Alan Wu
7a7f128d0d ZJIT: Add a ccall macro that also adds an LIR comment
This DRYs up the `asm_comment!` + `asm.ccall` combo, and makes ccalls
have a comment by default.
2025-07-14 22:11:24 -04:00
Max Bernstein
a6d483971a ZJIT: Make debug info more detailed
Print the filename, line number, and whether or not the function has
been optimized:

```
Initial HIR:
fn initialize@test.rb:4:
bb0(v0:BasicObject):
  v2:Fixnum[1] = Const Value(1)
  SetIvar v0, :@a, v2
  Return v2

Optimized HIR:
fn initialize@test.rb:4:
bb0(v0:BasicObject):
  v2:Fixnum[1] = Const Value(1)
  SetIvar v0, :@a, v2
  Return v2
```
2025-07-14 16:34:32 -04:00
Takashi Kokubun
e288a86692
ZJIT: Restore SP register after JIT-to-JIT call (#13882)
Co-authored-by: Alan Wu <alansi.xingwu@shopify.com>
Co-authored-by: Stan Lo <stan.lo@shopify.com>
2025-07-14 12:22:13 -07:00
Takashi Kokubun
3ec46aad37
ZJIT: Mark objects baked in JIT code (#13862) 2025-07-11 13:24:08 -07:00
Max Bernstein
b0b1712b52
ZJIT: Use Vec instead of HashMap for profiling (#13809)
This is notably faster: no need to hash indices.

Before:

```
plum% samply record ~/.rubies/ruby-zjit/bin/ruby --zjit benchmarks/getivar.rb
ruby 3.5.0dev (2025-07-10T14:40:49Z master 51252ef8d7) +ZJIT dev +PRISM [arm64-darwin24]
itr:   time
 #1: 5311ms
 #2:   49ms
 #3:   49ms
 #4:   48ms
```

After:

```
plum% samply record ~/.rubies/ruby-zjit/bin/ruby --zjit benchmarks/getivar.rb
ruby 3.5.0dev (2025-07-10T15:09:06Z mb-benchmark-compile 42ffd3c1ee) +ZJIT dev +PRISM [arm64-darwin24]
itr:   time
 #1: 1332ms
 #2:   49ms
 #3:   48ms
 #4:   48ms
```
2025-07-11 16:55:06 +00:00
Takashi Kokubun
b760afe2b7
ZJIT: Improve asm comments for side exits (#13853)
* ZJIT: Improve asm comments for side exits

* Use GuardType(Type) and GuardBitEquals(VALUE)
2025-07-11 09:49:25 -07:00
Max Bernstein
bd162dc0cb ZJIT: Run validation between compiler passes in debug mode 2025-07-11 12:30:46 -04:00
Max Bernstein
e53bfe217e ZJIT: Fix missing find!() for SetIvar 2025-07-11 12:30:46 -04:00
Max Bernstein
0d7d87b40f ZJIT: Gracefully handle iseq_name with NULL ISEQ 2025-07-11 12:30:46 -04:00
Max Bernstein
e3456d6180 ZJIT: Don't stringify Function in ValidationError
That's not the validator's responsibility; the caller can choose to
later.
2025-07-11 12:30:46 -04:00
Jeremy Evans
2ab38691a2 Add Set C-API
This should be a minimal C-API needed to deal with Set objects. It
supports creating the sets, checking whether an element is the set,
adding and removing elements, iterating over the elements, clearing
a set, and returning the size of the set.

Co-authored-by: Nobuyoshi Nakada <nobu.nakada@gmail.com>
2025-07-11 15:24:23 +09:00
Alan Wu
1317377fa7 ZJIT: A64: Have add/sub to SP be single-instruction
Previously a missed optimization for add followed by mov. While we're
at it, have Add and Sub share the same match arm in arm64_split().
2025-07-11 15:08:49 +09:00
Takashi Kokubun
0e2bae82dc
ZJIT: Print a message about ZJIT_RB_BUG when unused (#13852) 2025-07-10 18:12:29 -07:00
Max Bernstein
470e11a411 ZJIT: Mark Snapshot as having an output
Other instructions use it as an operand and #13814 especially needs it
to have an output for validation.
2025-07-10 17:10:50 -04:00
Max Bernstein
45be0e99a8 ZJIT: Validate that each IR instruction appears at most once 2025-07-10 17:10:50 -04:00
Takashi Kokubun
b1828cbbfe
ZJIT: Implement patch points on BOP redefinition (#13850)
Co-authored-by: Max Bernstein <max@bernsteinbear.com>
2025-07-10 13:40:40 -07:00
Ken Jin
214983bd9b
ZJIT: Add def-use validator via dataflow analysis (#13814)
This PR adds a validator based on dataflow analysis to ZJIT. It checks that all uses are dominated by a GEN-DEF prior.

See issue https://github.com/Shopify/ruby/issues/591

This is especially useful in validating optimizations don't zap away instructions that are actually needed, e.g. DCE.

Also included: a slight refactor of the DCE code to its own function, so I can reuse it.

Note: the algorithm uses the worklist algorithm rather than the iterative version for faster convergence.

Co-Authored-By: Max Bernstein <ruby@bernsteinbear.com>
2025-07-10 19:11:54 +00:00
Takashi Kokubun
9ab80a7455
ZJIT: Avoid optimizing locals on eval (#13840)
* ZJIT: Avoid optimizing locals on eval

* Maintain the local state for eval
2025-07-10 12:08:09 -07:00
Takashi Kokubun
f5085c70f2
ZJIT: Mark profiled objects when marking ISEQ (#13784) 2025-07-09 16:03:23 -07:00
Stan Lo
e2a81c738c ZJIT: Optimize opt_and and opt_or instructions for Fixnum 2025-07-09 17:50:41 -04:00
Stan Lo
10b582dab6 ZJIT: Profile opt_and and opt_or instructions 2025-07-09 17:50:41 -04:00
Stan Lo
e9cd3060ac
ZJIT: Support guarding *Exact types (#13797)
ZJIT already can generate guard type instructions for *Exact types.

For example:

```
def test(strings)
  strings.map do |string|
    string.bytesize
  end
end

test(["foo", "bar"])
```

```
HIR:
fn block in test:
bb0(v0:BasicObject, v1:BasicObject):
  PatchPoint MethodRedefined(String@0x1014be890, bytesize@0x19f1)
  v7:StringExact = GuardType v1, StringExact
  v8:Fixnum = CCall bytesize@0x16fa4cc18, v7
  Return v8

```

But zjit only supported guarding fixnums so this script would panic.

This commit adds support for guarding *Exact types.
2025-07-08 23:56:52 -04:00
Max Bernstein
c691095f2e ZJIT: Use BitSet in HIR 2025-07-08 15:57:31 -04:00
Max Bernstein
e59f404bea ZJIT: Add a BitSet type 2025-07-08 15:57:31 -04:00
Stan Lo
342ada1546 ZJIT: Use nil? optimization to test guard generation against different types 2025-07-08 15:51:44 -04:00
Stan Lo
79915e6f78 ZJIT: Profile nil? calls
This allows ZJIT to profile `nil?` calls and create type guards for
its receiver.

- Add `zjit_profile` to `opt_nil_p` insn
- Start profiling `opt_nil_p` calls
- Use `runtime_exact_ruby_class` instead of `exact_ruby_class` to determine
  the profiled receiver class
2025-07-08 15:51:43 -04:00
Stan Lo
9e4157a01c ZJIT: Make type definition code more consistent 2025-07-08 12:28:03 -04:00
Stan Lo
af892c1be3 ZJIT: More accurately model Class types 2025-07-08 12:28:03 -04:00
Stan Lo
6c20082852 ZJIT: Support inference of ModuleExact type 2025-07-08 12:28:03 -04:00
Stan Lo
e0841a795b
ZJIT: Fix Rust warnings (#13813) 2025-07-07 23:46:21 +00:00
Daniel Colson
1f024cfdba
ZJIT: Add opnds macro for Vec<InsnId> to Vec<Opnd> (#13805)
Along the same lines as the `opnd` macro we already have, but for a
`Vec<InsnId>` instead of a single `InsnId`.

This gets a few for loops and `jit.get_opnd` calls out of the `gen_`
functions.
2025-07-07 11:26:49 -07:00
Ken Jin
c1937480ac
ZJIT: Add a simple HIR validator (#13780)
This PR adds a simple validator for ZJIT's HIR.

See issue https://github.com/Shopify/ruby/issues/591
2025-07-07 11:45:01 -04:00
Daniel Colson
002d746418 ZJIT: Avoid double negative in Mem debug
Prior to this commit the debug output for negative offsets would look
like:

```
Mem64[Reg(3) - -8
```

That makes it look like we're adding instead of subtracting. After this
commit we'll print:

```
Mem64[Reg(3) - 8
```
2025-07-07 15:12:20 +09:00
Stan Lo
68af19290a Support inference of ClassExact type 2025-07-03 20:43:44 -04:00
Stan Lo
0c694b5688 Add missed runtime_exact_ruby_class case for Regexp 2025-07-03 20:43:44 -04:00
Takashi Kokubun
ed3fd94e77
ZJIT: Panic on BOP redefinition only when needed (#13782) 2025-07-03 13:09:10 -07:00
Takashi Kokubun
0abe17dae0
ZJIT: Bail out on register spill (#13773) 2025-07-03 09:30:45 -07:00
Takashi Kokubun
d5f5a56bf2
ZJIT: Reject ISEQs with too-large stack_max (#13770) 2025-07-02 13:01:24 -07:00
Max Bernstein
e240b415a5
ZJIT: Add reason for SideExit (#13768)
This makes it clearer what is unimplemented when looking at HIR dumps.
2025-07-02 14:57:09 -04:00
Takashi Kokubun
1d31c98e04
ZJIT: Avoid panicing with "Option::unwrap() on None" (#13762) 2025-07-02 10:46:08 -07:00
Takashi Kokubun
6e28574ed0
ZJIT: Support spilling basic block arguments (#13761)
Co-authored-by: Max Bernstein <max@bernsteinbear.com>
2025-07-02 10:37:30 -07:00
Stan Lo
a0bf36a9f4
ZJIT: Annotate NilClass#nil? and Kernel#nil?
These methods return fixed `true` or `false` so we can be certain about their return types.
2025-07-02 17:15:52 +00:00
Alan Wu
ddb8de1f5f ZJIT: throw to HIR 2025-07-03 00:52:24 +09:00
Alan Wu
565ab3ef57 ZJIT: Use initialization shorthand 2025-07-03 00:52:24 +09:00
Stan Lo
6af5398359
ZJIT: Support Regexp type (#13760) 2025-07-02 08:06:59 -04:00
Takashi Kokubun
53baafe496
ZJIT: Shorten Debug print for 64-bit VReg (#13763) 2025-07-01 15:11:58 -07:00
Takashi Kokubun
2fda843479
ZJIT: Stop tracking EP == BP assumption on JIT entry (#13752)
* ZJIT: Stop tracking EP == BP assumption on JIT entry

* Enable test_method.rb as well
2025-07-01 11:59:33 -07:00
ywenc
03e08a946d ZJIT: Add codegen for IsNil 2025-06-30 17:04:15 -07:00