[llvm-dev] New LLVM backend for Renesas RL78 MCU

Aaron Ballman via llvm-dev
Tue, 26 May 2020 18:42:24 -0000

On Tue, May 26, 2020 at 12:46 PM David Blaikie <dblaikie at gmail.com>
wrote:
>
> +Aaron as the attribution expert
> +Richard for general Clang things
>
> I imagine there might be some interest in a pragma that applies an
attribute to a function - I know Apple folks implemented some attribution
framework based on an input file, so attributing-at-a-distance is roughly in the
realms of plausible.

We have several that do this already, so it hopefully won't be too bad
to support for your case. We have #pragma clang attribute itself
(which allows you to apply attributes to batches of declarations), as
well as some OpenMP pragmas that generate function attributes, that
can likely be used as a model.

~Aaron

> Compatibility with an existing compiler is usually compelling - are the
compilers you're trying to be compatible with publicly available/documented?
> The other aspect to new features, targets, etc, is the ongoing support -
might be relevant to know a bit more about you/your users, whether there are
other folks who are likely to maintain this work if you stop being involved at
some point, etc.
>
> On Wed, Apr 1, 2020 at 10:26 AM Sebastian Perta via llvm-dev <llvm-dev
at lists.llvm.org> wrote:
>>
>> Hello all,
>>
>> For the past couple of months I've been writing a new llvm backend
for Renesas RL78 MCU:
>>
https://www.renesas.com/eu/en/products/microcontrollers-microprocessors/rl78.html
>> The software manual which contains all there is to know about RL78 is
available here:
>>
https://www.renesas.com/us/en/doc/products/mpumcu/doc/rl78/r01us0015ej0220_rl78.pdf
>>
>> The motivation behind this is the following:
>> For the past 7 years I've been working on the Renesas RL78 and RX
MCU ports in GCC (originally developed and maintained by Red Hat).
>> In case of RX I have no real issues with GCC as performance is similar
to the RX commercial/proprietary compilers,
>> however in case of RL78 the performance(both code size and speed) of
GCC is very poor it ranges from 20% to 300% worse compared to the RL78
commercial compilers (from Renesas and IAR Systems).
>>
>> I'm still a few months away from upstreaming the port but the port
is currently quite stable and performance is very similar to the
commercial/proprietary compilers (the machine outliner is very effective as RL78
has a very limited instruction set), and there's still a lot of room for
improvement.
>> Also I'm able to keep ABI compatibility with the commercial
compilers and implement features (available in the commercial compilers) which I
wasn't able to do in GCC although I tried really hard for years.
>> So I would like take this opportunity to say thank you to you all for
making LLVM so great and ease to use and extend.
>>
>> Although I'm looking at other targets and follow the guidelines if
there are pointers/suggestions which people would like to share I'm happy to
listen.
>>
>> I would like to show just one short example which was my starting point
and motivation to switch to LLVM:
>> char foo(char a, char b, char c, char d, char e, char f) {
>> return a + b + c + d + e + f;
>> }
>>
>> This is what GCC produces (30 bytes and 18 clock cycles excluding the
ret instruction)
>> _foo:
>> mova, [sp+14]
>> movc, a
>> mova, [sp+12]
>> adda, c
>> movc, a
>> mova, [sp+10]
>> adda, c
>> movc, a
>> mova, [sp+8]
>> adda, c
>> movc, a
>> mova, [sp+6]
>> adda, c
>> movc, a
>> mova, [sp+4]
>> adda, c
>> movr8, a
>> ret
>> While with I can produce the following output code (11 bytes and 5
clock cycles excluding the ret)
>> Notice also the ABI difference (with LLVM I was able to use the same
ABI as the commercial compilers)
>> _foo:
>> add a, x
>> add a, c
>> add a, b
>> add a, e
>> add a, d
>> ret
>>
>> Please note the following comments are more directed at clang and I
apologize if I shouldn't post here at all, I will repost the second part on
cfe-dev list as well, but the first part of the email is about the announcement
of the port and I think it belongs here.
>>
>> Because I aim to replace GCC with LLVM, I already implemented the GCC
RL78 attributes (__attribute__) and builtin functions (__builtin_rl78_*) however
I recently received a request which brings me to the reason why I'm writing
today:
>> I was asked if I can implement the C Language extension from the
Renesas CCRL (Renesas RL78 commercial compiler) in clang in order to close the
gap between the two compilers.
>>
>> In GCC I implemented one of them (#pragma address) but when I pushed it
upstream it wasn't met with too much enthusiasm and it didn't get
accepted. I ended up maintaining it locally among many other things which I
didn't upstream which made updating to new versions of GCC difficult.
>> This is one very important thing which I would like to avoid in LLVM, I
don't want to do something that would not be accepted upstream and end up in
the same situation as I was with GCC.
>>
>> My question here will be: are the following CCRL extensions acceptable
to be implemented in clang? or will I find myself in the same situation as I am
with GCC as they won't be accepted upstream? Especially since for most of
them we already/can have alternative implementations using __attribute__ and
other approaches more in line with clang extensions.
>>
>>
>> First things I would like to explain are the pragmas.
>> Most CCRL pragmas have a trait which is quite unusual: the first
parameter is function or a variable name, for example in order to declare a
interrupt functions while in GCC I do:
>> void inter ( void ) __attribute__((interrupt));
>> In CCRL this is declared the following way:
>> #pragma interrupt inter
>> void inter ( void ) {
>> }
>>
>> I haven't checked the clang source code but I imagine it is not
straight forward to tie a pragma to a particular function declaration as there
are no other such pragmas as far as I'm aware.
>>
>> The complete list of pragmas in question is:
>> #pragma interrupt [(]interrupt-handler-name[(interrupt-specification
[,...])][)]
>> The equivalent of __attribute__((interrupt)) as discussed above.
>> #pragma interrupt_brk
[(]interrupt-handler-name[(interrupt-specification[,...])][)]
>> The equvivalent of __attribute__((brk_interrupt)).
>> #pragma section [ section-type][ new-section-name]
section-type:{text|const|data|bss}
>> #pragma inline [(]function-name [,...][)]
>> #pragma noinline [(]function-name [,...][)]
>> As the name says inline, noinline. We have inline, __inline and
__inline__ keywords and __attribute__ ((always_inline)).
>> #pragma inline_asm [(]function-name [,...][)]
>> This pragma specifies the body of the function is assembly code.
>> I image substantial changes will be required in clang for this.
>> #pragma address [(]variable-name=absolute-address[,...][)]
>> This can be implemented with
__attribute((section("section-name")) and then handling that section
in the linker script accordingly.
>> And a few more pragmas for we could have equivalent __attribute__.
>> #pragma saddr [(]variable-name[,...][)]
>> #pragma near [(] function-name [,...][)]
>> #pragma far [(] function-name [,...][)]
>> #pragma callt [(]function-name[,...][)]
>> #pragma stack_protector
[(]function-name[(num=number)][,function-name[(num=number)]][,...][)]
>> #pragma no_stack_protector [(]function-name[,...][)]
>>
>> Finally there are 2 operators:
>> __sectop("section-name")
>> __secend("section-name")
>> This can be easily done by adding symbols at start and end of output
sections in the linker script and referencing them from C as global pointers.
>>
>>
>> The CCRL manual explaining those extension in detail is available here:
>>
https://www.renesas.com/us/en/doc/products/tool/doc/015/r20ut3123ej0109-ccrl.pdf
>>
>> Best Regards,
>> Sebastian
>>
>>
>>
>>
>> Renesas Electronics Europe GmbH, Geschaeftsfuehrer/President: Carsten
Jauch, Sitz der Gesellschaft/Registered office: Duesseldorf, Arcadiastrasse 10,
40472 Duesseldorf, Germany, Handelsregister/Commercial Register: Duesseldorf,
HRB 3708 USt-IDNr./Tax identification no.: DE 119353406 WEEE-Reg.-Nr./WEEE reg.
no.: DE 14978647
>> _______________________________________________
>> LLVM Developers mailing list
>> llvm-dev at lists.llvm.org
>> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev