> On Jul 17, 2025, at 11:40, Jakub Jelinek <ja...@redhat.com> wrote:
> 
> On Thu, Jul 17, 2025 at 03:26:05PM +0000, Qing Zhao wrote:
>> How about add a new flag to distinguish these two cases, and put it to the 
>> 3th argument:
>> 
>>   ACCESS_WITH_SIZE (REF_TO_OBJ, REF_TO_SIZE,
>>                     TYPE_OF_SIZE + ACCESS_MODE + IS_POINTER, TYPE_SIZE_UNIT 
>> for element)
>>   which returns the REF_TO_OBJ same as the 1st argument;
>> 
>>   1st argument REF_TO_OBJ: The reference to the object when IS_POINTER is 
>> false;
>>           The address of the reference to the object when IS_POINTER is true;
>>   2nd argument REF_TO_SIZE: The reference to the size of the object,
>>   3rd argument TYPE_OF_SIZE + ACCESS_MODE + IS_POINTER An integer constant 
>> with a pointer
>>     TYPE.
>>     The pointee TYPE of the pointer TYPE is the TYPE of the object referenced
>>        by REF_TO_SIZE.
>>     The integer constant value represents the ACCESS_MODE + IS_POINTER:
>>        00: none
>>        01: read_only
>>        10: write_only
>>        11: read_write
>>       100:  IS_POINTER
> 
> Sure, I was talking about it before, the value of the 3rd argument can be a
> set of various bit flags.
> I still don't understand what do you want to use that
> read_only/write_only/read_write flags for,

It will be used for implementing the attribute “access” with .ACCESS_WITH_SIZE: 
(a future work)
https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-access-function-attribute

access (access-mode, ref-index) 

The ACCESS_MODE flag in the 3rd argument is for carrying the above 
“access_mode” of the first argument
of the “access” attribute.  


> if you mark loads from the
> pointer, those will be always reads and whether something is load, store or
> load/store of data pointed by that pointer is something normally visible in
> the IL (plus you probably don't know it in the FE).

Since I haven’t study this in details yet, not sure whether this is necessary 
or not to encode it into 
.ACCESS_WITH_SIZE.

Maybe just this flag now? And add it later if we really need it?

> 
> So say for
> struct S { int s; int *p __attribute__((counted_by (s))); };
> 
> int
> foo (struct S *x, int y)
> {
>  return x->p[y];
> }
> I would have expected you emit something like
>  _1 = x->p;
>  _6 = &x->s;
>  _5 = .ACCESS_WITH_SIZE (_1, _6, IS_POINTER, 4);
>  _2 = (long unsigned int) y;
>  _3 = _2 * 4;
>  _4 = _5 + _3;
>  D.2965 = *_4;

The above IL doesn’t require an additional IS_POINTER flag for the 
.ACCESS_WITH_SIZE since 
The first argument is still the pointer for the object, same as the FAM case.

With IS_POINTER flag added, we can pass the ADDRESS of the pointer as the first 
argument to
.ACCESS_WITH_SIZE, and also return the ADDRESS of the pointer for the pointer 
with counted_by. i.e:

 _1 = &x->p;
 _6 = &x->s;
 _5 = .ACCESS_WITH_SIZE (_1, _6, IS_POINTER, 4);
 _2 = (long unsigned int) y;
 _3 = _2 * 4;
 _4 = *_5 + _3;
 D.2965 = *_4;

> and for
>  x->p = whatever;
> no .ACCESS_WITH_SIZE.

With the IS_POINTER flag, and pass and return the ADDRESS of the pointer to 
.ACCESS_WITH_SIZE, 
It will be no correctness issue when we generate .ACCESS_WITH_SIZE for the 
above case. 
The only issue is for such case, the call to .ACCESS_WITH_SIZE is useless. 

Is this reasonable?

Qing




Reply via email to