Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
This patch immitates avr-gcc behavior on __flash
- __flash variables are put into .section .progmem.data
- __flash non-const variables are rejected.
I am not very familiar with Clang so I can't say much about it. Although I wonder whether a macro is the right way to implement this? Is there something similar in other targets? (GPUs tend to have lots of address spaces, you could take a look there).
clang/test/CodeGen/address-space-avr.c | ||
---|---|---|
2–5 | This comment is now out of date. |
A macro definition is the simplest way, an alias to __attribute__((address_space(0))). I do not find any other easy way for a plain keyword __flash.
Ok, macro could be a reasonable direction. This is how clang implements address spaces for CUDA. Another option is adding a keyword. OpenCL implements address spaces this way. You can't add a target-specific keyword but considering that it start with "__" it should be reasonable to add this to C/C++ mode. You could for example align with gcc implementation.
I am guessing this will only be supported by 1 target in clang? Then target address spaces make sense otherwise you can also extend the language address space enum. Are you also planning to add __flashN?
https://gcc.gnu.org/onlinedocs/gcc/Named-Address-Spaces.html
clang/include/clang/Basic/DiagnosticSemaKinds.td | ||
---|---|---|
2995 ↗ | (On Diff #327361) | Minor wording change: qualifier '%select{const|volatile}0' is %select{needed|invalid}1 Could you not use the same parameter in select twice i.e. qualifier '%select{const|volatile}0' is %select{needed|invalid}0 ? |
I am guessing this will only be supported by 1 target in clang? Then target address spaces make sense otherwise you can also extend the language address space enum. Are you also planning to add __flashN?
https://gcc.gnu.org/onlinedocs/gcc/Named-Address-Spaces.html
Yes. I will add __flashN in another patch.
Btw is any pointer conversion between address space 1 and the default address space allowed? I.e. is the following code valid:
__flash static const int var1[] = {111, 222, 333}; void foo(int*); .... foo(var1);
or
__flash static const int var1[] = {111, 222, 333}; void foo(int*); .... foo((int*)var1);
?
clang/include/clang/Basic/DiagnosticSemaKinds.td | ||
---|---|---|
2996 ↗ | (On Diff #333659) | FYI I guess you don't need 3 parameters any more so it should be: "for variables in address space '%1'">; |
clang/lib/CodeGen/TargetInfo.cpp | ||
8120 | ok, now you should only need: << 0 << "__flash"; | |
clang/test/CodeGen/avr-flash.c | ||
2 | If you are only checking the diagnostics you should pass: -emit-llvm-only -> -syntax-only and also it should be moved to clang/test/Sema. | |
5 | Let's also test the volatile case. |
clang/test/CodeGen/avr-flash.c | ||
---|---|---|
2 | This test can not run with -syntax-only. Since the check is performed in the codegen stage. I would like to do the check in the Sema stage, but there is no target specific code in the sema stage. And such checks are better to be put into AVRTargetCodeGenInfo. |
No. clang denied with error: passing 'const __attribute__((address_space(1))) int *' to parameter of type 'const int *' changes address space of pointer while avr-gcc accepted it.
It seems I need more efforts to make clang-avr fully compatible with avr-gcc.
Ok, it makes sense for clang to align with gcc in general but do you know whether or where this conversions are described? By default if not specified explicitly implicit conversions are always disallowed in ISO/IEC DTR 18037 and explicit casts are always allowed but can yeild undefined behavior if address spaces don't overlap.
clang/include/clang/Basic/DiagnosticFrontendKinds.td | ||
---|---|---|
162 | Ok, do you plan to pass anything other than __flash here? If not then you don't need to pass an argument in this diagnostic. | |
clang/test/CodeGen/avr-flash.c | ||
2 |
Sema has target hooks and access to the target specific address spaces so you could indeed move them to Sema. Normally we do diagnostics as early as possible but there is no strict rule and there are some tradeoffs. So, you can also keep it here to allow better code incapsulation and simplify maintenance. If you need to implement the pointer conversion logic you might move this completely to Sema. Btw just to highlight the following change https://reviews.llvm.org/D62574 that generalizes some logic that might be useful for your pointer conversions. | |
6 | Is there anything you are testing with these array subscript expressions? If not I suggest removing them and only keep what is needed for testing the new functionality. |
I do not think clang needs to fully follow avr-gcc's way. Since avr-gcc generates wrong assembly that c code.
__flash static const int var1[] = {111, 222, 333}; void foo(int*); .... foo(var1);
LDD (which is used access data space) is generated in th function foo, while LPM is needed for accessing var1 (in the program space).
avr-gcc silently accepts the c code with any warning and generates wrong assembly. And I think clang should rise an error .
Ok, do you plan to pass anything other than __flash here? If not then you don't need to pass an argument in this diagnostic.