On 2025-04-08 12:41, Qing Zhao wrote:
For the following small example:
[ counted_by_whole]$ cat t.c
#include <stdlib.h>
#include <stddef.h>
struct annotated {
size_t count;
char other;
char array[] __attribute__((counted_by (count)));
};
#define MAX(A, B) (A > B) ? (A) : (B)
#define ALLOC_SIZE_ANNOTATED(COUNT) \
MAX(sizeof (struct annotated), \
offsetof(struct annotated, array[0]) + (COUNT) * sizeof(char))
static struct annotated * __attribute__((__noinline__)) alloc_buf (int index)
{
struct annotated *p;
p = (struct annotated *) malloc (ALLOC_SIZE_ANNOTATED(index));
p->count = index;
return p;
}
int main()
{
struct annotated *q = alloc_buf (10);
__builtin_printf ("the bdos whole is %d\n",
__builtin_dynamic_object_size(q, 1));
return 0;
}
The gimple IR is:
1 int main ()
2 {
3 int D.5072;
4
5 {
6 struct annotated * q;
7
8 q = alloc_buf (10);
9 _1 = __builtin_dynamic_object_size (q, 1);
10 __builtin_printf ("the bdos whole is %d\n", _1);
11 D.5072 = 0;
12 return D.5072;
13 }
14 D.5072 = 0;
15 return D.5072;
16 }
17
18
19 __attribute__((noinline))
20 struct annotated * alloc_buf (int index)
21 {
22 struct annotated * D.5074;
23 struct annotated * p;
24 25 _1 = (long unsigned int) index;
26 _2 = _1 + 9;
27 _3 = MAX_EXPR <_2, 16>;
28 p = malloc (_3);
29 _4 = (long unsigned int) index;
30 p->count = _4;
31 D.5074 = p;
32 return D.5074;
33 }
When we generate the .ACCESS_WITH_SIZE for a pointer reference to “struct
annotated”,
Looks like all the pointer references, at line 8, “q”, at line 9, “q”, at line
28, “p”, need to be changed
to a call to .ACCESS_WITH_SIZE. this might increase the IR size unnecessarily.
Might have some
Impact on the inlining decision heuristics or other heuristic that depend on
the code size.
Not sure whether this is a concern or not.
On the general question of whether additional .ACCESS_WITH_SIZE could
hinder optimizations, one effect may be that it ends up acting as a
barrier preventing code reordering around it, which may miss some
opportunities. However IMO that preserves correctness anyway.
On the other hand though, .ACCESS_WITH_SIZE should ideally provide range
information that could aid optimization or even diagnostics. It's not
something we do at the moment AFAIK though, except when
.ACCESS_WITH_SIZE feeds directly into a __bos/__bdos call, in which case
the __bos/__bdos call ends up providing that hint (I think).
Andrew, is this something pranger could explicitly identify? That is,
use .ACCESS_WITH_SIZE calls to identify the range of the pointer it is
called with?
Thanks,
Sid