public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* Correct way to express to the compiler "this does not get clobbered"?
@ 2020-12-03 11:47 Andrea Corallo
  2020-12-03 12:04 ` Richard Earnshaw
                   ` (2 more replies)
  0 siblings, 3 replies; 27+ messages in thread
From: Andrea Corallo @ 2020-12-03 11:47 UTC (permalink / raw)
  To: gcc-help; +Cc: nd

Hi all,

I've a piece of code that reduced looks like this:

#+begin_src C
typedef struct {
  void (*fun_ptr)(void);
} x_t;

x_t *x;

void
f (void)
{
  const x_t const *y = x;
  for (int i = 0; i < 1000; ++i)
    y->fun_ptr ();
}
#+end_src

What is the correct way (if any) to express to the compiler that the
value of y->fun_ptr does not get clobbered by the function call itself
so the corresponding load to obtain its value can be moved out of the
loop?

My understanding is that the const qualifier is more for diagnostic
reasons and is not sufficient for GCC to make this assumption.  OTOH I
cannot give 'fun_ptr' the attribute pure as it's not.

Thanks

  Andrea

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

* Re: Correct way to express to the compiler "this does not get clobbered"?
  2020-12-03 11:47 Correct way to express to the compiler "this does not get clobbered"? Andrea Corallo
@ 2020-12-03 12:04 ` Richard Earnshaw
  2020-12-03 12:28   ` Andrea Corallo
  2020-12-03 18:24 ` David Brown
  2020-12-05  8:06 ` Liu Hao
  2 siblings, 1 reply; 27+ messages in thread
From: Richard Earnshaw @ 2020-12-03 12:04 UTC (permalink / raw)
  To: Andrea Corallo, gcc-help; +Cc: nd

On 03/12/2020 11:47, Andrea Corallo via Gcc-help wrote:
> Hi all,
> 
> I've a piece of code that reduced looks like this:
> 
> #+begin_src C
> typedef struct {
>   void (*fun_ptr)(void);
> } x_t;
> 
> x_t *x;
> 
> void
> f (void)
> {
>   const x_t const *y = x;
>   for (int i = 0; i < 1000; ++i)
>     y->fun_ptr ();
> }
> #+end_src
> 
> What is the correct way (if any) to express to the compiler that the
> value of y->fun_ptr does not get clobbered by the function call itself
> so the corresponding load to obtain its value can be moved out of the
> loop?
> 
> My understanding is that the const qualifier is more for diagnostic
> reasons and is not sufficient for GCC to make this assumption.  OTOH I
> cannot give 'fun_ptr' the attribute pure as it's not.
> 
> Thanks
> 
>   Andrea
> 

Why not just put the function pointer in a local variable?  Then the
compiler will know that the value can't change.

R.



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

* Re: Correct way to express to the compiler "this does not get clobbered"?
  2020-12-03 12:04 ` Richard Earnshaw
@ 2020-12-03 12:28   ` Andrea Corallo
  2020-12-03 13:06     ` Richard Earnshaw
  0 siblings, 1 reply; 27+ messages in thread
From: Andrea Corallo @ 2020-12-03 12:28 UTC (permalink / raw)
  To: Richard Earnshaw; +Cc: gcc-help, nd

Richard Earnshaw <Richard.Earnshaw@foss.arm.com> writes:

> On 03/12/2020 11:47, Andrea Corallo via Gcc-help wrote:
>> Hi all,
>> 
>> I've a piece of code that reduced looks like this:
>> 
>> #+begin_src C
>> typedef struct {
>>   void (*fun_ptr)(void);
>> } x_t;
>> 
>> x_t *x;
>> 
>> void
>> f (void)
>> {
>>   const x_t const *y = x;
>>   for (int i = 0; i < 1000; ++i)
>>     y->fun_ptr ();
>> }
>> #+end_src
>> 
>> What is the correct way (if any) to express to the compiler that the
>> value of y->fun_ptr does not get clobbered by the function call itself
>> so the corresponding load to obtain its value can be moved out of the
>> loop?
>> 
>> My understanding is that the const qualifier is more for diagnostic
>> reasons and is not sufficient for GCC to make this assumption.  OTOH I
>> cannot give 'fun_ptr' the attribute pure as it's not.
>> 
>> Thanks
>> 
>>   Andrea
>> 
>
> Why not just put the function pointer in a local variable?  Then the
> compiler will know that the value can't change.

Hi Richard,

yeah that would do the job.

This is generated code and changing the code generator that way might
not be completely trivial (e.g. where is the best position to perform
the assignments to each local variable?).  Therefore before going for
this solution I'd like to be convinced there's no way to express this
directly to GCC.

  Andrea

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

* Re: Correct way to express to the compiler "this does not get clobbered"?
  2020-12-03 12:28   ` Andrea Corallo
@ 2020-12-03 13:06     ` Richard Earnshaw
  2020-12-03 13:40       ` Andrea Corallo
  0 siblings, 1 reply; 27+ messages in thread
From: Richard Earnshaw @ 2020-12-03 13:06 UTC (permalink / raw)
  To: Andrea Corallo; +Cc: gcc-help, nd

On 03/12/2020 12:28, Andrea Corallo wrote:
> Richard Earnshaw <Richard.Earnshaw@foss.arm.com> writes:
> 
>> On 03/12/2020 11:47, Andrea Corallo via Gcc-help wrote:
>>> Hi all,
>>>
>>> I've a piece of code that reduced looks like this:
>>>
>>> #+begin_src C
>>> typedef struct {
>>>   void (*fun_ptr)(void);
>>> } x_t;
>>>
>>> x_t *x;
>>>
>>> void
>>> f (void)
>>> {
>>>   const x_t const *y = x;
>>>   for (int i = 0; i < 1000; ++i)
>>>     y->fun_ptr ();
>>> }
>>> #+end_src
>>>
>>> What is the correct way (if any) to express to the compiler that the
>>> value of y->fun_ptr does not get clobbered by the function call itself
>>> so the corresponding load to obtain its value can be moved out of the
>>> loop?
>>>
>>> My understanding is that the const qualifier is more for diagnostic
>>> reasons and is not sufficient for GCC to make this assumption.  OTOH I
>>> cannot give 'fun_ptr' the attribute pure as it's not.
>>>
>>> Thanks
>>>
>>>   Andrea
>>>
>>
>> Why not just put the function pointer in a local variable?  Then the
>> compiler will know that the value can't change.
> 
> Hi Richard,
> 
> yeah that would do the job.
> 
> This is generated code and changing the code generator that way might
> not be completely trivial (e.g. where is the best position to perform
> the assignments to each local variable?).  Therefore before going for
> this solution I'd like to be convinced there's no way to express this
> directly to GCC.
> 
>   Andrea
> 

Perhaps you could declare y with the restrict qualifier?  But that would
need to apply to all of *y, not just fun_ptr.

R.

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

* Re: Correct way to express to the compiler "this does not get clobbered"?
  2020-12-03 13:06     ` Richard Earnshaw
@ 2020-12-03 13:40       ` Andrea Corallo
  0 siblings, 0 replies; 27+ messages in thread
From: Andrea Corallo @ 2020-12-03 13:40 UTC (permalink / raw)
  To: Richard Earnshaw; +Cc: gcc-help, nd

Richard Earnshaw <Richard.Earnshaw@foss.arm.com> writes:

[...]

> Perhaps you could declare y with the restrict qualifier?  But that would
> need to apply to all of *y, not just fun_ptr.

Having it applied to all *y would be perfect to me.

Unfortunatelly declaring y as:

x_t  * __restrict__ y = x;

does not influence the generated code :/

I though restrict is for pointer aliasing, maybe does not cover function
call clobbering?

  Andrea

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

* Re: Correct way to express to the compiler "this does not get clobbered"?
  2020-12-03 11:47 Correct way to express to the compiler "this does not get clobbered"? Andrea Corallo
  2020-12-03 12:04 ` Richard Earnshaw
@ 2020-12-03 18:24 ` David Brown
  2020-12-03 23:00   ` Andrea Corallo
  2020-12-05  8:06 ` Liu Hao
  2 siblings, 1 reply; 27+ messages in thread
From: David Brown @ 2020-12-03 18:24 UTC (permalink / raw)
  To: Andrea Corallo, gcc-help; +Cc: nd

On 03/12/2020 12:47, Andrea Corallo via Gcc-help wrote:
> Hi all,
> 
> I've a piece of code that reduced looks like this:
> 
> #+begin_src C
> typedef struct {
>   void (*fun_ptr)(void);
> } x_t;
> 
> x_t *x;
> 
> void
> f (void)
> {
>   const x_t const *y = x;
>   for (int i = 0; i < 1000; ++i)
>     y->fun_ptr ();
> }
> #+end_src
> 
> What is the correct way (if any) to express to the compiler that the
> value of y->fun_ptr does not get clobbered by the function call itself
> so the corresponding load to obtain its value can be moved out of the
> loop?
> 
> My understanding is that the const qualifier is more for diagnostic
> reasons and is not sufficient for GCC to make this assumption.  OTOH I
> cannot give 'fun_ptr' the attribute pure as it's not.
> 

Imagine you also had :

x_t foox;

void foo1(void);
void foo2(void);

void foo1(void) {
	printf("foo1\n");
	foox.fun_ptr = foo2;
}

void foo2(void) {
	printf("foo2\n");
	foox.fun_ptr = foo1;
}

void test(void) {
	x = &foox;
	f();
}

As "f()" runs, the value of "y->fun_ptr" changes with each step as you
get alternating "foo1", "foo2" outputs.  Thus it is clear (I hope) that
the compiler cannot assume that "y->fun_ptr" is not clobbered by the
function call.

To get the effect you want, you'll have to change the code.  The easiest
way is (as has been suggested) to capture "y->fun_ptr" in a local
variable.  Alternatively you could capture "x" to a local variable, or
make it static, and ensure that its address doesn't escape - then the
compiler can tell that the fun_ptr() call can't change it.




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

* Re: Correct way to express to the compiler "this does not get clobbered"?
  2020-12-03 18:24 ` David Brown
@ 2020-12-03 23:00   ` Andrea Corallo
  2020-12-04  7:23     ` stefan
  2020-12-04  8:27     ` David Brown
  0 siblings, 2 replies; 27+ messages in thread
From: Andrea Corallo @ 2020-12-03 23:00 UTC (permalink / raw)
  To: David Brown; +Cc: gcc-help, nd

David Brown <david.brown@hesbynett.no> writes:

Hi David,

> As "f()" runs, the value of "y->fun_ptr" changes with each step as you
> get alternating "foo1", "foo2" outputs.  Thus it is clear (I hope) that
> the compiler cannot assume that "y->fun_ptr" is not clobbered by the
> function call.

Indeed that's clear.  The question is more if there's some way to express
this to the compiler qualifying the variables in discussion without
changing the structure of the code.  This because as I wrote may be not
trivial to modify the code generator for optimal results.

I understand this is probably not possible and there's no magic
attribute or qualifier to express this.

Thanks

  Andrea

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

* Re: Correct way to express to the compiler "this does not get clobbered"?
  2020-12-03 23:00   ` Andrea Corallo
@ 2020-12-04  7:23     ` stefan
  2020-12-04  9:52       ` Andrea Corallo
  2020-12-04  8:27     ` David Brown
  1 sibling, 1 reply; 27+ messages in thread
From: stefan @ 2020-12-04  7:23 UTC (permalink / raw)
  To: Stefan Franke; +Cc: gcc-help



Am 4. Dezember 2020 00:00:28 MEZ schrieb Andrea Corallo via Gcc-help <gcc-help@gcc.gnu.org>:
>David Brown <david.brown@hesbynett.no> writes:
>
>Hi David,
>
>> As "f()" runs, the value of "y->fun_ptr" changes with each step as
>you
>> get alternating "foo1", "foo2" outputs.  Thus it is clear (I hope)
>that
>> the compiler cannot assume that "y->fun_ptr" is not clobbered by the
>> function call.
>
>Indeed that's clear.  The question is more if there's some way to
>express
>this to the compiler qualifying the variables in discussion without
>changing the structure of the code.  This because as I wrote may be not
>trivial to modify the code generator for optimal results.
>
>I understand this is probably not possible and there's no magic
>attribute or qualifier to express this.
>
>Thanks
>
>  Andrea

IMHO it's a bug that const members referenced by a const pointer are reloaded inside the loop.

Regards

Stefan

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

* Re: Correct way to express to the compiler "this does not get clobbered"?
  2020-12-03 23:00   ` Andrea Corallo
  2020-12-04  7:23     ` stefan
@ 2020-12-04  8:27     ` David Brown
  2020-12-04 10:05       ` Andrea Corallo
  1 sibling, 1 reply; 27+ messages in thread
From: David Brown @ 2020-12-04  8:27 UTC (permalink / raw)
  To: Andrea Corallo; +Cc: gcc-help, nd


On 04/12/2020 00:00, Andrea Corallo wrote:
> David Brown <david.brown@hesbynett.no> writes:
> 
> Hi David,
> 
>> As "f()" runs, the value of "y->fun_ptr" changes with each step as you
>> get alternating "foo1", "foo2" outputs.  Thus it is clear (I hope) that
>> the compiler cannot assume that "y->fun_ptr" is not clobbered by the
>> function call.
> 
> Indeed that's clear.  The question is more if there's some way to express
> this to the compiler qualifying the variables in discussion without
> changing the structure of the code.  This because as I wrote may be not
> trivial to modify the code generator for optimal results.
> 
> I understand this is probably not possible and there's no magic
> attribute or qualifier to express this.
> 

In order to add a qualifier or attribute, you'd still need to change the 
code in some way.  Is it possible to make /some/ changes to the code 
generator, but not others?  (I appreciate that code generators can be 
difficult to change.)

On trick that sometimes works when you want to give the compiler more 
information is to use "if (!x) __builtin_unreachable();" as a way of 
saying "x is always true".  But I can't see any way that would help 
here, I'm afraid.


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

* Re: Correct way to express to the compiler "this does not get clobbered"?
  2020-12-04  7:23     ` stefan
@ 2020-12-04  9:52       ` Andrea Corallo
  2020-12-04 17:27         ` Segher Boessenkool
  0 siblings, 1 reply; 27+ messages in thread
From: Andrea Corallo @ 2020-12-04  9:52 UTC (permalink / raw)
  To: stefan; +Cc: gcc-help

stefan@franke.ms writes:

> Am 4. Dezember 2020 00:00:28 MEZ schrieb Andrea Corallo via Gcc-help <gcc-help@gcc.gnu.org>:
>>David Brown <david.brown@hesbynett.no> writes:
>>
>>Hi David,
>>
>>> As "f()" runs, the value of "y->fun_ptr" changes with each step as
>>you
>>> get alternating "foo1", "foo2" outputs.  Thus it is clear (I hope)
>>that
>>> the compiler cannot assume that "y->fun_ptr" is not clobbered by the
>>> function call.
>>
>>Indeed that's clear.  The question is more if there's some way to
>>express
>>this to the compiler qualifying the variables in discussion without
>>changing the structure of the code.  This because as I wrote may be not
>>trivial to modify the code generator for optimal results.
>>
>>I understand this is probably not possible and there's no magic
>>attribute or qualifier to express this.
>>
>>Thanks
>>
>>  Andrea
>
> IMHO it's a bug that const members referenced by a const pointer are reloaded inside the loop.

I might open a bug but my understanding is that const is generally
not used for optimizations.  Am I wrong?

  Andrea

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

* Re: Correct way to express to the compiler "this does not get clobbered"?
  2020-12-04  8:27     ` David Brown
@ 2020-12-04 10:05       ` Andrea Corallo
  0 siblings, 0 replies; 27+ messages in thread
From: Andrea Corallo @ 2020-12-04 10:05 UTC (permalink / raw)
  To: David Brown; +Cc: gcc-help, nd

David Brown <david.brown@hesbynett.no> writes:

> On 04/12/2020 00:00, Andrea Corallo wrote:
>> David Brown <david.brown@hesbynett.no> writes:
>> Hi David,
>> 
>>> As "f()" runs, the value of "y->fun_ptr" changes with each step as you
>>> get alternating "foo1", "foo2" outputs.  Thus it is clear (I hope) that
>>> the compiler cannot assume that "y->fun_ptr" is not clobbered by the
>>> function call.
>> Indeed that's clear.  The question is more if there's some way to
>> express
>> this to the compiler qualifying the variables in discussion without
>> changing the structure of the code.  This because as I wrote may be not
>> trivial to modify the code generator for optimal results.
>> I understand this is probably not possible and there's no magic
>> attribute or qualifier to express this.
>> 
>
> In order to add a qualifier or attribute, you'd still need to change
> the code in some way.  Is it possible to make /some/ changes to the
> code generator, but not others?

What I said is that is possible to change the code generator, but adding
a qualifier or similar would be trivial, adding the local copy no.

I have many of these functions called through function pointer, each of
these can appear more then once in the code and I have non trivial
control flows (nested loops etc).  I could just emit all these copies at
the beginning of each function but this is suboptimal as non necessarly
they all will be used depending on the execution path, also for
scheduling reasons this would be not good.  The right thing would be to
load these pointers in the first common dominator of each basic block
requiring the use of each function pointer.  I can do it but is not a
good definition of trivial.

Thanks

  Andrea

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

* Re: Correct way to express to the compiler "this does not get clobbered"?
  2020-12-04  9:52       ` Andrea Corallo
@ 2020-12-04 17:27         ` Segher Boessenkool
  2020-12-04 18:16           ` Andrea Corallo
  0 siblings, 1 reply; 27+ messages in thread
From: Segher Boessenkool @ 2020-12-04 17:27 UTC (permalink / raw)
  To: Andrea Corallo; +Cc: stefan, gcc-help

On Fri, Dec 04, 2020 at 10:52:17AM +0100, Andrea Corallo via Gcc-help wrote:
> stefan@franke.ms writes:
> I might open a bug but my understanding is that const is generally
> not used for optimizations.  Am I wrong?

extern const int x = 42;
int f(void) { return x; }

The code generated for f does not load the value for x from memory: it
returns 42 always.


Segher

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

* Re: Correct way to express to the compiler "this does not get clobbered"?
  2020-12-04 17:27         ` Segher Boessenkool
@ 2020-12-04 18:16           ` Andrea Corallo
  2020-12-04 18:33             ` Segher Boessenkool
  0 siblings, 1 reply; 27+ messages in thread
From: Andrea Corallo @ 2020-12-04 18:16 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: stefan, gcc-help

Segher Boessenkool <segher@kernel.crashing.org> writes:

> On Fri, Dec 04, 2020 at 10:52:17AM +0100, Andrea Corallo via Gcc-help wrote:
>> stefan@franke.ms writes:
>> I might open a bug but my understanding is that const is generally
>> not used for optimizations.  Am I wrong?
>
> extern const int x = 42;
> int f(void) { return x; }
>
> The code generated for f does not load the value for x from memory: it
> returns 42 always.

Hi Segher,

Are you suggesting we should treat this as a bug?

  Andrea

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

* Re: Correct way to express to the compiler "this does not get clobbered"?
  2020-12-04 18:16           ` Andrea Corallo
@ 2020-12-04 18:33             ` Segher Boessenkool
  2020-12-04 18:45               ` Andrea Corallo
       [not found]               ` <017701d6ca6d$7dc8dc90$795a95b0$@bebbosoft.de>
  0 siblings, 2 replies; 27+ messages in thread
From: Segher Boessenkool @ 2020-12-04 18:33 UTC (permalink / raw)
  To: Andrea Corallo; +Cc: stefan, gcc-help

On Fri, Dec 04, 2020 at 07:16:45PM +0100, Andrea Corallo via Gcc-help wrote:
> Segher Boessenkool <segher@kernel.crashing.org> writes:
> 
> > On Fri, Dec 04, 2020 at 10:52:17AM +0100, Andrea Corallo via Gcc-help wrote:
> >> stefan@franke.ms writes:
> >> I might open a bug but my understanding is that const is generally
> >> not used for optimizations.  Am I wrong?
> >
> > extern const int x = 42;
> > int f(void) { return x; }
> >
> > The code generated for f does not load the value for x from memory: it
> > returns 42 always.

> Are you suggesting we should treat this as a bug?

Huh?  No, I am just saying that const *is* used for optimisation, with a
dumb simple example.  Remove const from this code and you get different
generated machine code (that does load x from memory always).

If you think you have found a missing optimisation, please make a
self-contained demonstrator for that, and a file a PR?


Segher

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

* Re: Correct way to express to the compiler "this does not get clobbered"?
  2020-12-04 18:33             ` Segher Boessenkool
@ 2020-12-04 18:45               ` Andrea Corallo
       [not found]               ` <017701d6ca6d$7dc8dc90$795a95b0$@bebbosoft.de>
  1 sibling, 0 replies; 27+ messages in thread
From: Andrea Corallo @ 2020-12-04 18:45 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: stefan, gcc-help

Segher Boessenkool <segher@kernel.crashing.org> writes:

> On Fri, Dec 04, 2020 at 07:16:45PM +0100, Andrea Corallo via Gcc-help wrote:
>> Segher Boessenkool <segher@kernel.crashing.org> writes:
>> 
>> > On Fri, Dec 04, 2020 at 10:52:17AM +0100, Andrea Corallo via Gcc-help wrote:
>> >> stefan@franke.ms writes:
>> >> I might open a bug but my understanding is that const is generally
>> >> not used for optimizations.  Am I wrong?
>> >
>> > extern const int x = 42;
>> > int f(void) { return x; }
>> >
>> > The code generated for f does not load the value for x from memory: it
>> > returns 42 always.
>
>> Are you suggesting we should treat this as a bug?
>
> Huh?

Sorry for the miscommunication, with "this" I meant the code of the
original question of this thread.

> No, I am just saying that const *is* used for optimisation, with a
> dumb simple example.  Remove const from this code and you get different
> generated machine code (that does load x from memory always).
>
> If you think you have found a missing optimisation, please make a
> self-contained demonstrator for that, and a file a PR?

All righ I'll do it.

  Andrea

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

* AW: Correct way to express to the compiler "this does not get clobbered"?
       [not found]               ` <017701d6ca6d$7dc8dc90$795a95b0$@bebbosoft.de>
@ 2020-12-04 18:57                 ` Stefan Franke
  2020-12-04 22:52                   ` Andrea Corallo
  0 siblings, 1 reply; 27+ messages in thread
From: Stefan Franke @ 2020-12-04 18:57 UTC (permalink / raw)
  To: gcc-help

> > -----Ursprüngliche Nachricht-----
> > Von: Gcc-help <gcc-help-bounces@gcc.gnu.org> Im Auftrag von Segher
> > Boessenkool
> > Gesendet: Freitag, 4. Dezember 2020 19:33
> > An: Andrea Corallo <andrea.corallo@arm.com>
> > Cc: stefan@franke.ms; gcc-help@gcc.gnu.org
> > Betreff: Re: Correct way to express to the compiler "this does not get
> > clobbered"?
> >
> > On Fri, Dec 04, 2020 at 07:16:45PM +0100, Andrea Corallo via Gcc-help
> wrote:
> > > Segher Boessenkool <segher@kernel.crashing.org> writes:
> > >
> > > > On Fri, Dec 04, 2020 at 10:52:17AM +0100, Andrea Corallo via
> Gcc-help
> > wrote:
> > > >> stefan@franke.ms writes:
> > > >> I might open a bug but my understanding is that const is
> > > >> generally not used for optimizations.  Am I wrong?
> > > >
> > > > extern const int x = 42;
> > > > int f(void) { return x; }
> > > >
> > > > The code generated for f does not load the value for x from memory:
> > > > it returns 42 always.
> >
> > > Are you suggesting we should treat this as a bug?
> >
> > Huh?  No, I am just saying that const *is* used for optimisation, with
> > a
> dumb
> > simple example.  Remove const from this code and you get different
> > generated machine code (that does load x from memory always).
> >
> > If you think you have found a missing optimisation, please make a
> > self- contained demonstrator for that, and a file a PR?
> >
> >
> > Segher

IMHO it's the cprop pass which should get enhanced.

Stefan



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

* Re: AW: Correct way to express to the compiler "this does not get clobbered"?
  2020-12-04 18:57                 ` AW: " Stefan Franke
@ 2020-12-04 22:52                   ` Andrea Corallo
  2020-12-05 14:01                     ` David Brown
  0 siblings, 1 reply; 27+ messages in thread
From: Andrea Corallo @ 2020-12-04 22:52 UTC (permalink / raw)
  To: Stefan Franke; +Cc: gcc-help, stefan

"Stefan Franke" <s.franke@bebbosoft.de> writes:

>> > -----Ursprüngliche Nachricht-----
>> > Von: Gcc-help <gcc-help-bounces@gcc.gnu.org> Im Auftrag von Segher
>> > Boessenkool
>> > Gesendet: Freitag, 4. Dezember 2020 19:33
>> > An: Andrea Corallo <andrea.corallo@arm.com>
>> > Cc: stefan@franke.ms; gcc-help@gcc.gnu.org
>> > Betreff: Re: Correct way to express to the compiler "this does not get
>> > clobbered"?
>> >
>> > On Fri, Dec 04, 2020 at 07:16:45PM +0100, Andrea Corallo via Gcc-help
>> wrote:
>> > > Segher Boessenkool <segher@kernel.crashing.org> writes:
>> > >
>> > > > On Fri, Dec 04, 2020 at 10:52:17AM +0100, Andrea Corallo via
>> Gcc-help
>> > wrote:
>> > > >> stefan@franke.ms writes:
>> > > >> I might open a bug but my understanding is that const is
>> > > >> generally not used for optimizations.  Am I wrong?
>> > > >
>> > > > extern const int x = 42;
>> > > > int f(void) { return x; }
>> > > >
>> > > > The code generated for f does not load the value for x from memory:
>> > > > it returns 42 always.
>> >
>> > > Are you suggesting we should treat this as a bug?
>> >
>> > Huh?  No, I am just saying that const *is* used for optimisation, with
>> > a
>> dumb
>> > simple example.  Remove const from this code and you get different
>> > generated machine code (that does load x from memory always).
>> >
>> > If you think you have found a missing optimisation, please make a
>> > self- contained demonstrator for that, and a file a PR?
>> >
>> >
>> > Segher
>
> IMHO it's the cprop pass which should get enhanced.
>
> Stefan

Hi Stefan,

IIUC declaring a pointer to constant prevents the pointer to be used in
order to modify what is pointing to.

But in this case (the original example) it does not prevent the function
being called to modify that piece of memory (the one pointed by y).

Therefore I believe this is not a bug.

  Andrea

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

* Re: Correct way to express to the compiler "this does not get clobbered"?
  2020-12-03 11:47 Correct way to express to the compiler "this does not get clobbered"? Andrea Corallo
  2020-12-03 12:04 ` Richard Earnshaw
  2020-12-03 18:24 ` David Brown
@ 2020-12-05  8:06 ` Liu Hao
  2 siblings, 0 replies; 27+ messages in thread
From: Liu Hao @ 2020-12-05  8:06 UTC (permalink / raw)
  To: Andrea Corallo, gcc-help; +Cc: nd


[-- Attachment #1.1: Type: text/plain, Size: 1510 bytes --]

在 2020/12/3 下午7:47, Andrea Corallo via Gcc-help 写道:
> Hi all,
> 
> I've a piece of code that reduced looks like this:
> 
> #+begin_src C
> typedef struct {
>   void (*fun_ptr)(void);
> } x_t;
> 
> x_t *x;
> 
> void
> f (void)
> {
>   const x_t const *y = x;
>   for (int i = 0; i < 1000; ++i)
>     y->fun_ptr ();
> }
> #+end_src
> 
> What is the correct way (if any) to express to the compiler that the
> value of y->fun_ptr does not get clobbered by the function call itself
> so the corresponding load to obtain its value can be moved out of the
> loop?


How about:

```c
void
f (void)
{
  int i;

  for (__auto_type p = (     // warning: use of GCC extension
              (i = 0),       // set `i` to zero
              y->fun_ptr);   // warning: abuse of comma operator
           i < 1000; ++i)
    p ();
}
```

You would only ever need one `i` in each function, so it'd not be very complicated. The scope of `p`
is limited to the enclosing `for` statement.

> 
> My understanding is that the const qualifier is more for diagnostic
> reasons and is not sufficient for GCC to make this assumption.  OTOH I
> cannot give 'fun_ptr' the attribute pure as it's not.
> 

`const` may be used for optimization only if it causes an object to be declared `const`. Something
such as `const int x = 42;` is known by the compiler to be immutable, but the result of an
indirection through a pointer might not be.



-- 
Best regards,
LH_Mouse


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: AW: Correct way to express to the compiler "this does not get clobbered"?
  2020-12-04 22:52                   ` Andrea Corallo
@ 2020-12-05 14:01                     ` David Brown
  2020-12-05 14:17                       ` AW: " Stefan Franke
  2020-12-05 17:29                       ` Andrea Corallo
  0 siblings, 2 replies; 27+ messages in thread
From: David Brown @ 2020-12-05 14:01 UTC (permalink / raw)
  To: Andrea Corallo, Stefan Franke; +Cc: gcc-help, stefan

On 04/12/2020 23:52, Andrea Corallo via Gcc-help wrote:
> "Stefan Franke" <s.franke@bebbosoft.de> writes:
> 
>>>> -----Ursprüngliche Nachricht-----
>>>> Von: Gcc-help <gcc-help-bounces@gcc.gnu.org> Im Auftrag von Segher
>>>> Boessenkool
>>>> Gesendet: Freitag, 4. Dezember 2020 19:33
>>>> An: Andrea Corallo <andrea.corallo@arm.com>
>>>> Cc: stefan@franke.ms; gcc-help@gcc.gnu.org
>>>> Betreff: Re: Correct way to express to the compiler "this does not get
>>>> clobbered"?
>>>>
>>>> On Fri, Dec 04, 2020 at 07:16:45PM +0100, Andrea Corallo via Gcc-help
>>> wrote:
>>>>> Segher Boessenkool <segher@kernel.crashing.org> writes:
>>>>>
>>>>>> On Fri, Dec 04, 2020 at 10:52:17AM +0100, Andrea Corallo via
>>> Gcc-help
>>>> wrote:
>>>>>>> stefan@franke.ms writes:
>>>>>>> I might open a bug but my understanding is that const is
>>>>>>> generally not used for optimizations.  Am I wrong?
>>>>>>
>>>>>> extern const int x = 42;
>>>>>> int f(void) { return x; }
>>>>>>
>>>>>> The code generated for f does not load the value for x from memory:
>>>>>> it returns 42 always.
>>>>
>>>>> Are you suggesting we should treat this as a bug?
>>>>
>>>> Huh?  No, I am just saying that const *is* used for optimisation, with
>>>> a
>>> dumb
>>>> simple example.  Remove const from this code and you get different
>>>> generated machine code (that does load x from memory always).
>>>>
>>>> If you think you have found a missing optimisation, please make a
>>>> self- contained demonstrator for that, and a file a PR?
>>>>
>>>>
>>>> Segher
>>
>> IMHO it's the cprop pass which should get enhanced.
>>
>> Stefan
> 
> Hi Stefan,
> 
> IIUC declaring a pointer to constant prevents the pointer to be used in
> order to modify what is pointing to.
> 
> But in this case (the original example) it does not prevent the function
> being called to modify that piece of memory (the one pointed by y).
> 
> Therefore I believe this is not a bug.
> 
>   Andrea
> 

That is, AFAIUI, correct.

The case of "extern const int x = 42;" above is very different - here
the object "x" is /defined/ as a const, and therefore the compiler knows
it cannot ever be changed (or rather, any attempts to change it are
undefined behaviour).  But if you make a const pointer to something, you
are merely saying that /you/ won't change the object (via that pointer).
 There is no way in C to say that there can't be anything else that
changes the object.



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

* AW: AW: Correct way to express to the compiler "this does not get clobbered"?
  2020-12-05 14:01                     ` David Brown
@ 2020-12-05 14:17                       ` Stefan Franke
  2020-12-05 18:10                         ` Andrea Corallo
  2020-12-05 19:03                         ` David Brown
  2020-12-05 17:29                       ` Andrea Corallo
  1 sibling, 2 replies; 27+ messages in thread
From: Stefan Franke @ 2020-12-05 14:17 UTC (permalink / raw)
  To: gcc-help



> -----Ursprüngliche Nachricht-----
> Von: David Brown <david.brown@hesbynett.no>
> Gesendet: Samstag, 5. Dezember 2020 15:01
> An: Andrea Corallo <andrea.corallo@arm.com>; Stefan Franke
> <s.franke@bebbosoft.de>
> Cc: gcc-help@gcc.gnu.org; stefan@franke.ms
> Betreff: Re: AW: Correct way to express to the compiler "this does not get
> clobbered"?
> 
> On 04/12/2020 23:52, Andrea Corallo via Gcc-help wrote:
> > "Stefan Franke" <s.franke@bebbosoft.de> writes:
> >
> >>>> -----Ursprüngliche Nachricht-----
> >>>> Von: Gcc-help <gcc-help-bounces@gcc.gnu.org> Im Auftrag von
> Segher
> >>>> Boessenkool
> >>>> Gesendet: Freitag, 4. Dezember 2020 19:33
> >>>> An: Andrea Corallo <andrea.corallo@arm.com>
> >>>> Cc: stefan@franke.ms; gcc-help@gcc.gnu.org
> >>>> Betreff: Re: Correct way to express to the compiler "this does not
> >>>> get clobbered"?
> >>>>
> >>>> On Fri, Dec 04, 2020 at 07:16:45PM +0100, Andrea Corallo via
> >>>> Gcc-help
> >>> wrote:
> >>>>> Segher Boessenkool <segher@kernel.crashing.org> writes:
> >>>>>
> >>>>>> On Fri, Dec 04, 2020 at 10:52:17AM +0100, Andrea Corallo via
> >>> Gcc-help
> >>>> wrote:
> >>>>>>> stefan@franke.ms writes:
> >>>>>>> I might open a bug but my understanding is that const is
> >>>>>>> generally not used for optimizations.  Am I wrong?
> >>>>>>
> >>>>>> extern const int x = 42;
> >>>>>> int f(void) { return x; }
> >>>>>>
> >>>>>> The code generated for f does not load the value for x from
> memory:
> >>>>>> it returns 42 always.
> >>>>
> >>>>> Are you suggesting we should treat this as a bug?
> >>>>
> >>>> Huh?  No, I am just saying that const *is* used for optimisation,
> >>>> with a
> >>> dumb
> >>>> simple example.  Remove const from this code and you get different
> >>>> generated machine code (that does load x from memory always).
> >>>>
> >>>> If you think you have found a missing optimisation, please make a
> >>>> self- contained demonstrator for that, and a file a PR?
> >>>>
> >>>>
> >>>> Segher
> >>
> >> IMHO it's the cprop pass which should get enhanced.
> >>
> >> Stefan
> >
> > Hi Stefan,
> >
> > IIUC declaring a pointer to constant prevents the pointer to be used
> > in order to modify what is pointing to.
> >
> > But in this case (the original example) it does not prevent the
> > function being called to modify that piece of memory (the one pointed by
> y).
> >
> > Therefore I believe this is not a bug.
> >
> >   Andrea
> >
> 
> That is, AFAIUI, correct.
> 
> The case of "extern const int x = 42;" above is very different - here the object
> "x" is /defined/ as a const, and therefore the compiler knows it cannot ever
> be changed (or rather, any attempts to change it are undefined behaviour).
> But if you make a const pointer to something, you are merely saying that
> /you/ won't change the object (via that pointer).
>  There is no way in C to say that there can't be anything else that changes the
> object.
> 

I disagree:

typedef struct {
   void (* const fun_ptr)(void);
   const long x;
 } x_t;

Declares that fun_ptr and x both are const and cannot change. So these const value can safely be propagated out of loops if the pointer to is also const and can't change. The current compiler simply ignores that knowledge.

I cannot judge if this is a bug or a not implemented feature. But in the current implementation only the c/c++ parser cares about const whereas the compiler passes do not check constness.

Regards

Stefan





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

* Re: AW: Correct way to express to the compiler "this does not get clobbered"?
  2020-12-05 14:01                     ` David Brown
  2020-12-05 14:17                       ` AW: " Stefan Franke
@ 2020-12-05 17:29                       ` Andrea Corallo
  2020-12-05 19:07                         ` David Brown
  1 sibling, 1 reply; 27+ messages in thread
From: Andrea Corallo @ 2020-12-05 17:29 UTC (permalink / raw)
  To: David Brown; +Cc: Stefan Franke, gcc-help, stefan

David Brown <david.brown@hesbynett.no> writes:

[...]

>  There is no way in C to say that there can't be anything else that
> changes the object.

I think it would be nice to have, if not in C at least in GCC.

  Andrea

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

* Re: AW: AW: Correct way to express to the compiler "this does not get clobbered"?
  2020-12-05 14:17                       ` AW: " Stefan Franke
@ 2020-12-05 18:10                         ` Andrea Corallo
  2020-12-07 22:27                           ` Segher Boessenkool
  2020-12-05 19:03                         ` David Brown
  1 sibling, 1 reply; 27+ messages in thread
From: Andrea Corallo @ 2020-12-05 18:10 UTC (permalink / raw)
  To: Stefan Franke; +Cc: gcc-help, stefan

"Stefan Franke" <s.franke@bebbosoft.de> writes:

[...]

> I disagree:
>
> typedef struct {
>    void (* const fun_ptr)(void);
>    const long x;
>  } x_t;
>
> Declares that fun_ptr and x both are const and cannot change. So these const value can safely be propagated out of loops if the pointer to is also const and can't change. The current compiler simply ignores that knowledge.
>
> I cannot judge if this is a bug or a not implemented feature. But in the current implementation only the c/c++ parser cares about const whereas the compiler passes do not check constness.

You might be right if you change the code this way, but to begin with
how do you set 'fun_ptr' if the only way to access it is through a
pointer to const?  I suspect this is not very much a realistic case.

  Andrea

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

* Re: AW: AW: Correct way to express to the compiler "this does not get clobbered"?
  2020-12-05 14:17                       ` AW: " Stefan Franke
  2020-12-05 18:10                         ` Andrea Corallo
@ 2020-12-05 19:03                         ` David Brown
  2020-12-06 11:29                           ` AW: " Stefan Franke
  1 sibling, 1 reply; 27+ messages in thread
From: David Brown @ 2020-12-05 19:03 UTC (permalink / raw)
  To: stefan, gcc-help

On 05/12/2020 15:17, Stefan Franke wrote:
> 
> 
>> -----Ursprüngliche Nachricht-----
>> Von: David Brown <david.brown@hesbynett.no>
>> Gesendet: Samstag, 5. Dezember 2020 15:01
>> An: Andrea Corallo <andrea.corallo@arm.com>; Stefan Franke
>> <s.franke@bebbosoft.de>
>> Cc: gcc-help@gcc.gnu.org; stefan@franke.ms
>> Betreff: Re: AW: Correct way to express to the compiler "this does not get
>> clobbered"?
>>
>> On 04/12/2020 23:52, Andrea Corallo via Gcc-help wrote:
>>> "Stefan Franke" <s.franke@bebbosoft.de> writes:
>>>
>>>>>> -----Ursprüngliche Nachricht-----
>>>>>> Von: Gcc-help <gcc-help-bounces@gcc.gnu.org> Im Auftrag von
>> Segher
>>>>>> Boessenkool
>>>>>> Gesendet: Freitag, 4. Dezember 2020 19:33
>>>>>> An: Andrea Corallo <andrea.corallo@arm.com>
>>>>>> Cc: stefan@franke.ms; gcc-help@gcc.gnu.org
>>>>>> Betreff: Re: Correct way to express to the compiler "this does not
>>>>>> get clobbered"?
>>>>>>
>>>>>> On Fri, Dec 04, 2020 at 07:16:45PM +0100, Andrea Corallo via
>>>>>> Gcc-help
>>>>> wrote:
>>>>>>> Segher Boessenkool <segher@kernel.crashing.org> writes:
>>>>>>>
>>>>>>>> On Fri, Dec 04, 2020 at 10:52:17AM +0100, Andrea Corallo via
>>>>> Gcc-help
>>>>>> wrote:
>>>>>>>>> stefan@franke.ms writes:
>>>>>>>>> I might open a bug but my understanding is that const is
>>>>>>>>> generally not used for optimizations.  Am I wrong?
>>>>>>>>
>>>>>>>> extern const int x = 42;
>>>>>>>> int f(void) { return x; }
>>>>>>>>
>>>>>>>> The code generated for f does not load the value for x from
>> memory:
>>>>>>>> it returns 42 always.
>>>>>>
>>>>>>> Are you suggesting we should treat this as a bug?
>>>>>>
>>>>>> Huh?  No, I am just saying that const *is* used for optimisation,
>>>>>> with a
>>>>> dumb
>>>>>> simple example.  Remove const from this code and you get different
>>>>>> generated machine code (that does load x from memory always).
>>>>>>
>>>>>> If you think you have found a missing optimisation, please make a
>>>>>> self- contained demonstrator for that, and a file a PR?
>>>>>>
>>>>>>
>>>>>> Segher
>>>>
>>>> IMHO it's the cprop pass which should get enhanced.
>>>>
>>>> Stefan
>>>
>>> Hi Stefan,
>>>
>>> IIUC declaring a pointer to constant prevents the pointer to be used
>>> in order to modify what is pointing to.
>>>
>>> But in this case (the original example) it does not prevent the
>>> function being called to modify that piece of memory (the one pointed by
>> y).
>>>
>>> Therefore I believe this is not a bug.
>>>
>>>   Andrea
>>>
>>
>> That is, AFAIUI, correct.
>>
>> The case of "extern const int x = 42;" above is very different - here the object
>> "x" is /defined/ as a const, and therefore the compiler knows it cannot ever
>> be changed (or rather, any attempts to change it are undefined behaviour).
>> But if you make a const pointer to something, you are merely saying that
>> /you/ won't change the object (via that pointer).
>>  There is no way in C to say that there can't be anything else that changes the
>> object.
>>
> 
> I disagree:
> 
> typedef struct {
>    void (* const fun_ptr)(void);
>    const long x;
>  } x_t;
> 
> Declares that fun_ptr and x both are const and cannot change. So these const value can safely be propagated out of loops if the pointer to is also const and can't change. The current compiler simply ignores that knowledge.
> 
> I cannot judge if this is a bug or a not implemented feature. But in the current implementation only the c/c++ parser cares about const whereas the compiler passes do not check constness.
> 
> Regards
> 
> Stefan
> 

Pointer declarations cannot tell the compiler that something never
changes.  All you can do with a pointer declaration is promise that
/you/ will not change the object, at least not via that declaration.

This is because you can assign a pointer-to-const to point to a
non-const object.  The "true" constness of an object comes from its
definition, not from how you use it.


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

* Re: AW: Correct way to express to the compiler "this does not get clobbered"?
  2020-12-05 17:29                       ` Andrea Corallo
@ 2020-12-05 19:07                         ` David Brown
  2020-12-06  9:22                           ` Jonathan Wakely
  0 siblings, 1 reply; 27+ messages in thread
From: David Brown @ 2020-12-05 19:07 UTC (permalink / raw)
  To: Andrea Corallo; +Cc: gcc-help, stefan, Stefan Franke

On 05/12/2020 18:29, Andrea Corallo via Gcc-help wrote:
> David Brown <david.brown@hesbynett.no> writes:
> 
> [...]
> 
>>  There is no way in C to say that there can't be anything else that
>> changes the object.
> 
> I think it would be nice to have, if not in C at least in GCC.
> 
>   Andrea
> 

Agreed.  But I think there are so many possible things about constness
that it would be nice to have, that it could quickly get out of hand.

I'd really like a way to tell the compiler that a given object gets set
once during some early function in the program, and can never change
after that.  But I can't think of any good syntax for that.


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

* Re: AW: Correct way to express to the compiler "this does not get clobbered"?
  2020-12-05 19:07                         ` David Brown
@ 2020-12-06  9:22                           ` Jonathan Wakely
  0 siblings, 0 replies; 27+ messages in thread
From: Jonathan Wakely @ 2020-12-06  9:22 UTC (permalink / raw)
  To: David Brown; +Cc: Andrea Corallo, gcc-help, stefan, Stefan Franke

On Sat, 5 Dec 2020, 19:08 David Brown, <david.brown@hesbynett.no> wrote:

> On 05/12/2020 18:29, Andrea Corallo via Gcc-help wrote:
> > David Brown <david.brown@hesbynett.no> writes:
> >
> > [...]
> >
> >>  There is no way in C to say that there can't be anything else that
> >> changes the object.
> >
> > I think it would be nice to have, if not in C at least in GCC.
> >
> >   Andrea
> >
>
> Agreed.  But I think there are so many possible things about constness
> that it would be nice to have, that it could quickly get out of hand.
>
> I'd really like a way to tell the compiler that a given object gets set
> once during some early function in the program, and can never change
> after that.  But I can't think of any good syntax for that.
>

An attribute on the assignment statement (or function) that sets it could
say it's the last write to the object.

That seems appropriate for an attribute, since it's only an optimisation
hint and a conforming compiler could choose to ignore the hint without
changing the meaning of the code. (That's the rule of thumb for whether to
use [[attribute]] syntax in ISO C++).

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

* AW: AW: AW: Correct way to express to the compiler "this does not get clobbered"?
  2020-12-05 19:03                         ` David Brown
@ 2020-12-06 11:29                           ` Stefan Franke
  0 siblings, 0 replies; 27+ messages in thread
From: Stefan Franke @ 2020-12-06 11:29 UTC (permalink / raw)
  To: gcc-help



> -----Ursprüngliche Nachricht-----
> Von: David Brown <david.brown@hesbynett.no>
> Gesendet: Samstag, 5. Dezember 2020 20:03
> An: stefan@franke.ms; gcc-help@gcc.gnu.org
> Betreff: Re: AW: AW: Correct way to express to the compiler "this does not
> get clobbered"?
> 
> On 05/12/2020 15:17, Stefan Franke wrote:
> >
> >
> >> -----Ursprüngliche Nachricht-----
> >> Von: David Brown <david.brown@hesbynett.no>
> >> Gesendet: Samstag, 5. Dezember 2020 15:01
> >> An: Andrea Corallo <andrea.corallo@arm.com>; Stefan Franke
> >> <s.franke@bebbosoft.de>
> >> Cc: gcc-help@gcc.gnu.org; stefan@franke.ms
> >> Betreff: Re: AW: Correct way to express to the compiler "this does
> >> not get clobbered"?
> >>
> >> On 04/12/2020 23:52, Andrea Corallo via Gcc-help wrote:
> >>> "Stefan Franke" <s.franke@bebbosoft.de> writes:
> >>>
> >>>>>> -----Ursprüngliche Nachricht-----
> >>>>>> Von: Gcc-help <gcc-help-bounces@gcc.gnu.org> Im Auftrag von
> >> Segher
> >>>>>> Boessenkool
> >>>>>> Gesendet: Freitag, 4. Dezember 2020 19:33
> >>>>>> An: Andrea Corallo <andrea.corallo@arm.com>
> >>>>>> Cc: stefan@franke.ms; gcc-help@gcc.gnu.org
> >>>>>> Betreff: Re: Correct way to express to the compiler "this does
> >>>>>> not get clobbered"?
> >>>>>>
> >>>>>> On Fri, Dec 04, 2020 at 07:16:45PM +0100, Andrea Corallo via
> >>>>>> Gcc-help
> >>>>> wrote:
> >>>>>>> Segher Boessenkool <segher@kernel.crashing.org> writes:
> >>>>>>>
> >>>>>>>> On Fri, Dec 04, 2020 at 10:52:17AM +0100, Andrea Corallo via
> >>>>> Gcc-help
> >>>>>> wrote:
> >>>>>>>>> stefan@franke.ms writes:
> >>>>>>>>> I might open a bug but my understanding is that const is
> >>>>>>>>> generally not used for optimizations.  Am I wrong?
> >>>>>>>>
> >>>>>>>> extern const int x = 42;
> >>>>>>>> int f(void) { return x; }
> >>>>>>>>
> >>>>>>>> The code generated for f does not load the value for x from
> >> memory:
> >>>>>>>> it returns 42 always.
> >>>>>>
> >>>>>>> Are you suggesting we should treat this as a bug?
> >>>>>>
> >>>>>> Huh?  No, I am just saying that const *is* used for optimisation,
> >>>>>> with a
> >>>>> dumb
> >>>>>> simple example.  Remove const from this code and you get
> >>>>>> different generated machine code (that does load x from memory
> always).
> >>>>>>
> >>>>>> If you think you have found a missing optimisation, please make a
> >>>>>> self- contained demonstrator for that, and a file a PR?
> >>>>>>
> >>>>>>
> >>>>>> Segher
> >>>>
> >>>> IMHO it's the cprop pass which should get enhanced.
> >>>>
> >>>> Stefan
> >>>
> >>> Hi Stefan,
> >>>
> >>> IIUC declaring a pointer to constant prevents the pointer to be used
> >>> in order to modify what is pointing to.
> >>>
> >>> But in this case (the original example) it does not prevent the
> >>> function being called to modify that piece of memory (the one
> >>> pointed by
> >> y).
> >>>
> >>> Therefore I believe this is not a bug.
> >>>
> >>>   Andrea
> >>>
> >>
> >> That is, AFAIUI, correct.
> >>
> >> The case of "extern const int x = 42;" above is very different - here
> >> the object "x" is /defined/ as a const, and therefore the compiler
> >> knows it cannot ever be changed (or rather, any attempts to change it
> >> are undefined behaviour).
> >> But if you make a const pointer to something, you are merely saying
> >> that /you/ won't change the object (via that pointer).
> >>  There is no way in C to say that there can't be anything else that
> >> changes the object.
> >>
> >
> > I disagree:
> >
> > typedef struct {
> >    void (* const fun_ptr)(void);
> >    const long x;
> >  } x_t;
> >
> > Declares that fun_ptr and x both are const and cannot change. So these
> > const value can safely be propagated out of loops if the pointer to is
> > also const and can't change. The current compiler simply ignores that
> > knowledge.
> >
> > I cannot judge if this is a bug or a not implemented feature. But in
> > the current implementation only the c/c++ parser cares about const
> > whereas the compiler passes do not check constness.
> >
> > Regards
> >
> > Stefan
> >
> 
> Pointer declarations cannot tell the compiler that something never changes.
> All you can do with a pointer declaration is promise that /you/ will not change
> the object, at least not via that declaration.
> 
> This is because you can assign a pointer-to-const to point to a non-const
> object.  The "true" constness of an object comes from its definition, not from
> how you use it.


If you look at the type you'll notice the const qualifier.

With two changes to expr.c that info can be used and the compiler pulls it out of the loop.

One here to mark the const pointer as unchanging:

      if (exp && exp->ssa_name.typed.type->base.constant_flag)
	decl_rtl->unchanging = 1;
...
      /* Show we haven't gotten RTL for this yet.  */

And another one there :

	if (MEM_P (op0) && exp->base.code == COMPONENT_REF && XEXP (op0, 0)->unchanging
	    && ((exp)->exp.operands[1])->base.readonly_flag)
	  {
	    if (op0 == orig_op0)
	      op0 = copy_rtx (op0);

	    MEM_READONLY_P(op0) = 1;
	  }
...
	/* In cases where an aligned union has an unaligned object

Marks the mem as read only. And the code gets enhanced.

That's not fully correct, and just a hack, but it shows that there is present information which could be used to enhance the code generation.


/Cheers

Stefan



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

* Re: AW: AW: Correct way to express to the compiler "this does not get clobbered"?
  2020-12-05 18:10                         ` Andrea Corallo
@ 2020-12-07 22:27                           ` Segher Boessenkool
  0 siblings, 0 replies; 27+ messages in thread
From: Segher Boessenkool @ 2020-12-07 22:27 UTC (permalink / raw)
  To: Andrea Corallo; +Cc: Stefan Franke, gcc-help, stefan

On Sat, Dec 05, 2020 at 07:10:08PM +0100, Andrea Corallo via Gcc-help wrote:
> "Stefan Franke" <s.franke@bebbosoft.de> writes:
> > typedef struct {
> >    void (* const fun_ptr)(void);
> >    const long x;
> >  } x_t;
> >
> > Declares that fun_ptr and x both are const and cannot change. So these const value can safely be propagated out of loops if the pointer to is also const and can't change. The current compiler simply ignores that knowledge.
> >
> > I cannot judge if this is a bug or a not implemented feature. But in the current implementation only the c/c++ parser cares about const whereas the compiler passes do not check constness.
> 
> You might be right if you change the code this way, but to begin with
> how do you set 'fun_ptr' if the only way to access it is through a
> pointer to const?  I suspect this is not very much a realistic case.

void f(void)
{
	x_t x = { .x = 42; .fun_ptr = f; };

...

etc.

The variable dies when the function returns, but other than that this
works fine.


Segher

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

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

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-03 11:47 Correct way to express to the compiler "this does not get clobbered"? Andrea Corallo
2020-12-03 12:04 ` Richard Earnshaw
2020-12-03 12:28   ` Andrea Corallo
2020-12-03 13:06     ` Richard Earnshaw
2020-12-03 13:40       ` Andrea Corallo
2020-12-03 18:24 ` David Brown
2020-12-03 23:00   ` Andrea Corallo
2020-12-04  7:23     ` stefan
2020-12-04  9:52       ` Andrea Corallo
2020-12-04 17:27         ` Segher Boessenkool
2020-12-04 18:16           ` Andrea Corallo
2020-12-04 18:33             ` Segher Boessenkool
2020-12-04 18:45               ` Andrea Corallo
     [not found]               ` <017701d6ca6d$7dc8dc90$795a95b0$@bebbosoft.de>
2020-12-04 18:57                 ` AW: " Stefan Franke
2020-12-04 22:52                   ` Andrea Corallo
2020-12-05 14:01                     ` David Brown
2020-12-05 14:17                       ` AW: " Stefan Franke
2020-12-05 18:10                         ` Andrea Corallo
2020-12-07 22:27                           ` Segher Boessenkool
2020-12-05 19:03                         ` David Brown
2020-12-06 11:29                           ` AW: " Stefan Franke
2020-12-05 17:29                       ` Andrea Corallo
2020-12-05 19:07                         ` David Brown
2020-12-06  9:22                           ` Jonathan Wakely
2020-12-04  8:27     ` David Brown
2020-12-04 10:05       ` Andrea Corallo
2020-12-05  8:06 ` Liu Hao

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).