-
Notifications
You must be signed in to change notification settings - Fork 54
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove request for preprocessor guards from header files. #321
Changes from 8 commits
fc50eb1
994aec6
1270932
6e3991a
9079875
ae42458
92e5b8c
fb4b4f8
15bd063
4fafea9
50f5670
9d357be
cd750bf
7b3ee34
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -925,8 +925,8 @@ and: | |
to the more specific header files below. These intrinsics are in the | ||
C implementation namespace and begin with double underscores. It is | ||
unspecified whether they are available without the header being | ||
included. The `__ARM_ACLE` macro should be tested before including the | ||
header: | ||
included. The `__ARM_ACLE` macro can be tested before including the | ||
header, but this might limit function multi-versioning capabilities: | ||
|
||
``` c | ||
#ifdef __ARM_ACLE | ||
|
@@ -939,8 +939,9 @@ header: | |
`<arm_fp16.h>` is provided to define the scalar 16-bit floating point | ||
arithmetic intrinsics. As these intrinsics are in the user namespace, | ||
an implementation would not normally define them until the header is | ||
included. The `__ARM_FEATURE_FP16_SCALAR_ARITHMETIC` feature macro | ||
should be tested before including the header: | ||
included. The `__ARM_FEATURE_FP16_SCALAR_ARITHMETIC` macro can be | ||
tested before including the header, but this might limit function | ||
multi-versioning capabilities: | ||
|
||
``` c | ||
#ifdef __ARM_FEATURE_FP16_SCALAR_ARITHMETIC | ||
|
@@ -953,8 +954,8 @@ should be tested before including the header: | |
`<arm_bf16.h>` is provided to define the 16-bit brain floating point | ||
arithmetic intrinsics. As these intrinsics are in the user namespace, | ||
an implementation would not normally define them until the header is | ||
included. The `__ARM_FEATURE_BF16` feature macro | ||
should be tested before including the header: | ||
included. The `__ARM_FEATURE_BF16` macro can be tested before including | ||
the header, but this might limit function multi-versioning capabilities: | ||
|
||
``` c | ||
#ifdef __ARM_FEATURE_BF16 | ||
|
@@ -975,8 +976,9 @@ instructions available are conversion intrinsics between `bfloat16_t` and | |
intrinsics](#advanced-simd-neon-intrinsics) and associated | ||
[data types](#vector-data-types). As these intrinsics and data types are | ||
in the user namespace, an implementation would not normally define them | ||
until the header is included. The `__ARM_NEON` macro should be tested | ||
before including the header: | ||
until the header is included. The `__ARM_NEON` macro can be tested before | ||
including the header, but this might limit function multi-versioning | ||
capabilities: | ||
|
||
``` c | ||
#ifdef __ARM_NEON | ||
|
@@ -999,8 +1001,8 @@ following it. --><span id="arm_sve.h"></span> | |
`<arm_sve.h>` defines data types and intrinsics for SVE and its | ||
extensions; see [SVE language extensions and | ||
intrinsics](#sve-language-extensions-and-intrinsics) for details. | ||
You should test the `__ARM_FEATURE_SVE` macro before including the | ||
header: | ||
The `__ARM_FEATURE_SVE` macro can be tested before including the header, | ||
but this might limit function multi-versioning capabilities: | ||
|
||
``` c | ||
#ifdef __ARM_FEATURE_SVE | ||
|
@@ -1019,7 +1021,7 @@ Including `<arm_sve.h>` also includes the following header files: | |
|
||
`<arm_neon_sve_bridge.h>` defines intrinsics for moving data between | ||
Neon and SVE vector types; see [NEON-SVE Bridge](#neon-sve-bridge) | ||
for details. The `__ARM_NEON_SVE_BRIDGE` macro should be tested | ||
for details. The `__ARM_NEON_SVE_BRIDGE` macro should be tested | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: unnecessary change. |
||
before including the header: | ||
|
||
``` c | ||
|
@@ -1061,8 +1063,8 @@ change or be extended in the future. | |
|
||
`<arm_sme.h>` declares functions and defines intrinsics for SME | ||
and its extensions; see [SME language extensions and intrinsics](#sme-language-extensions-and-intrinsics) | ||
for details. The `__ARM_FEATURE_SME` macro should be tested before | ||
including the header: | ||
for details. The `__ARM_FEATURE_SME` macro can be tested before including the | ||
header, but this might limit function multi-versioning capabilities: | ||
|
||
``` c | ||
#ifdef __ARM_FEATURE_SME | ||
|
@@ -1072,6 +1074,32 @@ including the header: | |
|
||
Including `<arm_sme.h>` also includes [`<arm_sve.h>`](#arm_sve.h). | ||
|
||
### Predefined Macros and Headers | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should this be changed to : "### predefined feature macros and header files" ? |
||
|
||
CarolineConcatto marked this conversation as resolved.
Show resolved
Hide resolved
|
||
The macros can represent a compiler's ability to use the instructions | ||
associated with the feature via ACLE documented intrinsics and within inline | ||
assembly. However users should not rely solely on macro definition, because | ||
there are intrinsics that may be influenced by mechanisms like `#pragma` or | ||
`attribute`. The macros are defined only for user convenience. | ||
|
||
CarolineConcatto marked this conversation as resolved.
Show resolved
Hide resolved
|
||
For example: | ||
|
||
``` c | ||
#ifdef __ARM_FEATURE_SME | ||
#include<arm_sme.h> | ||
void foo(svbool_t pg, void *ptr, uint32_t slice_base) { | ||
svst1_hor_za8(0, slice_base, pg, ptr); | ||
} | ||
#endif | ||
``` | ||
|
||
`foo` uses `__ARM_FEATURE_SME` to have available SME intriniscs, | ||
like `svst1_hor_za8`. However it has the compilation error: | ||
`builtin can only be called from a streaming function` | ||
for the command line: | ||
`armclang -O3 -target aarch64-linux-gnu -march=armv8-a+sme` | ||
that defines `__ARM_FEATURE_SME` to one. | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about? Testing a feature macro returns the compiler's support for the feature via ACLE documented intrinsics and inline assembly. This property can be independent of where the test is performed, meaning a feature macro does not guarantee the validity of using the feature at the point it is tested. For example: #include <arm_sme.h>
void foo(svbool_t pg, void *ptr, uint32_t slice_base) {
#ifdef __ARM_FEATURE_SME
svst1_hor_za8(0, slice_base, pg, ptr);
#endif
} Whilst testing `__ARM_FEATURE_SME` ensures the compiler supports the SME intrinsic `svst1_hor_za8`, `foo` will fail to compile because it has not been decorated with the necessary keywords to guarantee the function will be executed in streaming mode. Not all such issues can be caught during compilation and may instead result in runtime failures. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Not sure if it is just me, the key is how we define "support". "Testing a feature macro allows to check if the compiler can make use of the architecture feature via ACLE documented intrinsics and inline assembly assuming the provided compilation flags." What do you think? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This distinction is not relevant because there is no assumption about compilation flags. The macro alone is sufficient to detect at the source level whether the compiler (in the mode it's in when compiling the input) can support a specific feature. By support we effectively mean "is able to compile the input when it is correctly formed". The provided example shows something that is not "correctly formed" where the compiler will report an error that must be fixed before the code will compile. There are many other examples but I don't see a reason to document them all here. Note I say "compile" and not "compile to a working binary" because the more typical result is the compiler correctly building the input which then generates a SIGILL when executed. This is covered by the "Not all such issues..." sentence. Personally I don't think it's worth going into anymore detail than this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure, I get the difference between "compile" and not "compile to a working binary". For me it was just the meaning of word support, as in my mind feature could be supported (as implemented) by a tool but not available when given set of options it provided. It has this small difference from the user point of view as if feature is not implemented they can not do anything, while if it is not enabled they can change options. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that's because you are considering this from the point of view of a human asking whether the compiler can support a feature. Whereas the feature macros are source code actions and thus the context is the point the source code is being compiled, at which point the compiler has already been "configured" (for want of a better word) by the user. Perhaps the point you are raising is the document does not detail what actions the user should take in order to control the definitions of the feature flags, which is intentional because we cannot dictate that. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree it would be good to be a bit more precise about what “support” means though. At one level, GCC 14 “supports” SME2, and the word is often used in that sense. So if we just say “support”, users might expect GCC 14 to define Instead, for compatibility, we have to define the macro only if the intrinsics are “available” in functions that have no target annotations (not precise wording either). What users need to do to achieve that for a given compiler is outside the scope of the ACLE, but I think the result is within scope. IMO, the example of using SME intrinsics in non-streaming functions is an example of an intrinsics being available, but being used incorrectly. It's somewhat like passing an out-of-range value to a constant argument, except that the error is contextual, rather than contained within the call. (I still think it's a good example though.) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I did changed to what @paulwalker-arm requested, but instead of using support I wrote available, as suggested by @rsandifo-arm. |
||
## Attributes | ||
|
||
GCC-style attributes are provided to annotate types, objects and | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ignore me if this format has already been agreed but if not can I recommend:
The `XYZ` macro can be tested before including the header. However, this is not recommended for cases where target feature selection is overridden within code, for example, when using #function-multi-versioning.