-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[libc] Proof of concept of aliasing long double math functions. #132627
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
base: main
Are you sure you want to change the base?
Changes from 7 commits
d53238e
1243671
ed922b7
8e1abc1
268dd92
f4d2856
0d04f79
e2b6c90
0be1f70
95f920a
08627d4
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 |
|---|---|---|
|
|
@@ -37,21 +37,44 @@ | |
|
|
||
| #define LLVM_LIBC_ATTR(name) EXPAND_THEN_SECOND(LLVM_LIBC_FUNCTION_ATTR_##name) | ||
|
|
||
| // MacOS needs to be excluded because it does not support aliasing. | ||
| #if defined(LIBC_COPT_PUBLIC_PACKAGING) && (!defined(__APPLE__)) | ||
| #define LLVM_LIBC_FUNCTION_IMPL(type, name, arglist) \ | ||
| // MacOS needs to be excluded because it does not support [[gnu::aliasing]]. | ||
| #ifndef __APPLE__ | ||
|
|
||
| #if defined(LIBC_COPT_PUBLIC_PACKAGING) | ||
| #define LLVM_LIBC_FUNCTION(type, name, arglist) \ | ||
| LLVM_LIBC_ATTR(name) \ | ||
| LLVM_LIBC_FUNCTION_ATTR decltype(LIBC_NAMESPACE::name) \ | ||
| __##name##_impl__ __asm__(#name); \ | ||
| __##name##_impl__ asm(#name); \ | ||
| decltype(LIBC_NAMESPACE::name) name [[gnu::alias(#name)]]; \ | ||
| type __##name##_impl__ arglist | ||
| #else | ||
| #define LLVM_LIBC_FUNCTION_IMPL(type, name, arglist) type name arglist | ||
| #endif | ||
|
|
||
| // This extra layer of macro allows `name` to be a macro to rename a function. | ||
| #define LLVM_LIBC_ALIASING_FUNCTION(name, func) \ | ||
| decltype(LIBC_NAMESPACE::name) LIBC_NAMESPACE::name [[gnu::alias(#func)]]; \ | ||
| asm(#name " = " #func); \ | ||
|
||
| static_assert(true, "Require semicolon") | ||
|
Member
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 find it a bit unusual for the top-level macros to require semicolon at the end, and it's not common in other libc implementations, see for example: https://sourceware.org/git/?p=glibc.git;a=blob;f=string/basename.c;h=dd2c8182dbc5df71b89100aab33ae98ff4e176ff;hb=HEAD#l28. So my preference would be to avoid requiring semicolons at the end of
Contributor
Author
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 found that forcing the semicolons at the end of these top level macros plays much nicer with clang-format, especially when they are inside
Contributor
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 don't have a strong opinion one way or another, but if we want to commit to this, we should add it to the docs and file an issue for fixing the other macros. |
||
| #else | ||
| #define LLVM_LIBC_FUNCTION(type, name, arglist) \ | ||
| LLVM_LIBC_FUNCTION_IMPL(type, name, arglist) | ||
| LLVM_LIBC_ATTR(name) \ | ||
| LLVM_LIBC_FUNCTION_ATTR decltype(LIBC_NAMESPACE::name) \ | ||
| __##name##_impl__ asm("__" #name "_impl__"); \ | ||
| decltype(LIBC_NAMESPACE::name) name [[gnu::alias("__" #name "_impl__")]]; \ | ||
| type __##name##_impl__ arglist | ||
|
|
||
| #define LLVM_LIBC_ALIASING_FUNCTION(name, func) \ | ||
| decltype(LIBC_NAMESPACE::name) LIBC_NAMESPACE::name \ | ||
| [[gnu::alias("__" #func "_impl__")]]; \ | ||
| asm(#name " = __" #func "_impl__"); \ | ||
|
||
| static_assert(true, "Require semicolon") | ||
| #endif // LIBC_COPT_PUBLIC_PACKAGING | ||
|
|
||
| #else | ||
|
|
||
| #define LLVM_LIBC_FUNCTION(type, name, arglist) type name arglist | ||
|
|
||
| #define LLVM_LIBC_ALIASING_FUNCTION(name, func) \ | ||
| static_assert(true, "Require semicolon") | ||
|
|
||
| #endif // !__APPLE__ | ||
|
|
||
| namespace LIBC_NAMESPACE_DECL { | ||
| namespace internal { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,24 +7,30 @@ function(add_math_entrypoint_object name) | |
| # We prefer machine specific implementation if available. Hence we check | ||
| # that first and return early if we are able to add an alias target for the | ||
| # machine specific implementation. | ||
| get_fq_target_name("${LIBC_TARGET_ARCHITECTURE}.${name}" fq_machine_specific_target_name) | ||
| if(NOT ARGN) | ||
| set(alias_entrypoint ${name}) | ||
| else() | ||
| set(alias_entrypoint ${ARGN}) | ||
| endif() | ||
|
|
||
| get_fq_target_name("${LIBC_TARGET_ARCHITECTURE}.${alias_entrypoint}" fq_machine_specific_target_name) | ||
| if(TARGET ${fq_machine_specific_target_name}) | ||
| add_entrypoint_object( | ||
| ${name} | ||
| ALIAS | ||
| DEPENDS | ||
| .${LIBC_TARGET_ARCHITECTURE}.${name} | ||
| .${LIBC_TARGET_ARCHITECTURE}.${alias_entrypoint} | ||
| ) | ||
| return() | ||
| endif() | ||
|
|
||
| get_fq_target_name("generic.${name}" fq_generic_target_name) | ||
| get_fq_target_name("generic.${alias_entrypoint}" fq_generic_target_name) | ||
| if(TARGET ${fq_generic_target_name}) | ||
| add_entrypoint_object( | ||
| ${name} | ||
| ALIAS | ||
| DEPENDS | ||
| .generic.${name} | ||
| .generic.${alias_entrypoint} | ||
| ) | ||
| return() | ||
| endif() | ||
|
|
@@ -40,6 +46,20 @@ function(add_math_entrypoint_object name) | |
| ) | ||
| endfunction() | ||
|
|
||
| function(add_long_double_math_entrypoint_object name) | ||
| get_fq_target_name(${name} fq_double_math_target) | ||
| get_fq_target_name("${name}l" fq_long_double_math_target) | ||
| get_fq_target_name("${name}f128" fq_float128_math_target) | ||
|
|
||
| if(LIBC_TARGET_LONG_DOUBLE_IS_DOUBLE) | ||
| add_math_entrypoint_object("${name}l" "${name}") | ||
| elseif(LIBC_TARGET_LONG_DOUBLE_IS_FLOAT128) | ||
| add_math_entrypoint_object("${name}l" "${name}f128") | ||
| else() | ||
| add_math_entrypoint_object("${name}l") | ||
| endif() | ||
| endfunction() | ||
|
|
||
| add_math_entrypoint_object(acos) | ||
| add_math_entrypoint_object(acosf) | ||
| add_math_entrypoint_object(acosf16) | ||
|
|
@@ -88,9 +108,9 @@ add_math_entrypoint_object(ceilf128) | |
|
|
||
| add_math_entrypoint_object(copysign) | ||
| add_math_entrypoint_object(copysignf) | ||
| add_math_entrypoint_object(copysignl) | ||
| add_math_entrypoint_object(copysignf16) | ||
| add_math_entrypoint_object(copysignf128) | ||
| add_long_double_math_entrypoint_object(copysign) | ||
|
Contributor
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. Why is this even necessary? We should just be able to enable this entrypoint like anything else and then just let the preprocessor figure out whether or not it should be an alias.
Contributor
Author
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. it wouldn't be a problem for the libc target but it will be a problem for tests. Because our tests for
Contributor
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. But they're still independent targets, right? It's just that one is a single alias rather than an implementation.
Contributor
Author
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. My plan in the future is to add all the variations:
Contributor
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 the main difficulty is that the alias attribute wants the function to be defined.
Contributor
Author
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. So to answer to your question about the cmake changes: we could leave the cmake inplace, and make |
||
|
|
||
| add_math_entrypoint_object(cos) | ||
| add_math_entrypoint_object(cosf) | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.