[llvm-dev] Status of the AVR backend 2019/LLVM 7.0

Dylan McKay via llvm-dev llvm-dev at lists.llvm.org
Sun Jan 13 23:17:17 PST 2019

Hello all,

It is a near year and a new LLVM release; 7.0. It has been a while since
the last AVR update email, the backend has become much better at handling
complex programs.

To that end, this is the first LLVM release than can successfully compile
all of upstream Rust’s main compiler support library libcore without error.
This was the main blocker in merging the avr-rust
<https://github.com/avr-rust/rust> fork upstream.

There have a few been more backend contributors this year, mostly coming
from the avr-rust project.

The vast majority of the changes this last year have been related to
compilation bugfixes. We have been focusing on improving Rust support,
which exposed a number of compilation bugs and C-only assumptions that have
now been fixed. The amount of IR correctly accepted by the AVR backend has
noticeably increased, including implementation of atomics and things not
seen in C such as structs with zero size.
Frontends supporting AVR

   - clang
   - Rust
      - https://github.com/avr-rust/  <https://github.com/avr-rust/>
      - The fork has been updated to Rust master, supporting edition 2018
   - Swift
   -   http://swiftforarduino.com/
   - Go
   -   https://github.com/aykevl/tinygo


Support for functions in nonzero address spaces has landed upstream

Address space 0 is always RAM, address space 1 is always program/flash
In the past, functions could only be in address space 0, and thus the
entire LLVM middlend acted on the unfound assumption that every functon
pointer is in RAM… but it still mostly worked
Although a function pointer memory address would inherently load from
address space 0 - RAM, but with a memory offset into flash memory!

Now functions can be tagged with address spaces even at the textual IR level

A bunch of uninteresting compilation assertion error fixes. Almost all of
the changes fall into this category

A few test suite fixes - thanks to several driveby contributors, it’s

i128 divisions are now supported via libgcc calls
Test suite stability

The AVR backend and it’s test suite status has been decidedly more stable
over the last year. In most backend-breaking LLVM changes, the AVR backend
is updated at the same time as all the non-experimental backends.

The backend is still marked as experimental, which means that no emails are
sent out upon test failure. The AVR buildbot can be found on the staging
buildmaster at http://lab.llvm.org:8014/builders/llvm-avr-linux.

My main priority is integration testing, which needs some work. I’ve got a
project that integration tests the backend here
<https://github.com/dylanmckay/avr-compiler-integration-tests>, but it
cannot actually test LLVM trunk yet until D54334
<https://reviews.llvm.org/D54334> ([AVR] Automatically link CRT and libgcc
from the system avr-gcc) lands in clang, currently pending code review. The
simavr <https://fabricesalvaire.github.io/simavr/doxygen/index.html>
emulator has been very helpful here.
Backend implementation/maintenance pain points

The major pain points of an embedded processor backend with relatively
exotic properties are mostly the same as they were a few years ago. This
includes the greedy register allocator, which can sometimes struggle with
the extremely constrains sometimes imposed by AVR.

Another pain point is the DAG type legalizer, which currently assumes that
arithmetic and logic operations only need to be split down into the
smallest legal integer type. The implicit assumption is that hardware
instructions are defined for every operation on the smallest legal integer
type. The smallest legal integer type on AVR is 16-bit, which may be placed
into 8-bit GPR pairs or 16-bit pointer registers. Only a small portion of
the instruction set is 16-bit, with ADD, MUL, DIV, AND, OR, COM, etc only
being defined on 8-bit general purpose registers. After DAG type
legalization, >=32bit operation nodes are turned into multiple 16-bit
operations, but instruction selection cannot ever match them because on
AVR, most operations need to be split down once more to several 8-bit
operations. The AVR workaround is to create a new pseudo instruction with a
pattern for every 8-bit operation that operates on 16-bits. The
AVRExpandPseudoInsts pass has a couple thousand lines manually expanding
high-level 16-bit operations into hardware 8-bit instructions. A lot of
complex AVR backend code could be deleted if LLVM had a way to split these
operations down to the 8-bit level required.
Next year

As mentioned above, integration testing is a big priority and will help
improve stability of the backend, whilst also increasing confidence in
committing future changes. The end goal is to have a constantly-running
integration tester that tests every change in LLVM against simulated AVR

I intend to write an RFC to LLVM-dev about the promotion of the backend
from experimental to official in the coming weeks.

Special thanks to all of the helpful contributors that wrote patches,
reviewed code, fixed tests, raised issues, discussed problems, and updated
the AVR backend at the same time alongside their LLVM API breaking commits

Happy 2019 everybody,
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190114/a0e68000/attachment.html>

More information about the llvm-dev mailing list