On 16/03/17 22:33, Dylan McKay wrote: > Maintainer of the LLVM backend here. > >> gcc expects its targets to have registers capable of holding >> an int - in this case, 16 bits. So the AVR port of gcc has to work with >> register pairs r0:r1, r2:r3, r4:r5, etc., and then the backend peephole >> passes try to remove redundant operations. > > That's interesting - LLVM doesn't have this specific problem. > > One problem the backend _does_ have is that LLVM assumes that the size > of your largest register makes up the standard register size. This means > that LLVM sees the X,Y,Z pointer registers, assumes 16-bit operations > are generally supported, and then doesn't decide to split many 16-bit > operations into 8-bit ones. To work around this, we define sets of > 16-bit pseudo instructions and then have a custom pass to lower the IR > into assembly, often producing suboptimal code.
That sounds like a similar problem - or at least, a problem with similar effects. I haven't actually studied the AVR port of gcc (I haven't dug into the details of gcc in general), but know a bit about it from using it for many years, following the lists, discussions on "missed optimisation" bug reports, and so on. It is entirely possible that my description of avr gcc's challenge is not quite right, and that it is more similar to llvm's. avr gcc has collected a fair number of peephole optimisations to improve the quality of the output, and does quite a good job of it these days - but you still see occasional code where calculations are done with 16-bit register pairs even though the top half will be thrown away. But remember, although it is good to aim for the best possible code, in most cases "good enough is good enough". The beauty of tools like gcc and llvm for the avr is not in getting "perfect" code - it is in the fantastic range of features of these two tools, compared to any alternatives in the market. And while it is challenging to get the low-level optimisations as good as possible, these compilers have lots of high-level optimisations that you get "for free". > > This problem could be fixed, but it requires some changes to LLVM which > are quite large. I can appreciate that. Like gcc, llvm supports a range of targets but has to make certain assumptions about them in order to avoid being overly complex. For example, I believe gcc requires CHAR_BIT to be 8, which makes many things a lot easier but excludes its use for some DSP devices and "dinosaur" processors. I assume llvm has similar restrictions. > > Regarding the state of the backend, GCC should definitely be preferred. > Now that LLVM 4.0 has been tagged, we're working on enabling that AVR > backend in Rust. There will likely be a few assertion errors and latent > bugs being hit. I have not tried Rust as yet, but I think it is marvellous to see a choice here. C is basically a static language - it is something we know, it is well enough defined and small enough that it offers few surprises (once you understand the details), and it has /stability/. That stability is a strength and a curse - C does not change (much) with time. When we want a language for embedded programming that gains new features and possibilities, that is currently C++. Rust offers some features and benefits over C++ - while C++ can do things that Rust cannot. I look forward to Rust maturing and these two languages being inspired by each other - they will always be different, but both gain from competition in a similar market. Kind of like gcc and llvm :-) _______________________________________________ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org https://lists.nongnu.org/mailman/listinfo/avr-gcc-list