Am Donnerstag, dem 02.11.2023 um 17:28 -0700 schrieb Bill Wendling: > On Thu, Nov 2, 2023 at 1:36 PM Qing Zhao <qing.z...@oracle.com> wrote: > > > > Thanks a lot for raising these issues. > > > > If I understand correctly, the major question we need to answer is: > > > > For the following example: (Jakub mentioned this in an early message) > > > > 1 struct S { int a; char b __attribute__((counted_by (a))) []; }; > > 2 struct S s; > > 3 s.a = 5; > > 4 char *p = &s.b[2]; > > 5 int i1 = __builtin_dynamic_object_size (p, 0); > > 6 s.a = 3; > > 7 int i2 = __builtin_dynamic_object_size (p, 0); > > > > Should the 2nd __bdos call (line 7) get > > A. the latest value of s.a (line 6) for it’s size? > > Or B. the value when the s.b was referenced (line 3, line 4)? > > > I personally think it should be (A). The user is specifically > indicating that the size has somehow changed, and the compiler should > behave accordingly.
One potential problem for A apart from the potential impact on optimization is that the information may get lost more easily. Consider: char *p = &s.b[2]; f(&s); int i = __bdos(p, 0); If the compiler can not see into 'f', the information is lost because f may have changed the size. And if I understand it correctly, if the pointers escapes with .ACCESS_WITH_SIZE, then this is already true for: char *p = &s.b[2]; g(); int i = __bdos(p, 0); If we make it UB to change the size, then I guess we could also delay this choice. Or we implement B but have a UBSan option based on A that only verifies at run-time that the size did not change. Martin > > > A should be more convenient for the user to use the dynamic array feature. > > With B, the user has to modify the source code (to add code to “re-obtain” > > the pointer after the size was adjusted at line 6) as mentioned by Richard. > > > > This depends on how we design the new internal function .ACCESS_WITH_SIZE > > > > 1. Size is passed by value to .ACCESS_WITH_SIZE as we currently designed. > > > > PTR = .ACCESS_WITH_SIZE (PTR, SIZE, ACCESS_MODE) > > > > 2. Size is passed by reference to .ACCESS_WITH_SIZE as Jakub suggested. > > > > PTR = .ACCESS_WITH_SIZE(PTR, &SIZE, TYPEOFSIZE, ACCESS_MODE) > > > > With 1, We can only provide B, the user needs to modify the source code to > > get the full feature of dynamic array; > > With 2, We can provide A, the user will get full support to the dynamic > > array without restrictions in the source code. > > > My understanding of ACCESS_WITH_SIZE is that it's there to add an > explicit reference to SIZE so that the optimizers won't reorder the > code incorrectly. If that's the case, then it should act as if > ACCESS_WITH_SIZE wasn't even there (i.e. it's just a pointer > dereference into the FAM). We get that with (2) it appears. It would > be a major headache to make the user go throughout their code base to > ensure that SIZE was either unmodified, or if it was that extra code > must be added to ensure the expected behavior. > > > However, We have to pay additional cost for supporting A by using 2, which > > includes: > > > > 1. .ACCESS_WITH_SIZE will become an escape point, which will further impact > > the IPA optimizations, more runtime overhead. > > Then .ACCESS_WTH_SIZE will not be CONST, right? But it will still be > > PURE? > > > > 2. __builtin_dynamic_object_size will NOT be LEAF anymore. This will also > > impact some IPA optimizations, more runtime overhead. > > > > I think the following are the factors that make the decision: > > > > 1. How big the performance impact? > > 2. How important the dynamic array feature? Is adding some user > > restrictions as Richard mentioned feasible to support this feature? > > > > Maybe we can implement 1 first, if the full support to the dynamic array is > > needed, we can add 2 then? > > Or, we can implement both, and compare the performance difference, then > > decide? > > > > Qing > >