\* Fibonacci hashing spreads packed ARGB keys uniformly.
Used so that low bits don't dominate the cache. */
return (NSUInteger) ((key * 11400714819323198485ULL)
& (NS_COLOR_CACHE_SIZE - 1));
This is not how hashing works... Slowdown Zen1: tinycc: 1.34%, chibicc: -0.3% (slight speedup somehow?)
Slowdown X100: tinycc: 0.1%, chibicc: 3.4%
Last time I did full clang: https://news.ycombinator.com/item?id=47328214#47342362
And there was minimal slowdown (sometimes speedup) on x86, Arm and RISC-V. It was pointed out that llvm mostly uses size_t, however chibicc and tinycc use int as their default type, so there should be lots of overflow checking.
For high performance implementations both decoding variable length instructions and decoding/cracking fixed-length instructions into uops, are rather analogous in terms of the work hardware needs to do.
However, I think the advantage of fixed-length instructions, is that you can do further tricks, like pre-decoding in Icache. With RVC, you can also do pre-decoding, but now you need twice the amount of pre-decoding data, unless you find other tricks.
Still, in a reasonable variable-length ISA and fixed-length ISA, the variable-length one will get better code size. There are also a lot of other things to consider, RVC is self synchronizing, cracking is challenging for decode, but also keeps the backend better fed, how more instruction starts impact branch predictors, instructions crossing cache-lines...
I benchmark compiling programs with a rva23 clang build and clang compiled for rva23-without-C and got a 10% performance improvement from RVC on the SpacemiT X100. The X100 is a 4-wide out-of-order core and afaik doesn't do anything special for RVC, except for expanding the 16-bit to 32-bit instructions.
It's hard to quantify the real impact on a CPU design, but going the fixed-width route seems to enable more optimizations (not so much the decoding it self).