summaryrefslogtreecommitdiff
path: root/yjit/src/backend/ir.rs
AgeCommit message (Collapse)Author
2023-11-28YJIT: Assert no patch overlap on pos_marker (#9048)Takashi Kokubun
2023-11-10YJIT: Auto fix for clippy::clone_on_copyAlan Wu
2023-11-07YJIT: Use u32 for CodePtr to save 4 bytes eachAlan Wu
We've long had a size restriction on the code memory region such that a u32 could refer to everything. This commit capitalizes on this restriction by shrinking the size of `CodePtr` to be 4 bytes from 8. To derive a full raw pointer from a `CodePtr`, one needs a base pointer. Both `CodeBlock` and `VirtualMemory` can be used for this purpose. The base pointer is readily available everywhere, except for in the case of the `jit_return` "branch". Generalize lea_label() to lea_jump_target() in the IR to delay deriving the `jit_return` address until `compile()`, when the base pointer is available. On railsbench, this yields roughly a 1% reduction to `yjit_alloc_size` (58,397,765 to 57,742,248).
2023-10-19YJIT: Return Option from asm.compile() for has_dropped_bytes()Alan Wu
So that we get a reminder to check CodeBlock::has_dropped_bytes(). Internally, asm.compile() already checks it, and this patch just propagates it out to the caller with a `#[must_use]`. Code GC logic moved out one level in entry_stub_hit(), so the body can freely use `?`
2023-10-19YJIT: Enable the dead_code lint and delete some dead codeAlan Wu
2023-10-17YJIT: Fix clippy::redundant_localsAlan Wu
> note: `#[deny(clippy::redundant_locals)]` on by default On Rust 1.73.0.
2023-10-05YJIT: Avoid writing return value to memory in `leave`Alan Wu
Previously, at the end of `leave` we did `*caller_cfp->sp = return_value`, like the interpreter. With future changes that leaves the SP field uninitialized for C frames, this will become problematic. For cases like returning from `rb_funcall()`, the return value was written above the stack and never read anyway (callers use the copy in the return register). Leave the return value in a register at the end of `leave` and have the code at `cfp->jit_return` decide what to do with it. This avoids the unnecessary memory write mentioned above. For JIT-to-JIT returns, it goes through `asm.stack_push()` and benefits from register allocation for stack temporaries. Mostly flat on benchmarks, with maybe some marginal speed improvements. Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
2023-09-29YJIT: Chain-guard opt_mult overflow (#8554)Takashi Kokubun
* YJIT: Chain-guard opt_mult overflow * YJIT: Support regenerating Jo after Mul
2023-09-15YJIT: Avoid creating a vector in get_temp_regs() (#8446)Takashi Kokubun
* YJIT: Avoid creating a vector in get_temp_regs() Co-authored-by: Alan Wu <alansi.xingwu@shopify.com> * Remove unused import --------- Co-authored-by: Alan Wu <alansi.xingwu@shopify.com> Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>
2023-09-15YJIT: Fix and enable the unused_imports warningAlan Wu
2023-09-14YJIT: Skip Insn::Comment and format! if disasm is disabled (#8441)Takashi Kokubun
* YJIT: Skip Insn::Comment and format! if disasm is disabled Co-authored-by: Alan Wu <alansi.xingwu@shopify.com> * YJIT: Get rid of asm.comment --------- Co-authored-by: Alan Wu <alansi.xingwu@shopify.com> Notes: Merged-By: k0kubun <takashikkbn@gmail.com>
2023-09-14YJIT: Initialize Vec with capacity for iterators (#8439)Takashi Kokubun
Notes: Merged-By: k0kubun <takashikkbn@gmail.com>
2023-09-14YJIT: Initialize Assembler vectors with capacity (#8437)Takashi Kokubun
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-08-11YJIT: implement codegen for rb_int_lshift (#8201)Maxime Chevalier-Boisvert
* YJIT: implement codegen for rb_int_lshift * Update yjit/src/asm/x86_64/mod.rs Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com> --------- Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com> Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-08-10YJIT: add mul() instruction to backend IR (#8195)Maxime Chevalier-Boisvert
2023-08-04YJIT: guard for array_len >= num in expandarray (#8169)Maxime Chevalier-Boisvert
Avoid generating long dispatch chains for all array lengths seen. Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-08-03YJIT: add jb (unsigned less-than) instruction to backend (#8168)Maxime Chevalier-Boisvert
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-07-29YJIT: Drop Copy trait from Context (#8138)Takashi Kokubun
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-07-27YJIT: implement missing `asm.jg` instruction in backend (#8130)Maxime Chevalier-Boisvert
YJIT: implement missing jg instruction in backend While trying to implement a specialize integer left shift, I ran into a problem where we have no way to do a greater-than comparison at the moment. Surprising we went this far without ever needing it. Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-07-06YJIT: Use registers to pass stack temps to C calls (#7920)Takashi Kokubun
* YJIT: Use registers to pass stack temps to C calls * YJIT: Update comments in ccall
2023-07-04YJIT: Break register cycles for C arguments (take 2) (#8018)Takashi Kokubun
* Revert "Revert "YJIT: Break register cycles for C arguments (#7918)"" This reverts commit 78ca085785460de46bfc4851a898d525c1698ef8. * Use shfited_live_ranges for the last-insn check Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-06-12Revert "YJIT: Break register cycles for C arguments (#7918)"Takashi Kokubun
This reverts commit 888ba29e462075472776098f4f95eb6d3df8e730. It caused a CI failure http://ci.rvm.jp/results/trunk-yjit@ruby-sp2-docker/4598881 and I'm investigating it.
2023-06-12YJIT: Break register cycles for C arguments (#7918)Takashi Kokubun
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-04-20YJIT: Merge lower_stack into the split pass (#7748)Takashi Kokubun
Notes: Merged-By: k0kubun <takashikkbn@gmail.com>
2023-04-19YJIT: Remove Insn::RegTemps (#7741)Takashi Kokubun
* YJIT: Remove Insn::RegTemps * Update a comment Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com> --------- Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com> Notes: Merged-By: k0kubun <takashikkbn@gmail.com>
2023-04-17YJIT: Spill a caller stack as late as possible (#7726)Takashi Kokubun
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-04-14YJIT: Add a counter to all side exits (#7720)Takashi Kokubun
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-04-14YJIT: Introduce Target::SideExit (#7712)Takashi Kokubun
* YJIT: Introduce Target::SideExit * YJIT: Obviate Insn::SideExitContext * YJIT: Avoid cloning a Context for each insn Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-04-13YJIT: Move stack_opnd from Context to Assembler (#7700)Takashi Kokubun
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-04-12YJIT: Let Assembler own Context (#7691)Takashi Kokubun
* YJIT: Let Assembler own Context * Update a comment Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com> --------- Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com> Notes: Merged-By: k0kubun <takashikkbn@gmail.com>
2023-04-06YJIT: Stack temp register allocation for arm64 (#7659)Takashi Kokubun
* YJIT: Stack temp register allocation for arm64 * Update a comment Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com> * Update comments about assertion * Update a comment Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com> --------- Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com> Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-04-04YJIT: Stack temp register allocation (#7651)Takashi Kokubun
Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com> Notes: Merged-By: k0kubun <takashikkbn@gmail.com>
2023-03-15YJIT: Eliminate unnecessary mov for trampolines (#7537)Takashi Kokubun
Notes: Merged-By: k0kubun <takashikkbn@gmail.com>
2023-03-07YJIT: Add comments to peek and x86_mergeTakashi Kokubun
Notes: Merged: https://github.com/ruby/ruby/pull/7453
2023-03-07YJIT: Merge lea and mov on x86_64 when possibleTakashi Kokubun
Notes: Merged: https://github.com/ruby/ruby/pull/7453
2023-03-02YJIT: shrink stack_size/sp_offet to u8/i8 (#7426)Maxime Chevalier-Boisvert
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-02-22YJIT: Introduce Opnd::Stack (#7352)Takashi Kokubun
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-02-02Fix typos in YJIT [ci skip]Alan Wu
2023-01-19YJIT: Refactor side_exitsJimmy Miller
Notes: Merged: https://github.com/ruby/ruby/pull/7155
2023-01-03YJIT: Dump spill error to stderr [ci skip]Alan Wu
Since the panic message is in stderr, better to use the same stream in case stdout and stderr are not synced due to IO redirection.
2022-11-23YJIT: Simplify Insn::CCall to obviate Target::FunPtr (#6793)Takashi Kokubun
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2022-11-22YJIT: Skip padding jumps to side exits on Arm (#6790)Takashi Kokubun
YJIT: Skip padding jumps to side exits Co-authored-by: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com> Co-authored-by: Alan Wu <alansi.xingwu@shopify.com> Co-authored-by: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com> Co-authored-by: Alan Wu <alansi.xingwu@shopify.com> Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2022-11-1832 bit comparison on shape idAaron Patterson
This commit changes the shape id comparisons to use a 32 bit comparison rather than 64 bit. That means we don't need to load the shape id to a register on x86 machines. Given the following program: ```ruby class Foo def initialize @foo = 1 @bar = 1 end def read [@foo, @bar] end end foo = Foo.new foo.read foo.read foo.read foo.read foo.read puts RubyVM::YJIT.disasm(Foo.instance_method(:read)) ``` The machine code we generated _before_ this change is like this: ``` == BLOCK 1/4, ISEQ RANGE [0,3), 65 bytes ====================== # getinstancevariable 0x559a18623023: mov rax, qword ptr [r13 + 0x18] # guard object is heap 0x559a18623027: test al, 7 0x559a1862302a: jne 0x559a1862502d 0x559a18623030: cmp rax, 4 0x559a18623034: jbe 0x559a1862502d # guard shape, embedded, and T_OBJECT 0x559a1862303a: mov rcx, qword ptr [rax] 0x559a1862303d: movabs r11, 0xffff00000000201f 0x559a18623047: and rcx, r11 0x559a1862304a: movabs r11, 0xb000000002001 0x559a18623054: cmp rcx, r11 0x559a18623057: jne 0x559a18625046 0x559a1862305d: mov rax, qword ptr [rax + 0x18] 0x559a18623061: mov qword ptr [rbx], rax == BLOCK 2/4, ISEQ RANGE [3,6), 0 bytes ======================= == BLOCK 3/4, ISEQ RANGE [3,6), 47 bytes ====================== # gen_direct_jmp: fallthrough # getinstancevariable # regenerate_branch # getinstancevariable # regenerate_branch 0x559a18623064: mov rax, qword ptr [r13 + 0x18] # guard shape, embedded, and T_OBJECT 0x559a18623068: mov rcx, qword ptr [rax] 0x559a1862306b: movabs r11, 0xffff00000000201f 0x559a18623075: and rcx, r11 0x559a18623078: movabs r11, 0xb000000002001 0x559a18623082: cmp rcx, r11 0x559a18623085: jne 0x559a18625099 0x559a1862308b: mov rax, qword ptr [rax + 0x20] 0x559a1862308f: mov qword ptr [rbx + 8], rax ``` After this change, it's like this: ``` == BLOCK 1/4, ISEQ RANGE [0,3), 41 bytes ====================== # getinstancevariable 0x5560c986d023: mov rax, qword ptr [r13 + 0x18] # guard object is heap 0x5560c986d027: test al, 7 0x5560c986d02a: jne 0x5560c986f02d 0x5560c986d030: cmp rax, 4 0x5560c986d034: jbe 0x5560c986f02d # guard shape 0x5560c986d03a: cmp word ptr [rax + 6], 0x19 0x5560c986d03f: jne 0x5560c986f046 0x5560c986d045: mov rax, qword ptr [rax + 0x10] 0x5560c986d049: mov qword ptr [rbx], rax == BLOCK 2/4, ISEQ RANGE [3,6), 0 bytes ======================= == BLOCK 3/4, ISEQ RANGE [3,6), 23 bytes ====================== # gen_direct_jmp: fallthrough # getinstancevariable # regenerate_branch # getinstancevariable # regenerate_branch 0x5560c986d04c: mov rax, qword ptr [r13 + 0x18] # guard shape 0x5560c986d050: cmp word ptr [rax + 6], 0x19 0x5560c986d055: jne 0x5560c986f099 0x5560c986d05b: mov rax, qword ptr [rax + 0x18] 0x5560c986d05f: mov qword ptr [rbx + 8], rax ``` The first ivar read is a bit more complex, but the second ivar read is much simpler. I think eventually we could teach the context about the shape, then emit only one shape guard. Notes: Merged: https://github.com/ruby/ruby/pull/6737
2022-11-01YJIT: Visualize live ranges on register spill (#6651)Takashi Kokubun
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2022-10-19YJIT: Skip dumping code for the other cb on --yjit-dump-disasm (#6592)Takashi Kokubun
YJIT: Skip dumping code for the other cb on --yjit-dump-disasm Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2022-10-17YJIT: Allow --yjit-dump-disasm to dump into a file (#6552)Takashi Kokubun
* YJIT: Allow --yjit-dump-disasm to dump into a file * YJIT: Move IO implementation to disasm.rs * YJIT: More consistent naming Notes: Merged-By: k0kubun <takashikkbn@gmail.com>
2022-10-17YJIT: Interleave inline and outlined code blocks (#6460)Takashi Kokubun
Co-authored-by: Alan Wu <alansi.xingwu@shopify.com> Co-authored-by: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com> Notes: Merged-By: k0kubun <takashikkbn@gmail.com>
2022-10-13fixes more clippy warnings (#6543)Jimmy Miller
* fixes more clippy warnings * Fix x86 c_callable to have doc_strings Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2022-09-30A bunch of clippy auto fixes for yjit (#6476)Jimmy Miller
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2022-09-14YJIT: Add Opnd#with_num_bits to use only 8 bits (#6359)Takashi Kokubun
* YJIT: Add Opnd#sub_opnd to use only 8 bits * Add with_num_bits and let arm64_split use it * Add another assertion to with_num_bits * Use only with_num_bits Notes: Merged-By: maximecb <maximecb@ruby-lang.org>