> On Nov 2, 2023, at 7:52 AM, Richard Biener <richard.guent...@gmail.com> wrote: > > On Thu, Nov 2, 2023 at 11:40 AM Jakub Jelinek <ja...@redhat.com> wrote: >> >> On Thu, Nov 02, 2023 at 11:18:09AM +0100, Richard Biener wrote: >>>> Or, if we want to pay further price, .ACCESS_WITH_SIZE could take as one of >>>> the arguments not the size value, but its address. Then at __bdos time >>>> we would dereference that pointer to get the size. >>>> So, >>>> struct S { int a; char b __attribute__((counted_by (a))) []; }; >>>> struct S s; >>>> s.a = 5; >>>> char *p = &s.b[2]; >>>> int i1 = __builtin_dynamic_object_size (p, 0); >>>> s.a = 3; >>>> int i2 = __builtin_dynamic_object_size (p, 0); >>>> would then yield 3 and 1 rather than 3 and 3. >>> >>> I fail to see how we can get the __builtin_dynamic_object_size call >>> data dependent on s.a, thus avoid re-ordering or even DSE of the >>> store. >> >> If &s.b[2] is lowered as >> sz_1 = s.a; >> tmp_2 = .ACCESS_WITH_SIZE (&s.b[0], sz_1); >> p_3 = &tmp_2[2]; >> then sure, there is no way, you get the size from that point. >> tree-object-size.cc tracking then determines that in a particular >> case the pointer is size associated with sz_1 and use that value >> as the size (with the usual adjustments for pointer arithmetics and the >> like). >> >> What I meant is to emit >> tmp_4 = .ACCESS_WITH_SIZE (&s.b[0], &s.a, (typeof (&s.a)) 0); >> p_5 = &tmp_4[2]; >> i.e. don't associate the pointer with a value of the size, but with >> an address where to find the size (plus how large it is), basically escape >> pointer to the size at that point. And __builtin_dynamic_object_size is >> pure, >> so supposedly it can depend on what the escaped pointer points to. > > Well, yeah - that would work but depend on .ACCESS_WITH_SIZE being an > escape point (quite bad IMHO) and __builtin_dynamic_object_size being > non-const (that's probably not too bad). > >> We'd see that a particular pointer is size associated with &s.a address >> and would use that address cast to the type of the third argument (to >> preserve the exact pointer type on INTEGER_CST, though not sure, wouldn't >> VN CSE it anyway if one has say >> union U { struct S { int a; char b __attribute__((counted_by (a))) []; } s; >> struct T { char c, d, e, f; char g __attribute__((counted_by (c))) >> []; } t; }; >> and >> .ACCESS_WITH_SIZE (&v.s.b[0], &v.s.a, (int *) 0); >> ... >> .ACCESS_WITH_SIZE (&v.t.g[0], &v.t.c, (int *) 0); >> ? > > We'd probably CSE that - the usual issue of address-with-same-value. > >> It would mean though that counted_by wouldn't be allowed to be a >> bit-field... > > Yup. We could also pass a pointer to the container though, that's good enough > for the escape, and pass the size by value in addition to that. Could you explain a little bit more here? Then the .ACCESS_WITH_SIZE will become
PTR = .ACCESS_WITH_SIZE (PTR, &PTR’s Container, SIZE, ACCESS_MODE) ?? > >> Jakub >>