public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Question about sizeof after struct change
@ 2019-12-23 17:30 Erick Ochoa
  2019-12-24  7:37 ` Richard Biener
  2019-12-28 21:13 ` Nathan Sidwell
  0 siblings, 2 replies; 6+ messages in thread
From: Erick Ochoa @ 2019-12-23 17:30 UTC (permalink / raw)
  To: GCC Development, Christoph Müllner, Dr. Philipp Tomsich

Hi,

I am working on an LTO pass which drops unused fields on structs. On my
tests, I found that the gimple generated for `sizeof` is a constant. For
example, for the following C code:

```
struct astruct_s { _Bool c; _Bool a; _Bool b; };
struct astruct_s astruct;

int
main()
{
  int size = sizeof(astruct);
  return 0;
}
```

Produces the following gimple code:
```
size_1 = 3;
_2 = 0;
<L0>:
return _2;
```

Is there a way to determine where the value assigned to size_1 is
obtained from? I would like to 
1. inspect sizeof statements
2. determine whether the argument of sizeof is struct astruct_s
3. substitute struct astruct_s with a modified version of struct
astruct_s which has field `a` removed.

Therefore, at the end of this transformation we would have size_1 = 2;
Similary, I would like pointer arithmetic to be affected. For example:

```
struct astruct_s { _Bool c; _Bool a; _Bool b; };
struct astruct_s astruct;

int
main()
{
  _Bool *c = &astruct.c;
  _Bool *b = &astruct.b;
  ptrdiff_t d = b - c;
  printf("%d\n", d);
}
```

Produces the following gimple code:
```
c_3 = &astruct.c;
b_4 = &astruct.b;
d_5 = b_4 - c_3;
```

Running the code results in the value 2 being printed . After running
the transformation, the result should be 1.

Can anyone point me in the right direction?

So far I have tried changing the TYPE_FIELDS to drop field a, but that
doesn't work and it is not general. I also have some code which
creates a copy of RECORD_TYPE tree and modifies the tree and creates a
new identifier for this modified RECORD_TYPE tree. However, I believe
this may still not produce the intended behaviour.

Any help is appreciated. Thanks!

-Erick

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Question about sizeof after struct change
  2019-12-23 17:30 Question about sizeof after struct change Erick Ochoa
@ 2019-12-24  7:37 ` Richard Biener
  2020-01-03 16:09   ` Erick Ochoa
  2019-12-28 21:13 ` Nathan Sidwell
  1 sibling, 1 reply; 6+ messages in thread
From: Richard Biener @ 2019-12-24  7:37 UTC (permalink / raw)
  To: gcc, Erick Ochoa, GCC Development, Christoph Müllner,
	Dr. Philipp Tomsich

On December 23, 2019 6:30:31 PM GMT+01:00, Erick Ochoa <erick.ochoa@theobroma-systems.com> wrote:
>Hi,
>
>I am working on an LTO pass which drops unused fields on structs. On my
>tests, I found that the gimple generated for `sizeof` is a constant.
>For
>example, for the following C code:
>
>```
>struct astruct_s { _Bool c; _Bool a; _Bool b; };
>struct astruct_s astruct;
>
>int
>main()
>{
>  int size = sizeof(astruct);
>  return 0;
>}
>```
>
>Produces the following gimple code:
>```
>size_1 = 3;
>_2 = 0;
><L0>:
>return _2;
>```
>
>Is there a way to determine where the value assigned to size_1 is
>obtained from? I would like to 
>1. inspect sizeof statements
>2. determine whether the argument of sizeof is struct astruct_s
>3. substitute struct astruct_s with a modified version of struct
>astruct_s which has field `a` removed.
>
>Therefore, at the end of this transformation we would have size_1 = 2;
>Similary, I would like pointer arithmetic to be affected. For example:
>
>```
>struct astruct_s { _Bool c; _Bool a; _Bool b; };
>struct astruct_s astruct;
>
>int
>main()
>{
>  _Bool *c = &astruct.c;
>  _Bool *b = &astruct.b;
>  ptrdiff_t d = b - c;
>  printf("%d\n", d);
>}
>```
>
>Produces the following gimple code:
>```
>c_3 = &astruct.c;
>b_4 = &astruct.b;
>d_5 = b_4 - c_3;
>```
>
>Running the code results in the value 2 being printed . After running
>the transformation, the result should be 1.
>
>Can anyone point me in the right direction?

I believe there is no convenient point in the compilation to do all of this in GCC. 

Note that users can very well write a literal 8 (substitute correct value) for a
Sizeof expression. Likewise writing pointer subtraction in terms of integers is possible. 

>So far I have tried changing the TYPE_FIELDS to drop field a, but that
>doesn't work and it is not general. I also have some code which
>creates a copy of RECORD_TYPE tree and modifies the tree and creates a
>new identifier for this modified RECORD_TYPE tree. However, I believe
>this may still not produce the intended behaviour.
>
>Any help is appreciated. Thanks!

You need to analyze and change all actual accesses since not all of them will necessarily use component refs refering to the FIELD_DECLs you change.

Richard. 

>-Erick

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Question about sizeof after struct change
  2019-12-23 17:30 Question about sizeof after struct change Erick Ochoa
  2019-12-24  7:37 ` Richard Biener
@ 2019-12-28 21:13 ` Nathan Sidwell
  1 sibling, 0 replies; 6+ messages in thread
From: Nathan Sidwell @ 2019-12-28 21:13 UTC (permalink / raw)
  To: Erick Ochoa, GCC Development, Christoph Müllner,
	Dr. Philipp Tomsich

On 12/23/19 12:30 PM, Erick Ochoa wrote:
> Hi,
> 
> I am working on an LTO pass which drops unused fields on structs. On my
> tests, I found that the gimple generated for `sizeof` is a constant. For
> example, for the following C code:
> 
> ```

you also need to pay attention to offsetof.

nathan
-- 
Nathan Sidwell

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Question about sizeof after struct change
  2019-12-24  7:37 ` Richard Biener
@ 2020-01-03 16:09   ` Erick Ochoa
  2020-01-06 11:03     ` Jonathan Wakely
  0 siblings, 1 reply; 6+ messages in thread
From: Erick Ochoa @ 2020-01-03 16:09 UTC (permalink / raw)
  To: Richard Biener, gcc, Christoph Müllner, Dr. Philipp Tomsich



On 2019-12-24 2:37 a.m., Richard Biener wrote:
> On December 23, 2019 6:30:31 PM GMT+01:00, Erick Ochoa <erick.ochoa@theobroma-systems.com> wrote:
>> Hi,
>>
>> I am working on an LTO pass which drops unused fields on structs. On my
>> tests, I found that the gimple generated for `sizeof` is a constant.
>> For
>> example, for the following C code:
>>
>> ```
>> struct astruct_s { _Bool c; _Bool a; _Bool b; };
>> struct astruct_s astruct;
>>
>> int
>> main()
>> {
>>  int size = sizeof(astruct);
>>  return 0;
>> }
>> ```
>>
>> Produces the following gimple code:
>> ```
>> size_1 = 3;
>> _2 = 0;
>> <L0>:
>> return _2;
>> ```
>>
>> Is there a way to determine where the value assigned to size_1 is
>> obtained from? I would like to 
>> 1. inspect sizeof statements
>> 2. determine whether the argument of sizeof is struct astruct_s
>> 3. substitute struct astruct_s with a modified version of struct
>> astruct_s which has field `a` removed.
>>
>> Therefore, at the end of this transformation we would have size_1 = 2;
>> Similary, I would like pointer arithmetic to be affected. For example:
>>
>> ```
>> struct astruct_s { _Bool c; _Bool a; _Bool b; };
>> struct astruct_s astruct;
>>
>> int
>> main()
>> {
>>  _Bool *c = &astruct.c;
>>  _Bool *b = &astruct.b;
>>  ptrdiff_t d = b - c;
>>  printf("%d\n", d);
>> }
>> ```
>>
>> Produces the following gimple code:
>> ```
>> c_3 = &astruct.c;
>> b_4 = &astruct.b;
>> d_5 = b_4 - c_3;
>> ```
>>
>> Running the code results in the value 2 being printed . After running
>> the transformation, the result should be 1.
>>
>> Can anyone point me in the right direction?
> 
> I believe there is no convenient point in the compilation to do all of this in GCC. 
> 
> Note that users can very well write a literal 8 (substitute correct value) for a
> Sizeof expression. Likewise writing pointer subtraction in terms of integers is possible. 
> 
>> So far I have tried changing the TYPE_FIELDS to drop field a, but that
>> doesn't work and it is not general. I also have some code which
>> creates a copy of RECORD_TYPE tree and modifies the tree and creates a
>> new identifier for this modified RECORD_TYPE tree. However, I believe
>> this may still not produce the intended behaviour.
>>
>> Any help is appreciated. Thanks!

Hi Richard,

can you please clarify what do you mean by:

> 
> You need to analyze and change all actual accesses since not all of them will necessarily use component refs refering to the FIELD_DECLs you change.

If we are not using component refs to access the fields, what else can be used?
Do you mean something like taking the address of a struct and adding an offset
to access a field?

Thanks!

> 
> Richard. 
> 
>> -Erick
> 

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Question about sizeof after struct change
  2020-01-03 16:09   ` Erick Ochoa
@ 2020-01-06 11:03     ` Jonathan Wakely
  2020-01-07 12:43       ` Richard Biener
  0 siblings, 1 reply; 6+ messages in thread
From: Jonathan Wakely @ 2020-01-06 11:03 UTC (permalink / raw)
  To: Erick Ochoa
  Cc: Richard Biener, gcc, Christoph Müllner, Dr. Philipp Tomsich

On Fri, 3 Jan 2020 at 16:09, Erick Ochoa wrote:
> Do you mean something like taking the address of a struct and adding an offset
> to access a field?

Yes, the following code is valid:

struct S { int unused; int used; };
static_assert( sizeof(S) == 8 );
S s[4];
int* s2_used = (int*)((char*)s + 20);

Accessing the field doesn't refer to S::used or S::unused directly,
and doesn't use sizeof(S) or sizeof(int) explicitly.

So if your pass removes S::unused, then you'd need to analyse
((char*)s + 20) to determine that it accesses s[2].used and then
adjust it to ((char*)s + 8) instead.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Question about sizeof after struct change
  2020-01-06 11:03     ` Jonathan Wakely
@ 2020-01-07 12:43       ` Richard Biener
  0 siblings, 0 replies; 6+ messages in thread
From: Richard Biener @ 2020-01-07 12:43 UTC (permalink / raw)
  To: Jonathan Wakely
  Cc: Erick Ochoa, gcc, Christoph Müllner, Dr. Philipp Tomsich

On Mon, Jan 6, 2020 at 12:03 PM Jonathan Wakely <jwakely.gcc@gmail.com> wrote:
>
> On Fri, 3 Jan 2020 at 16:09, Erick Ochoa wrote:
> > Do you mean something like taking the address of a struct and adding an offset
> > to access a field?
>
> Yes, the following code is valid:
>
> struct S { int unused; int used; };
> static_assert( sizeof(S) == 8 );
> S s[4];
> int* s2_used = (int*)((char*)s + 20);
>
> Accessing the field doesn't refer to S::used or S::unused directly,
> and doesn't use sizeof(S) or sizeof(int) explicitly.
>
> So if your pass removes S::unused, then you'd need to analyse
> ((char*)s + 20) to determine that it accesses s[2].used and then
> adjust it to ((char*)s + 8) instead.

Also GCC, at its own discretion, might decide to change
s[1].used to MEM[&s + 8] because semantically they are
the same.

Richard.

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2020-01-07 12:43 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-23 17:30 Question about sizeof after struct change Erick Ochoa
2019-12-24  7:37 ` Richard Biener
2020-01-03 16:09   ` Erick Ochoa
2020-01-06 11:03     ` Jonathan Wakely
2020-01-07 12:43       ` Richard Biener
2019-12-28 21:13 ` Nathan Sidwell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).