question about possible new extensions (mainly pragmas) in clang for new LLVM backend for Renesas RL78 MCU

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

question about possible new extensions (mainly pragmas) in clang for new LLVM backend for Renesas RL78 MCU

Fangrui Song via cfe-dev
Hello all,

I just made an announcement on the llvm-dev list about a new LLVM backend for the Renesas RL78 MCU which I'm writing:
http://lists.llvm.org/pipermail/llvm-dev/2020-April/140546.html

Because I aim to replace GCC with LLVM, I already implemented the GCC RL78 attributes (__attribute__) and builtin functions (__builtin_rl78_*) and I don't have any real concern about getting those attributes and builtins accepted upstream however I recently received a new request:
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.
However I am little bit concerned with those extension as they are a little bit unusual compared to what I see in clang.

A few years ago I implemented one of them in GCC (#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 which I something that I want to avoid with clang/llvm I don't want to do something that would not be accepted upstream.

My question here will be: are the following CCRL extensions acceptable to be implemented in clang? 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
_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: question about possible new extensions (mainly pragmas) in clang for new LLVM backend for Renesas RL78 MCU

Fangrui Song via cfe-dev
Hi Sebastian,

On Wed, Apr 1, 2020 at 8:45 PM Sebastian Perta via cfe-dev <[hidden email]> wrote:
My question here will be: are the following CCRL extensions acceptable to be implemented in clang? 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.

It would require a little infrastructure work, but I think it would be quite doable. Generally, for your pragmas it seems like you might need to extend support for attaching pragmas as attributes to functions. Please take a look at how '#pragma omp declare' (for example, '#pragma omp declare simd', '#pragma omp declare variant') are implemented.

*Assuming* that LLVM would be accepting the backend, and as long as you scope the processing of these proprietary pragmas to your target and your target only, I think there should be no issue.

However, given the advantages of standard attributes and general practice in writing modern C and C++, it would be a lot better if we could avoid proprietary pragmas, or at least have a plan towards removing them in future.

Upgrading the compiler would not be completely transparent for your customers anyway, some manual adjustments to the source code would be necessary (for example, to get rid of other proprietary extensions and reliance on implementation-defined behaviors, recover performance, fix bugs uncovered by the new compiler etc.) I recommend that you provide a source-to-source translation tool that translates the pragmas to attributes, as well as translating the unusual assembly syntax into the more widely accepted GCC asm extension. If the your current toolchain supports that spelling, the customers could even run the tool, translate the code to use a more widely accepted syntax, validate the changes using the old toolchain (should be a no-op), and then migrate to Clang.

Implementing the inline assembler extension would be more difficult than pragmas. Clang already supports MSVC's inline assembler (see clang/test/CodeGen/ms-inline-asm-64.c, for example), but implementing it was a major endeavor. It created non-trivial maintenance burden, because the MSVC inline assembler allowed to incorporate some C and C++ expressions and declaration references directly into the assembly commands. If your dialect does not have such power, it might be easier to support, but again, my best suggestion is to consider asking users to run a source-to-source translation to the GCC inline asm extension, or the MSVC inline asm since it is already supported in Clang and not going away.

Developing a source-to-source translation tool would be beneficial not just for eliminating these pragmas and unusual inline asm, but also for eliminating many other small incompatibilities between your proprietary toolchain and Clang that you will undoubtedly find. While implementing pragmas in Clang is realistic and practical, implementing bug-for-bug compatibility for other issues is not, and customers would have to change the code in order to upgrade the toolchain. While they do that, they could as well run a source-to-source translation tool to eliminate pragmas and unusual inline asm -- if the translation tool is reliable, those additional edits would be trivial to review, compared to the effort needed to find and eliminate other incompatibilities and newly found bugs.

Dmitri

--
main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if
(j){printf("%d\n",i);}}} /*Dmitri Gribenko <[hidden email]>*/

_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: question about possible new extensions (mainly pragmas) in clang for new LLVM backend for Renesas RL78 MCU

Fangrui Song via cfe-dev

Hi Dmitri,

 

>>*Assuming* that LLVM would be accepting the backend, and as long as you scope the processing of these proprietary pragmas to your target and your target only, I think there should be no issue.

Thank you very much!

 

>>I recommend that you provide a source-to-source translation tool

I already did this for Renesas RX (proprietary compiler -> GCC RX) many years ago.

Fortunately the two proprietary compilers (for RX and RL78) share roughly the same pragmas/extensions so I can reuse it.

The tool is based on RecursiveASTVisitor (and clang 3.3).

 

Best Regards,

Sebastian

 

From: Dmitri Gribenko <[hidden email]>
Sent: 08 April 2020 09:38
To: Sebastian Perta <[hidden email]>
Cc: [hidden email]
Subject: Re: [cfe-dev] question about possible new extensions (mainly pragmas) in clang for new LLVM backend for Renesas RL78 MCU

 

Hi Sebastian,

 

On Wed, Apr 1, 2020 at 8:45 PM Sebastian Perta via cfe-dev <[hidden email]> wrote:

My question here will be: are the following CCRL extensions acceptable to be implemented in clang? 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.

 

It would require a little infrastructure work, but I think it would be quite doable. Generally, for your pragmas it seems like you might need to extend support for attaching pragmas as attributes to functions. Please take a look at how '#pragma omp declare' (for example, '#pragma omp declare simd', '#pragma omp declare variant') are implemented.

 

*Assuming* that LLVM would be accepting the backend, and as long as you scope the processing of these proprietary pragmas to your target and your target only, I think there should be no issue.

 

However, given the advantages of standard attributes and general practice in writing modern C and C++, it would be a lot better if we could avoid proprietary pragmas, or at least have a plan towards removing them in future.

 

Upgrading the compiler would not be completely transparent for your customers anyway, some manual adjustments to the source code would be necessary (for example, to get rid of other proprietary extensions and reliance on implementation-defined behaviors, recover performance, fix bugs uncovered by the new compiler etc.) I recommend that you provide a source-to-source translation tool that translates the pragmas to attributes, as well as translating the unusual assembly syntax into the more widely accepted GCC asm extension. If the your current toolchain supports that spelling, the customers could even run the tool, translate the code to use a more widely accepted syntax, validate the changes using the old toolchain (should be a no-op), and then migrate to Clang.

 

Implementing the inline assembler extension would be more difficult than pragmas. Clang already supports MSVC's inline assembler (see clang/test/CodeGen/ms-inline-asm-64.c, for example), but implementing it was a major endeavor. It created non-trivial maintenance burden, because the MSVC inline assembler allowed to incorporate some C and C++ expressions and declaration references directly into the assembly commands. If your dialect does not have such power, it might be easier to support, but again, my best suggestion is to consider asking users to run a source-to-source translation to the GCC inline asm extension, or the MSVC inline asm since it is already supported in Clang and not going away.

 

Developing a source-to-source translation tool would be beneficial not just for eliminating these pragmas and unusual inline asm, but also for eliminating many other small incompatibilities between your proprietary toolchain and Clang that you will undoubtedly find. While implementing pragmas in Clang is realistic and practical, implementing bug-for-bug compatibility for other issues is not, and customers would have to change the code in order to upgrade the toolchain. While they do that, they could as well run a source-to-source translation tool to eliminate pragmas and unusual inline asm -- if the translation tool is reliable, those additional edits would be trivial to review, compared to the effort needed to find and eliminate other incompatibilities and newly found bugs.

 

Dmitri

 

--

main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if
(j){printf("%d\n",i);}}} /*Dmitri Gribenko <[hidden email]>*/



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


_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev