Open InBetweenNames opened 1 month ago
Hey thanks for your interest! Unfortunately the always_tail
attribute is a really important performance optimization for interpreters like this one. The other option would be a type of computed goto , but that doesn't exist in zig yet. It seems the ideal path here would be to file a bug on the zig compiler, which would ideally end up in an llvm upstream patch, fixing the issue.
The other potential path would be adding a secondary mode of execution that is a switch statement for platforms that don't support always_tail
. I would be open to this path, though it will involve a lot of code reshuffling and I'm pretty busy atm with the register backend.
Hi rdunnington,
I did a lot of reading and it seems you're right. However, I have good news to share: https://github.com/ziglang/zig/commit/3929cac154d71a3e19fd028fc67c1d1d15823ca2
That feature you linked seems to have just landed on nightly! Pretty exciting stuff. What do you think about porting over the TCO-based code over to this when it lands in stable?
Oh yeah that's awesome! I happened to see that today too. 😁 I think I would want to experiment with it anyway to see what the perf is like so I'm definitely interested in trying it out.
I will also say that I am a bit surprised that tail-calls don't work on MIPS in general. I'm only familiar with x86 but assuming MIPS still keeps track of the stack in a similar way using stack pointers, I would think the same mechanism could be implemented there as well. It might still be worth making an isolated repro and submitting a bug on the zig compiler if you are interested in advancing MIPS support in general.
Yeah I'll poke around LLVM and see what's the root cause in there. What's happening is Zig is lowering .always_tail
call sites into the LLVM musttail
attribute which is handled solely by the backend. Even ARM 32-bit is actively being worked on in this area to bring its TCO up to par with the more used LLVM backends. There's nothing special going on with MIPS here I don't think.
Hah, imagine if it's this simple:
It looks like the MIPS backend disables tail calls by default, even if they would otherwise be possible to perform
Sorry for the spam, but enabling this did indeed work on a C test program:
test.c:
int (*g)(void);
int __attribute__((noinline)) f(void) {
++g;
__attribute__((musttail)) return (*g)();
}
zig cc -target mips-linux-musl -O3 -mllvm -mips-tail-calls test.c -shared
The above command line works while removing the -mllvm -mips-tail-calls
causes the tail call to not be optimized out.
Made a ticket here: https://github.com/ziglang/zig/issues/21332
Nice investigation and thanks for the followup 👍.
Unfortunately, the LLVM MIPS32 backend doesn't support the
always_tail
call attribute and therefore the build fails on this platform. It's unclear to me if this is just the MIPS backend not being sophisticated enough to understand this attribute or if there are performance implications.