-
Notifications
You must be signed in to change notification settings - Fork 227
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
if/while (not= nil x)
doesn't always compile to jmpni
#1267
Comments
This makes sense mostly, as I specifically wrote a case for this so that fast loops could be compiled to break on EDIT: Logic for this optimization is in the function |
I've prepared a branch which appears to work correctly for all 8 cases. (defn test [a]
(var res false)
(if (not= nil a)
(set res true))
res)
(pp ((disasm test) :bytecode)) master: @[(ldf 2) (ldn 4) (neq 3 4 0) (jmpno 3 3) (ldt 2) (jmp 1) (ret 2)] branch: @[(ldf 2) (jmpni 0 2) (ldt 2) (ret 2)] I also added logic to remove @@ /src/core/specials.c -606,3 +643,3 @@
/* Compile jump to done */
labeljd = janet_v_count(c->buffer);
- if (!tail) janetc_emit(c, JOP_JUMP);
+ if (!tail && !(drop && janet_checktype(falsebody, JANET_NIL))) janetc_emit(c, JOP_JUMP); |
Looks like it works to me. The extra |
Tried it out with some tests for various repositories and didn't notice any issues 👍 |
This isn't so much an issue, as an observation.
I've noticed that minor changes can make significant differences in execution speed. One of those is coercing the compiler into using
jmpni
orjmpnn
fornot= nil
and= nil
.A minimal example:
If we make one minor change, the compiler performs the appropriate optimization:
In all variations of:
the only one that appears to optimize to a single op is
(while (,not= nil ,a)
.An interesting consequence is that the
while
loop above (with unconditionalbreak
) compiles to more efficient code thanif
:Hand-rolled, this could be written as just:
The text was updated successfully, but these errors were encountered: