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

Sebastian Perta via llvm-dev
Tue, 26 May 2020 17:28:33 -0000

Hi David,

Thank for very much for your reply!

I got a reply on the clang mailing list in April from Dmitri:
http://lists.llvm.org/pipermail/cfe-dev/2020-April/065115.html
and following his advice “attaching pragmas as attributes to functions” I
managed to do it, it was actually quite easy.

>>Compatibility with an existing compiler is usually compelling - are the
compilers you're trying to be compatible with publicly available/documented?
Yes the compiler can be downloaded from here (is available for free with some
restrictions compared to the paid version).
https://www.renesas.com/in/en/products/software-tools/tools/compiler-assembler/compiler-package-for-rl78-family.html
The documentation is available as well (in toolchain installer and website):
https://www.renesas.com/in/en/doc/products/tool/doc/015/r20ut3123ej0109-ccrl.pdf

>>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.
Sure, no problem!
About me: https://ro.linkedin.com/in/sebastian-perta-46a4383b
Currently I have no intentions of stop being involved in this for a very long
time. The only way this can happen is if I decide to leave Renesas in which case
I’m sure the company will be interested to find a replacement.
About the users: those are embedded engineers in automotive, IOT, domestic
appliances, etc.
Anything else you would like to know?

Best Regards,
Sebastian

From: David Blaikie <dblaikie at gmail.com>
Sent: 26 May 2020 17:46
To: Sebastian Perta <Sebastian.Perta at renesas.com>; Aaron Ballman
<aaron at aaronballman.com>; Richard Smith <richard at
metafoo.co.uk>
Cc: llvm-dev at lists.llvm.org
Subject: Re: [llvm-dev] New LLVM backend for Renesas RL78 MCU

+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.
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<mailto: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<mailto:llvm-dev at lists.llvm.org>
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev



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
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20200526/f8be8fee/attachment-0001.html>