diff options
author | Qing Zhao <qing.zhao@oracle.com> | 2024-10-15 17:55:22 +0000 |
---|---|---|
committer | Qing Zhao <qing.zhao@oracle.com> | 2024-10-15 19:55:54 +0000 |
commit | e7380688fa5917011c3fb85b5e06fb00f776a95d (patch) | |
tree | 7c12cb6c211b051e63f7d260ba9f9da1e968cbc6 /libcpp/files.cc | |
parent | 50f27896adb272b40ab03a56fd192e74789bef97 (diff) | |
download | gcc-e7380688fa5917011c3fb85b5e06fb00f776a95d.zip gcc-e7380688fa5917011c3fb85b5e06fb00f776a95d.tar.gz gcc-e7380688fa5917011c3fb85b5e06fb00f776a95d.tar.bz2 |
Provide new GCC builtin __builtin_counted_by_ref [PR116016]
With the addition of the 'counted_by' attribute and its wide roll-out
within the Linux kernel, a use case has been found that would be very
nice to have for object allocators: being able to set the counted_by
counter variable without knowing its name.
For example, given:
struct foo {
...
int counter;
...
struct bar array[] __attribute__((counted_by (counter)));
} *p;
The existing Linux object allocators are roughly:
#define MAX(A, B) (A > B) ? (A) : (B)
#define alloc(P, FAM, COUNT) ({ \
__auto_type __p = &(P); \
size_t __size = MAX (sizeof(*P),
__builtin_offsetof (__typeof(*P), FAM)
+ sizeof (*(P->FAM)) * COUNT); \
*__p = kmalloc(__size); \
})
Right now, any addition of a counted_by annotation must also
include an open-coded assignment of the counter variable after
the allocation:
p = alloc(p, array, how_many);
p->counter = how_many;
In order to avoid the tedious and error-prone work of manually adding
the open-coded counted-by intializations everywhere in the Linux
kernel, a new GCC builtin __builtin_counted_by_ref will be very useful
to be added to help the adoption of the counted-by attribute.
-- Built-in Function: TYPE __builtin_counted_by_ref (PTR)
The built-in function '__builtin_counted_by_ref' checks whether the
array object pointed by the pointer PTR has another object
associated with it that represents the number of elements in the
array object through the 'counted_by' attribute (i.e. the
counted-by object). If so, returns a pointer to the corresponding
counted-by object. If such counted-by object does not exist,
returns a null pointer.
This built-in function is only available in C for now.
The argument PTR must be a pointer to an array. The TYPE of the
returned value is a pointer type pointing to the corresponding
type of the counted-by object or a void pointer type in case of a
null pointer being returned.
With this new builtin, the central allocator could be updated to:
#define MAX(A, B) (A > B) ? (A) : (B)
#define alloc(P, FAM, COUNT) ({ \
__auto_type __p = &(P); \
__auto_type __c = (COUNT); \
size_t __size = MAX (sizeof (*(*__p)),\
__builtin_offsetof (__typeof(*(*__p)),FAM) \
+ sizeof (*((*__p)->FAM)) * __c); \
if ((*__p = kmalloc(__size))) { \
__auto_type ret = __builtin_counted_by_ref((*__p)->FAM); \
*_Generic(ret, void *: &(size_t){0}, default: ret) = __c; \
} \
})
And then structs can gain the counted_by attribute without needing
additional open-coded counter assignments for each struct, and
unannotated structs could still use the same allocator.
PR c/116016
gcc/c-family/ChangeLog:
* c-common.cc: Add new __builtin_counted_by_ref.
* c-common.h (enum rid): Add RID_BUILTIN_COUNTED_BY_REF.
gcc/c/ChangeLog:
* c-decl.cc (names_builtin_p): Add RID_BUILTIN_COUNTED_BY_REF.
* c-parser.cc (has_counted_by_object): New routine.
(get_counted_by_ref): New routine.
(c_parser_postfix_expression): Handle New RID_BUILTIN_COUNTED_BY_REF.
* c-tree.h: New routine handle_counted_by_for_component_ref.
* c-typeck.cc (handle_counted_by_for_component_ref): New routine.
(build_component_ref): Call the new routine.
gcc/ChangeLog:
* doc/extend.texi: Add documentation for __builtin_counted_by_ref.
gcc/testsuite/ChangeLog:
* gcc.dg/builtin-counted-by-ref-1.c: New test.
* gcc.dg/builtin-counted-by-ref.c: New test.
Diffstat (limited to 'libcpp/files.cc')
0 files changed, 0 insertions, 0 deletions