-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Avoid moving REG_SP (make it a base pointer) #546
Comments
What you wrote makes sense. The main question I have is: can we count on the Another potential detail is: I remember Alan talking about using the call-threaded handlers so we can fall back to the interpreter for a single instruction, and in that case, we might end up in a situation where we don't know what the SP is. I think that, if we only use a BP, we don't care what the value of the SP is as much in YJIT. However, we probably would still need to always make sure that the SP is up to date whenever we exit JITted code. That's a bit of a bummer, because it means we probably would have to keep the @XrXr any comments? |
Yeah I think this make sense. I feel confident relying on We shouldn't need to change A note for implementation, since |
Currently it's always present, but I don't think we should rely on it. https://github.com/Shopify/yjit/blob/main/vm_insnhelper.c#L2172-L2200 suggests it's likely to be removed, but I believe we'll be able to calculate BP as
We'll always have to write cfp->sp on side exits (as we already do today). I don't think we'll have to update |
So we'd keep I'm not sure what the impact on code size would be. I think it might remove some instructions in a few places, but also add a few more in other places since we'd be updating the SP still 🤔 May remove some data dependencies as you said. |
The dependency thing is probably not going to make much of a perf difference since the limiting factor on stalls is probably memory access around the relatively quick sp calculation. The main win I see for making this change is making it easier to write codegen / develop the new backend. |
This is an idea to improve how we handle stack addresses to make codegen simpler to write and possibly improve performance.
Currently,
REG_SP
always has the same value ofreg_cfp->sp
, but to avoid unnecessary register/memory reads/writes we store ansp_offset
and build our memory operands (ctx_sp_opnd
) using that offset. When we call into C code, call another method, or return to the interpreter, we calljit_save_sp
, which updates bothREG_SP
andREG_CFP->sp
.This causes some awkwardness in our codegen, because any memory operands we build using
ctx_sp_opnd
become invalid whenREG_SP
is updated (since they are relative toREG_SP
). This requires us to be careful about when these operands are created vs used.For example in
gen_opt_aref
I think it would be possible to avoid this issue by treating
REG_SP
as a base pointer of the stack rather than a moving stack pointer (should we also rename it?). Basically this means thatREG_SP
would not move throughout the iseq, it would keep the same value it had at the YJIT entry point. UpdatingREG_CFP->sp
would be done in the same way in the same places, however we'd now use a temporary register instead of updatingREG_SP
(same as we do forjit_save_pc
).In addition to making codegen simpler to write, I believe this will reduce the number of block versions.
Currently there is this comment at the end of
gen_send_cfunc
:Calling an iseq ends up with an
sp_offset
of 0, but calling a cfunc ends up with ansp_offset
of 1 (we must push the return value from the cfunc ourselves). If we instead use the base SP rather than a moving SP, thesp_offset
s will be the same leaving both basic blocks, therefore have compatible ctx, and can jump into the same target.Another potential advantage (less sure of this) is that by not moving the register we will avoid a data dependency in following stack operations, which may improve CPU pipelining by avoiding stalls.
The text was updated successfully, but these errors were encountered: