Ingredients?
$ nim --version
Nim Compiler Version 1.6.14 [Linux: arm]
Compiled at 2023-06-29
Copyright (c) 2006-2023 by Andreas Rumpf
active boot switches: -d:release
$ tcc --version
tcc version 0.9.28rc 2023-10-25 mob@6b967b1 (ARM eabi Linux)
What?
$ cat x.nim
echo "Hi, Nim!"
$ nim compile --cc:tcc x.nim
Hint: used config file '/etc/nim/nim.cfg' [Conf]
Hint: used config file '/etc/nim/config.nims' [Conf]
..........................................................
Hint: tcc -c -w -I/usr/lib/nim/lib -I/tmp/mc-yeti -o /home/yeti/.cache/nim/x_d/@m..@s..@susr@slib@snim@slib@ssystem.nim.c.o /home/yeti/.cache/nim/x_d/@m..@s..@susr@slib@snim@slib@ssystem.nim.c [Exec]
/home/yeti/.cache/nim/x_d/@m..@s..@susr@slib@snim@slib@ssystem.nim.c:319: error: unknown constraint 'q'
Error: execution of an external program failed: 'tcc -c -w -I/usr/lib/nim/lib -I/tmp/mc-yeti -o /home/yeti/.cache/nim/x_d/@m..@s..@susr@slib@snim@slib@ssystem.nim.c.o /home/yeti/.cache/nim/x_d/@m..@s..@susr@slib@snim@slib@ssystem.nim.c'
Digging...
$ awk '310<=NR && NR<=322' /home/yeti/.cache/nim/x_d/@m..@s..@susr@slib@snim@slib@ssystem.nim.c
static int __tcc_cas(int *ptr, int oldVal, int newVal)
{
unsigned char ret;
__asm__ __volatile__ (
" lock\n"
" cmpxchgl %2,%1\n"
" sete %0\n"
: "=q" (ret), "=m" (*ptr)
: "r" (newVal), "m" (*ptr), "a" (oldVal)
: "memory");
return ret;
}
There I only can surrender.
On AMD64 it compiles:
$ nim compile --cc:tcc x.nim
Hint: used config file '/etc/nim/nim.cfg' [Conf]
Hint: used config file '/etc/nim/config.nims' [Conf]
..........................................................
CC: ../../usr/lib/nim/lib/std/private/digitsutils.nim
CC: ../../usr/lib/nim/lib/system/dollars.nim
CC: ../../usr/lib/nim/lib/system/io.nim
CC: ../../usr/lib/nim/lib/system.nim
CC: x.nim
Hint: [Link]
tcc: error: undefined symbol 'fabs'
Error: execution of an external program failed: 'tcc -o /tmp/mc-yeti/x -ldl /home/yeti/.cache/nim/x_d/@m..@s..@susr@slib@snim@slib@sstd@sprivate@sdigitsutils.nim.c.o /home/yeti/.cache/nim/x_d/@m..@s..@susr@slib@snim@slib@ssystem@sdollars.nim.c.o /home/yeti/.cache/nim/x_d/@m..@s..@susr@slib@snim@slib@ssystem@sio.nim.c.o /home/yeti/.cache/nim/x_d/@m..@s..@susr@slib@snim@slib@ssystem.nim.c.o /home/yeti/.cache/nim/x_d/@mx.nim.c.o'
...and yes, I know how to add libm, but that was not the problem here.
Does (accidentally?) someone know how to keep TinyCC on Debian/ARMEL (Arm6HF/Pi1) happy?
You're joking?
Who says I always want to build Hello-Word-oneliners?
And TCC is mentioned in Nim's config and therefore I expect using it being a "legal" idea.
There I only can surrender.
codegen on other compilers for atomic compare-and-swap uses the compiler intrinsic directly. TCC being so barebones as it is uses x86 inline asm in absence of compiler builtins.
seems like the impl was borrowed from here.
ARM has no native CAS instruction so you need to implement your own using a spinlock. maybe try the libbionic impl?
I am one of the successful users and can also confirm I'd be alienated. :-) :-) :-) { Though I could probably also patch around things. }
Not that I think Araq does not know this, but it bears re-mention every time that it's always better to construct something reproducible -- whenever talking about performance (of anything, including compile times). Beyond the "hello world" Araq already mentioned, one can change this little bash program to Nim easily enough: https://forum.nim-lang.org/t/8677#56724 or use some other Nim code generation besides what cligen does. Something simpler might be better and that link should be expanded to include clang, clang -O0/vcc/etc. { And as always, bare metal timing has less unknown stuff going on than weird multi-tenant Cloud stuff. } Any benchmark will only ever be one (or a few) data points.
There may be an argument to be made for the shipped default Nim config to use -O0 for gcc (and similar for clang). People are sensitive enough to edit-compile-test/debug iteration times that it is often a selling point of PLs like Go, D, etc., as well as even REPLs and interpreted environments. They may "try out Nim" before really getting the hang of tweaking a user nim.cfg / config.nims for personal workflows and make a too hasty judgement based on subjective patience levels. We have the "DEBUG BUILD" message now, and I feel (anecdotally) like mistakes from non-optimized builds have gone down since the default became -Og.
IC should help, too.. someday. :)
Someone needs to implement compare-exchange on ARM, which likely needs to map to LL/SC: