public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* a question about const and pure functions.
@ 2004-11-10 19:14 Kenneth Zadeck
  2004-11-10 23:35 ` Geoffrey Keating
  0 siblings, 1 reply; 20+ messages in thread
From: Kenneth Zadeck @ 2004-11-10 19:14 UTC (permalink / raw)
  To: GCC Mailing List, Geoffrey Keating, Novillo, Diego, Berlin, Daniel

Do we mark functions being const or pure (TREE_READONLY or DECL_IS_PURE) 
based on some external standard definition or are these defined any way 
that the gcc community feels is good?  

I am in the process of moving the code that does this analysis so that 
it is done very early and at once for the entire compilation unit.  
There appear to be a few minor bugs in the code as well as a few missed 
opportinities.  But before I was going to make any changes, I was 
wondering if there was any better standard of definition beyond what is 
defined in doc/extend.texi.

Kenny

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

* Re: a question about const and pure functions.
  2004-11-10 19:14 a question about const and pure functions Kenneth Zadeck
@ 2004-11-10 23:35 ` Geoffrey Keating
  2004-11-11 15:04   ` Kenneth Zadeck
  0 siblings, 1 reply; 20+ messages in thread
From: Geoffrey Keating @ 2004-11-10 23:35 UTC (permalink / raw)
  To: Kenneth Zadeck; +Cc: Novillo, Diego, GCC Mailing List, Berlin, Daniel

[-- Attachment #1: Type: text/plain, Size: 935 bytes --]


On 10/11/2004, at 11:06 AM, Kenneth Zadeck wrote:

> Do we mark functions being const or pure (TREE_READONLY or 
> DECL_IS_PURE) based on some external standard definition or are these 
> defined any way that the gcc community feels is good?

There are backwards compatibility issues, of course, but they're not 
based on any particular standard.

> I am in the process of moving the code that does this analysis so that 
> it is done very early and at once for the entire compilation unit.  
> There appear to be a few minor bugs in the code as well as a few 
> missed opportinities.  But before I was going to make any changes, I 
> was wondering if there was any better standard of definition beyond 
> what is defined in doc/extend.texi.

No, I don't think there's anything beyond the documentation.  I think 
the documentation could do with being made more precise, but it's not 
very bad.

-- 
Geoff Keating <geoffk@apple.com>


[-- Attachment #2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 2408 bytes --]

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

* Re: a question about const and pure functions.
  2004-11-10 23:35 ` Geoffrey Keating
@ 2004-11-11 15:04   ` Kenneth Zadeck
  2004-11-11 15:07     ` Roger Sayle
                       ` (2 more replies)
  0 siblings, 3 replies; 20+ messages in thread
From: Kenneth Zadeck @ 2004-11-11 15:04 UTC (permalink / raw)
  To: Geoffrey Keating; +Cc: Novillo, Diego, GCC Mailing List, Berlin, Daniel



Geoffrey Keating wrote:

>
> On 10/11/2004, at 11:06 AM, Kenneth Zadeck wrote:
>
>> Do we mark functions being const or pure (TREE_READONLY or 
>> DECL_IS_PURE) based on some external standard definition or are these 
>> defined any way that the gcc community feels is good?
>
>
> There are backwards compatibility issues, of course, but they're not 
> based on any particular standard.
>
>> I am in the process of moving the code that does this analysis so 
>> that it is done very early and at once for the entire compilation 
>> unit.  There appear to be a few minor bugs in the code as well as a 
>> few missed opportinities.  But before I was going to make any 
>> changes, I was wondering if there was any better standard of 
>> definition beyond what is defined in doc/extend.texi.
>
>
> No, I don't think there's anything beyond the documentation.  I think 
> the documentation could do with being made more precise, but it's not 
> very bad.
>
The minor bugs and missed opportunities are associated with the code 
that controls the pure can call pure and const and const can call const 
put const cannot call pure.  The code is messed up in both ways.  Some 
const calling pures are allowed (if the pure has no args) and some pure 
calls consts are rejected.  These could be fixed in the existing code, 
but there are other issues with performing this analysis at the rtl level.

The extensions that I want to add are:

1) allow const to access memory if the memory is a constant, i.e. if you 
have a readonly static with a decl initial that satisfies  
is_gimple_min_invariant (), such a reference need not be treated 
differently than referencing a "5".

2) move the processing earlier so that it is available to the rest of 
the compiler.

3) allow for recursive and mutually recursive pure and const functions.

4) eventually to allow some loops (if they can be proven to be finite) 
rather than just looking for back edges in the cfg. We have this 
analysis in the compiler, we should be allowed to use the info here.

The hope here is that with the exception of setting errno, that most 
small table driven mathematical functions would fall into one of these  
categories.

Kenny

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

* Re: a question about const and pure functions.
  2004-11-11 15:04   ` Kenneth Zadeck
@ 2004-11-11 15:07     ` Roger Sayle
  2004-11-11 15:17       ` Daniel Berlin
                         ` (3 more replies)
  2004-11-11 21:40     ` Geoffrey Keating
  2004-11-25 13:22     ` Jan Hubicka
  2 siblings, 4 replies; 20+ messages in thread
From: Roger Sayle @ 2004-11-11 15:07 UTC (permalink / raw)
  To: Kenneth Zadeck; +Cc: Novillo, Diego, GCC Mailing List, Berlin, Daniel


On Thu, 11 Nov 2004, Kenneth Zadeck wrote:
> The minor bugs and missed opportunities are associated with the code
> that controls the pure can call pure and const and const can call const
> put const cannot call pure.  The code is messed up in both ways.  Some
> const calling pures are allowed (if the pure has no args) and some pure
> calls consts are rejected.  These could be fixed in the existing code,
> but there are other issues with performing this analysis at the rtl level.


A "const" call has no side-effects and its results depend purely on the
values of its arguments.  This closely follows the mathematical notion
of a "function".  A "pure" call has no side-effects, but in addition to
it's arguments may depend upon the memory/global variables of the system.

Examples of relevant optimizations include (i) if the result of a const
or a pure function is ignored, then the call to that function may be
completely eliminated, (ii) two calls to a const function with identical
arguments are guaranteed to produce the same result, and the second
invokation may be CSE'd, (iii) two calls to a pure function with identical
arguments are only guaranteed to produce the same results if there are
no write's to memory (that are visible to the function) between the two
calls.  In this case, the second invocation may be CSE'd.  (iv) Writes
to global variables need no be committed (i.e. moved after) calls to
const functions.


Now consider the example:

int var;

int foo()
{
  return var;
}

int bar()
{
  return foo();
}


In this example, foo is "pure", has no side-effects but reads from
global memory.   Although bar only calls "foo" with no arguments, it
still can not be classified as "const".

But contrary to your assertion bar is not "const" as it calls "foo".  The
semantics a "necessary" but no sufficient requirement of a "const"
function is that it only calls "const" functions. Likewise, a requirement
of a "pure" functions is that it only calls "pure" or "const" functions.

The optimization that might be confusing this is that if the result of
the call to foo() in "bar" is ignored, then it effectively doesn't exist.
i.e. in

int bar()
{
  foo();
  return 0;
}

bar() is "const".



> The extensions that I want to add are:
>
> 1) allow const to access memory if the memory is a constant, i.e. if you
> have a readonly static with a decl initial that satisfies
> is_gimple_min_invariant (), such a reference need not be treated
> differently than referencing a "5".

This is a valid and reasonable improvement.


> 4) eventually to allow some loops (if they can be proven to be finite)
> rather than just looking for back edges in the cfg. We have this
> analysis in the compiler, we should be allowed to use the info here.

This is also good, but seems to clash with your hopes of moving
pure/const analysis earlier.


> 3) allow for recursive and mutually recursive pure and const functions.

With the caveat that there can't be mutual recursion between a pure and
a const function [two pure functions may be mutually recursive, and two
const functions may be mutually recursive, but a const function can't
invoke a pure function.  Obviously both pure and const functions can be
recursive.]


> The hope here is that with the exception of setting errno, that most
> small table driven mathematical functions would fall into one of these
> categories.

This is only an issue when not using -ffast-math, which is a reasonable
requirement for any kind of performance benchmarking.  I would suggest
that we could add a "clobber_errno" attribute to the builtin math
functions to provide the compiler a hint that they are const except for
clobbers of errno.  Unfortunately, very few of GCC's backends actually
define GEN_ERRNO_RTX, so identify which memory location is actually
clobbered in the presence of macros in errno.h and thread local storage
is almost impossible.

Additionally, GCC models the "current floating point rounding" direction
by modelling some math functions, such as rint, as pure instead of const.
Hence, upon calling an unknown side-effecting function, GCC can no longer
assume that calls to rint with identical arguments produces the same
result.



I hope this helps, but perhaps I misunderstand your thoughts on const
functions calling pure functions.

Roger
--

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

* Re: a question about const and pure functions.
  2004-11-11 15:07     ` Roger Sayle
@ 2004-11-11 15:17       ` Daniel Berlin
  2004-11-11 15:17       ` Daniel Berlin
                         ` (2 subsequent siblings)
  3 siblings, 0 replies; 20+ messages in thread
From: Daniel Berlin @ 2004-11-11 15:17 UTC (permalink / raw)
  To: Roger Sayle; +Cc: Kenneth Zadeck, Novillo, Diego, GCC Mailing List


On Nov 11, 2004, at 8:57 AM, Roger Sayle wrote:




>
> On Thu, 11 Nov 2004, Kenneth Zadeck wrote:
>
>
>
>> 4) eventually to allow some loops (if they can be proven to be finite)
>> rather than just looking for back edges in the cfg. We have this
>> analysis in the compiler, we should be allowed to use the info here.
>>
>>
>
> This is also good, but seems to clash with your hopes of moving
> pure/const analysis earlier.
>
>
The tree-profiling branch will soon have a CFG at the cgraph level, so 
this isn't really a problem for a given definition of "some
loops" :)

--Dan


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

* Re: a question about const and pure functions.
  2004-11-11 15:07     ` Roger Sayle
  2004-11-11 15:17       ` Daniel Berlin
@ 2004-11-11 15:17       ` Daniel Berlin
  2004-11-11 17:20       ` Geert Bosch
  2004-11-11 19:04       ` Tom Tromey
  3 siblings, 0 replies; 20+ messages in thread
From: Daniel Berlin @ 2004-11-11 15:17 UTC (permalink / raw)
  To: Roger Sayle; +Cc: Kenneth Zadeck, Novillo, Diego, GCC Mailing List

>
>
>> 4) eventually to allow some loops (if they can be proven to be finite)
>> rather than just looking for back edges in the cfg. We have this
>> analysis in the compiler, we should be allowed to use the info here.
>
> This is also good, but seems to clash with your hopes of moving
> pure/const analysis earlier.

The tree-profiling branch (and other branches), will soon have a CFG at 
the cgraph level, so for some definition of "some loops", we could do 
this.

I believe Kenny is assuming this CFG at the cgraph level when he talks 
about doing this.

--Dan

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

* Re: a question about const and pure functions.
  2004-11-11 15:07     ` Roger Sayle
  2004-11-11 15:17       ` Daniel Berlin
  2004-11-11 15:17       ` Daniel Berlin
@ 2004-11-11 17:20       ` Geert Bosch
  2004-11-11 17:45         ` Roger Sayle
  2004-11-11 19:04       ` Tom Tromey
  3 siblings, 1 reply; 20+ messages in thread
From: Geert Bosch @ 2004-11-11 17:20 UTC (permalink / raw)
  To: Roger Sayle
  Cc: Novillo, Diego, Kenneth Zadeck, GCC Mailing List, Berlin, Daniel


On Nov 11, 2004, at 08:57, Roger Sayle wrote:
> A "const" call has no side-effects and its results depend purely on the
> values of its arguments.  This closely follows the mathematical notion
> of a "function".  A "pure" call has no side-effects, but in addition to
> it's arguments may depend upon the memory/global variables of the 
> system.

The terms no "side effects" and "values of its arguments" are a
bit imprecise.  For example, there is no reason that a "const"
or "pure" call can't raise an exception or memoize results.
I find the definition in the Ada standard (ISO/IEC 8652:1995)
very useful in practice. Apart from Ada legality rules, the
definition is stated entirely in terms of implementation permissions:

                         _Implementation Permissions_

  18. If a library unit is declared pure, then the implementation is
      permitted to omit a call on a library-level subprogram of the
      library unit if the results are not needed after the call.
      Similarly, it may omit such a call and simply reuse the results
      produced by an earlier call on the same subprogram, provided that
      none of the parameters are of a limited type, and the addresses
      and values of all by-reference actual parameters, and the values
      of all by-copy-in actual parameters, are the same as they were at
      the earlier call. This permission applies even if the subprogram
      produces other side effects when called.

Specification in terms of permissions is very useful, as it allows for
functions that are conceptually pure to:
   - memoize results
   - gather statistics
   - raise exceptions
   - produce diagnostic output
These could all be counted as side effects, but they still allow
us to take advantage of the permissions mentioned above.

Note the explicit mention of addresses *and* values of by-reference
parameters. We've had issues in Ada when declaring functions taking
String arguments as Pure for example. This could be an issue in C as
well. We'd like to optimize calls "strlen"-like functions, even if
we write to some unrelated memory. Conceptually, we're just passing
a constant array value. In the Ada case, the representation is even
a bit more complicated as it includes bounds information.

   -Geert

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

* Re: a question about const and pure functions.
  2004-11-11 17:20       ` Geert Bosch
@ 2004-11-11 17:45         ` Roger Sayle
  0 siblings, 0 replies; 20+ messages in thread
From: Roger Sayle @ 2004-11-11 17:45 UTC (permalink / raw)
  To: Geert Bosch
  Cc: Novillo, Diego, Kenneth Zadeck, GCC Mailing List, Berlin, Daniel


On Thu, 11 Nov 2004, Geert Bosch wrote:
> I find the definition in the Ada standard (ISO/IEC 8652:1995)
> very useful in practice.
> ...
>                          _Implementation Permissions_
>
>   18. If a library unit is declared pure, then the implementation is
>       permitted to omit a call on a library-level subprogram of the
>       library unit if the results are not needed after the call...
>       This permission applies even if the subprogram
>       produces other side effects when called.


The critical distinction is between whether the attributes of a function
are determined by the compiler, or are asserted by the programmer.  GCC
already makes use of Ada's implementation permission #18 above.
Consider:

int foo() __attribute__(const)
{
  printf("Hello world!\n");
  global++;
  return 0;
}

here the programmer is *declaring* (note the wording in the Ada standard)
that this function may be considered const, and therefore optimized away
if the return value is not used, or CSE'd blah, blah, blah!  Of course,
Ada's implementation permission #18, doesn't apply if the definition of
foo isn't explicitly *declared* foo.  Instead the remaining implementation
permissions described what constitutes a "safe code transformation" based
upon observable behaviour.

The other implementation permissions allow that calls to

int foo()
{
  return 0;
}

may be eliminated if the result isn't used, but for example prohibit
the compiler eliminating calls to

int foo()
{
  printf("hello world!\n");
  return 0;
}

where foo has not been explicitly declared "pure".  Hence pragmatically
Ada's notion of pure is actually derived from the aspects of the remaining
implementation permissions that allow a function to be eliminated under
the same conditions as being explicitly declared "pure".


Note it is the distinction between "declared" behaviour and "actual"
behaviour that allows us to optimize away calls to "sqrt" with -ffast-math
even though sqrt(-1.0) has observable side-effects.  Some language
front-ends are required to check whether the "const" and/or "pure"
attribute are actually honored by the code, others don't.  In GCC's
middle-end, however, these definitions are honored as always "true".

Roger
--

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

* Re: a question about const and pure functions.
  2004-11-11 15:07     ` Roger Sayle
                         ` (2 preceding siblings ...)
  2004-11-11 17:20       ` Geert Bosch
@ 2004-11-11 19:04       ` Tom Tromey
  2004-11-11 19:17         ` Roger Sayle
  3 siblings, 1 reply; 20+ messages in thread
From: Tom Tromey @ 2004-11-11 19:04 UTC (permalink / raw)
  To: Roger Sayle; +Cc: Novillo, Diego, GCC Mailing List, Berlin, Daniel

>>>>> "Roger" == Roger Sayle <roger@eyesopen.com> writes:

Roger> A "const" call has no side-effects and its results depend
Roger> purely on the values of its arguments.  This closely follows
Roger> the mathematical notion of a "function".  A "pure" call has no
Roger> side-effects, but in addition to it's arguments may depend upon
Roger> the memory/global variables of the system.

In libgcj we have a function called _Jv_InitClass that is used to
initialize a class.  It is a `void' function.  The first call to it in
a given function, with a given class argument, cannot be eliminated,
but all subsequent calls can.  I.e., this function is idempotent but
not pure or const, at least not by the above definitions.

This function has some other properties that can be exploited for
optimization though.  Initializing a class causes all its concrete
superclasses to be initialized as well.  This means that if we see a
call to _Jv_InitClass for a given class, we can also eliminate all
subsequent calls to _Jv_InitClass with arguments which are known to be
superclasses.


Right now we do some optimization in this area by introducing a local
variable for each class to track whether we've called _Jv_InitClass,
and we make calls to _Jv_InitClass conditional on the corresponding
local.  This is ok, in that it works, but it doesn't handle the
superclass case, and it interacts poorly with inlining (after inlining
we need to merge these synthetic locals, but we don't).


So, what to do?

We could have a new "idempotent" attribute.  This would not get the
superclass optimization but would solve the inlining problem.

Or we could somehow teach tree-ssa about the java type system... a
front-end specific pass?  Or extend the local variable approach to do
merging after inlining and to also track all superclasses?

Tom

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

* Re: a question about const and pure functions.
  2004-11-11 19:04       ` Tom Tromey
@ 2004-11-11 19:17         ` Roger Sayle
  2004-11-11 19:31           ` Tom Tromey
  0 siblings, 1 reply; 20+ messages in thread
From: Roger Sayle @ 2004-11-11 19:17 UTC (permalink / raw)
  To: Tom Tromey; +Cc: Novillo, Diego, GCC Mailing List, Berlin, Daniel


On 11 Nov 2004, Tom Tromey wrote:
> We could have a new "idempotent" attribute.  This would not get the
> superclass optimization but would solve the inlining problem.

If the performance overhead of the multiple calls to _Jv_InitClass
is a significant problem, then a new idempotent attribute might not
be unreasonable.  idempotency is the kind of attribute that can be
determined by the types of analysis proposed by Kenneth, but one
possible issue is that apart from _Jv_InitClass, it may not occur
very frequently in practice, i.e. user-written code.  It could
conceivably help libmudflap though.

The other issue is that there are currently no passes or mechanisms
for eliminating idempotent functions in GCC.  Because _Jv_InitClass
doesn't return a value, it's unlike pure/const functions where
CSE/GCSE could be tweaked to take care of this automatically.


If the conclussion is that you need to add a new tree-ssa pass,
specifically for eliminating "idempotent" functions, and this
pass only pays for itself on Java, it might be worth biting the
bullet, and enable front-ends to specify a langhook, or register
additional passes with the pass manager, and implement a special
purpose _Jv_InitClass optimization pass, that could simultaneously
handle _Jv_InitClass *and* implement the type hierarchy optimization.


Sorry if your question was rhetorical.  I've really no idea whether
idempotency is a significant source of optimization opportunities,
for example if any of the functions in SPEC, GCC or glibc could be
marked as idempotent?  Anyone?

Roger
--

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

* Re: a question about const and pure functions.
  2004-11-11 19:17         ` Roger Sayle
@ 2004-11-11 19:31           ` Tom Tromey
  2004-11-11 19:38             ` Roger Sayle
  0 siblings, 1 reply; 20+ messages in thread
From: Tom Tromey @ 2004-11-11 19:31 UTC (permalink / raw)
  To: Roger Sayle; +Cc: Novillo, Diego, GCC Mailing List, Berlin, Daniel

>>>>> "Roger" == Roger Sayle <roger@eyesopen.com> writes:

Roger> If the conclussion is that you need to add a new tree-ssa pass,
Roger> specifically for eliminating "idempotent" functions, and this
Roger> pass only pays for itself on Java, it might be worth biting the
Roger> bullet, and enable front-ends to specify a langhook, or register
Roger> additional passes with the pass manager, and implement a special
Roger> purpose _Jv_InitClass optimization pass, that could simultaneously
Roger> handle _Jv_InitClass *and* implement the type hierarchy optimization.

Roger> Sorry if your question was rhetorical.

I don't have an immediate plan to implement any of this, but I've
been thinking about it in the context of tree-ssa.  I've read that
some folks would like there to be a clean handoff from the front ends
to the GENERIC parts of the compiler -- so I've been trying to think
of situations where this causes problems for java.

Tom

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

* Re: a question about const and pure functions.
  2004-11-11 19:31           ` Tom Tromey
@ 2004-11-11 19:38             ` Roger Sayle
  2004-11-11 20:15               ` Diego Novillo
  0 siblings, 1 reply; 20+ messages in thread
From: Roger Sayle @ 2004-11-11 19:38 UTC (permalink / raw)
  To: Tom Tromey; +Cc: GCC Mailing List


On 11 Nov 2004, Tom Tromey wrote:
> I don't have an immediate plan to implement any of this, but I've
> been thinking about it in the context of tree-ssa.  I've read that
> some folks would like there to be a clean handoff from the front ends
> to the GENERIC parts of the compiler -- so I've been trying to think
> of situations where this causes problems for java.

Another possibility is to make the class initialization behaviour
far more explicit in the gimple when handing off to the middle-end.
For example, in the following:


extern void _Jv_InitClass();

void foo()
{
  int i = 0;

  if (!i)
  {
    _Jv_InitClass();
    i = 1;
  }

  if (!i)
  {
    _Jv_InitClass();
    i = 1;
  }

  if (!i)
  {
    _Jv_InitClass();
    i = 1;
  }
}


The current optimizers are able to optimize the local variable "i"
completely away.  Something similar may be possible in the Java
front-end, where the initial gimple containing these local init
flags one per class explicitly needing initialization in the function.
With a clever bit of hackery, the call of _Jv_InitClass (x) can set
the initialized flag for all of x's superclasses.

Just a thought.

Roger
--

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

* Re: a question about const and pure functions.
  2004-11-11 19:38             ` Roger Sayle
@ 2004-11-11 20:15               ` Diego Novillo
  0 siblings, 0 replies; 20+ messages in thread
From: Diego Novillo @ 2004-11-11 20:15 UTC (permalink / raw)
  To: Roger Sayle; +Cc: Tom Tromey, GCC Mailing List

On Thu, 2004-11-11 at 13:23, Roger Sayle wrote:
> On 11 Nov 2004, Tom Tromey wrote:
> > I don't have an immediate plan to implement any of this, but I've
> > been thinking about it in the context of tree-ssa.  I've read that
> > some folks would like there to be a clean handoff from the front ends
> > to the GENERIC parts of the compiler -- so I've been trying to think
> > of situations where this causes problems for java.
> 
> Another possibility is to make the class initialization behaviour
> far more explicit in the gimple when handing off to the middle-end.
>
That's roughly what I had in mind.  But I never thought it completely
through.  It is in-line with the general direction of expanding the
language semantics in painful detail on the IL for the optimizers
benefit.  There may be some some nasty side-effects in the size of the
IL, so we'd have to watch for that.


Diego.

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

* Re: a question about const and pure functions.
  2004-11-11 15:04   ` Kenneth Zadeck
  2004-11-11 15:07     ` Roger Sayle
@ 2004-11-11 21:40     ` Geoffrey Keating
  2004-11-12 14:50       ` Kenneth Zadeck
  2004-11-12 23:19       ` Geert Bosch
  2004-11-25 13:22     ` Jan Hubicka
  2 siblings, 2 replies; 20+ messages in thread
From: Geoffrey Keating @ 2004-11-11 21:40 UTC (permalink / raw)
  To: Kenneth Zadeck; +Cc: Novillo, Diego, GCC Mailing List, Berlin, Daniel

[-- Attachment #1: Type: text/plain, Size: 1223 bytes --]


On 11/11/2004, at 6:17 AM, Kenneth Zadeck wrote:

> The extensions that I want to add are:
>
> 1) allow const to access memory if the memory is a constant, i.e. if 
> you have a readonly static with a decl initial that satisfies  
> is_gimple_min_invariant (), such a reference need not be treated 
> differently than referencing a "5".
>
> 2) move the processing earlier so that it is available to the rest of 
> the compiler.
>
> 3) allow for recursive and mutually recursive pure and const functions.
>
> 4) eventually to allow some loops (if they can be proven to be finite) 
> rather than just looking for back edges in the cfg. We have this 
> analysis in the compiler, we should be allowed to use the info here.
>
> The hope here is that with the exception of setting errno, that most 
> small table driven mathematical functions would fall into one of these 
>  categories.

All this sounds like a great idea.

(I would caution, though, that really you should check that a recursive 
function terminates.  You may be able to finesse the issue on the 
grounds that a recursive function that doesn't terminate will usually 
eventually run out of stack and terminate that way.)

-- 
Geoff Keating <geoffk@apple.com>


[-- Attachment #2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 2408 bytes --]

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

* Re: a question about const and pure functions.
  2004-11-11 21:40     ` Geoffrey Keating
@ 2004-11-12 14:50       ` Kenneth Zadeck
  2004-11-12 23:19       ` Geert Bosch
  1 sibling, 0 replies; 20+ messages in thread
From: Kenneth Zadeck @ 2004-11-12 14:50 UTC (permalink / raw)
  To: Geoffrey Keating; +Cc: Novillo, Diego, GCC Mailing List, Berlin, Daniel



Geoffrey Keating wrote:

>
> On 11/11/2004, at 6:17 AM, Kenneth Zadeck wrote:
>
>> The extensions that I want to add are:
>>
>> 1) allow const to access memory if the memory is a constant, i.e. if 
>> you have a readonly static with a decl initial that satisfies  
>> is_gimple_min_invariant (), such a reference need not be treated 
>> differently than referencing a "5".
>>
>> 2) move the processing earlier so that it is available to the rest of 
>> the compiler.
>>
>> 3) allow for recursive and mutually recursive pure and const functions.
>>
>> 4) eventually to allow some loops (if they can be proven to be 
>> finite) rather than just looking for back edges in the cfg. We have 
>> this analysis in the compiler, we should be allowed to use the info 
>> here.
>>
>> The hope here is that with the exception of setting errno, that most 
>> small table driven mathematical functions would fall into one of 
>> these  categories.
>
>
> All this sounds like a great idea.
>
> (I would caution, though, that really you should check that a 
> recursive function terminates.  You may be able to finesse the issue 
> on the grounds that a recursive function that doesn't terminate will 
> usually eventually run out of stack and terminate that way.)
>
Yes, that was exactly my plan, even on a 64 bit machine, it will 
eventually terminate. 

kenny

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

* Re: a question about const and pure functions.
  2004-11-11 21:40     ` Geoffrey Keating
  2004-11-12 14:50       ` Kenneth Zadeck
@ 2004-11-12 23:19       ` Geert Bosch
  1 sibling, 0 replies; 20+ messages in thread
From: Geert Bosch @ 2004-11-12 23:19 UTC (permalink / raw)
  To: Geoffrey Keating
  Cc: Novillo, Diego, Kenneth Zadeck, GCC Mailing List, Berlin, Daniel


On Nov 11, 2004, at 16:05, Geoffrey Keating wrote:

> All this sounds like a great idea.
>
> (I would caution, though, that really you should check that a 
> recursive function terminates.  You may be able to finesse the issue 
> on the grounds that a recursive function that doesn't terminate will 
> usually eventually run out of stack and terminate that way.)

This of course will not hold for the case of where the recursion is 
optimized
away, or sibling calls prevent stack growth.

Also, even if all recursive functions eventually terminate, a stack
overflow does not necessarily have to be erroneous (undefined) 
execution.
For example, Ada requires Storage_Error to be raised in such cases, and
this is implemented through -fstack-check.

The following procedure should never output FAILED:

   with Some_Const_Function_That_Never_Returns;
   with Text_IO;
   procedure Hello is
      X : Integer;

   begin
      X := Some_Recursive_Const_Function_That_Never_Returns;
      Text_IO.Put_Line ("FAILED");
   end;

This function could either terminate the program with a Storage_Error
or run for indefinite time. Of course, I'm assuming here that
Some_Const_Function_That_Never_Returns was not declared to be const,
but would be detected as such with your suggestion.

Note however, that Some_Recursive_Const_Function_That_Never_Returns
still can be CSE'd, as long as at least one call remains. Even without
-fstack-check, it is highly dubious to back-propagate information
about execution becoming undefined.

   -Geert

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

* Re: a question about const and pure functions.
  2004-11-11 15:04   ` Kenneth Zadeck
  2004-11-11 15:07     ` Roger Sayle
  2004-11-11 21:40     ` Geoffrey Keating
@ 2004-11-25 13:22     ` Jan Hubicka
  2 siblings, 0 replies; 20+ messages in thread
From: Jan Hubicka @ 2004-11-25 13:22 UTC (permalink / raw)
  To: Kenneth Zadeck
  Cc: Geoffrey Keating, Novillo, Diego, GCC Mailing List, Berlin, Daniel

> 
> 
> Geoffrey Keating wrote:
> 
> >
> >On 10/11/2004, at 11:06 AM, Kenneth Zadeck wrote:
> >
> >>Do we mark functions being const or pure (TREE_READONLY or 
> >>DECL_IS_PURE) based on some external standard definition or are these 
> >>defined any way that the gcc community feels is good?
> >
> >
> >There are backwards compatibility issues, of course, but they're not 
> >based on any particular standard.
> >
> >>I am in the process of moving the code that does this analysis so 
> >>that it is done very early and at once for the entire compilation 
> >>unit.  There appear to be a few minor bugs in the code as well as a 
> >>few missed opportinities.  But before I was going to make any 
> >>changes, I was wondering if there was any better standard of 
> >>definition beyond what is defined in doc/extend.texi.
> >
> >
> >No, I don't think there's anything beyond the documentation.  I think 
> >the documentation could do with being made more precise, but it's not 
> >very bad.
> >
> The minor bugs and missed opportunities are associated with the code 
> that controls the pure can call pure and const and const can call const 
> put const cannot call pure.  The code is messed up in both ways.  Some 
> const calling pures are allowed (if the pure has no args) and some pure 
> calls consts are rejected.  These could be fixed in the existing code, 
> but there are other issues with performing this analysis at the rtl level.
> 
> The extensions that I want to add are:
> 
> 1) allow const to access memory if the memory is a constant, i.e. if you 
> have a readonly static with a decl initial that satisfies  
> is_gimple_min_invariant (), such a reference need not be treated 
> differently than referencing a "5".
> 
> 2) move the processing earlier so that it is available to the rest of 
> the compiler.
> 
> 3) allow for recursive and mutually recursive pure and const functions.
> 
> 4) eventually to allow some loops (if they can be proven to be finite) 
> rather than just looking for back edges in the cfg. We have this 
> analysis in the compiler, we should be allowed to use the info here.

This should be doable with the early cfg building framework and the code
to determine number of iterations given that function has no irreducible
regions.

In fact at least internaly the notion of const and pure functions can be
probably decoupled into aliasing like info "reads this known set of
memories"/"writes this known set of memories" and the additional flags
"is finite" and "don't do anything nasty (like volatile asm or
whatever)"

We really worry about the finiteness (and nastyness) only when we are
going to remove the call (in DCE and CSE). Even RTL representation of
call has slot that can list memory references modified (the pure differs
from const in a way that it contains use of memory that can alias with
anything).

THis also reminds me that I used to have patch that makes us to CSE pure
functions on tree level so we can drop the libcall notes.  I have to
look into what really happent with this thread.
> 
> The hope here is that with the exception of setting errno, that most 
> small table driven mathematical functions would fall into one of these  
> categories.
Concerning functions setting errno I guess one needs to prove that errno
is dead before removing the call that is tricky busynes.
Perhaps we can even have attribute that given function clobbers errno
so we can do the analysis.
We might have flag "sets errno but in const/pure way" so we can at least
CSE the functions... don't know here.

Honza
> 
> Kenny

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

* Re: a question about const and pure functions.
@ 2004-11-11 15:45 Richard Kenner
  0 siblings, 0 replies; 20+ messages in thread
From: Richard Kenner @ 2004-11-11 15:45 UTC (permalink / raw)
  To: stevenb; +Cc: gcc

    So write it down.

You have to agree on them first!  At least one language standardization
committee spent many hours on the question of pure and memoization.

    But your example is obvious - if the function is passed a pointer and
    it modifies it, that is clearly a side-effect because it is a a change
    that cannot be seen directly from the caller's side.

I agree that it should be considered a side-effect, but that makes the
definition of "side-effect" a little harder to state.

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

* Re: a question about const and pure functions.
  2004-11-11 15:09 Richard Kenner
@ 2004-11-11 15:26 ` Steven Bosscher
  0 siblings, 0 replies; 20+ messages in thread
From: Steven Bosscher @ 2004-11-11 15:26 UTC (permalink / raw)
  To: Richard Kenner; +Cc: roger, gcc

On Nov 11, 2004 04:12 PM, Richard Kenner <kenner@vlsi1.ultra.nyu.edu> wrote:
> "The devil is in the details", as they say!

Very true.

>  Is memoization considered a
> "side-effect", for example?  What about a function passed a pointer
> and which indirectly modifies that point?  Is that a "side-effect"?
> It's very tricky to get definitions exactly right.

So write it down.

But your example is obvious - if the function is passed a pointer
and it modifies it, that is clearly a side-effect because it is a
a change that cannot be seen directly from the caller's side.

Gr.
Steven


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

* Re: a question about const and pure functions.
@ 2004-11-11 15:09 Richard Kenner
  2004-11-11 15:26 ` Steven Bosscher
  0 siblings, 1 reply; 20+ messages in thread
From: Richard Kenner @ 2004-11-11 15:09 UTC (permalink / raw)
  To: roger; +Cc: gcc

    A "const" call has no side-effects and its results depend purely on the
    values of its arguments.  This closely follows the mathematical notion
    of a "function".  A "pure" call has no side-effects, but in addition to
    it's arguments may depend upon the memory/global variables of the system.

"The devil is in the details", as they say!  Is memoization considered
a "side-effect", for example?  What about a function passed a pointer and
which indirectly modifies that point?  Is that a "side-effect"?  It's
very tricky to get definitions exactly right.

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

end of thread, other threads:[~2004-11-25 12:44 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-11-10 19:14 a question about const and pure functions Kenneth Zadeck
2004-11-10 23:35 ` Geoffrey Keating
2004-11-11 15:04   ` Kenneth Zadeck
2004-11-11 15:07     ` Roger Sayle
2004-11-11 15:17       ` Daniel Berlin
2004-11-11 15:17       ` Daniel Berlin
2004-11-11 17:20       ` Geert Bosch
2004-11-11 17:45         ` Roger Sayle
2004-11-11 19:04       ` Tom Tromey
2004-11-11 19:17         ` Roger Sayle
2004-11-11 19:31           ` Tom Tromey
2004-11-11 19:38             ` Roger Sayle
2004-11-11 20:15               ` Diego Novillo
2004-11-11 21:40     ` Geoffrey Keating
2004-11-12 14:50       ` Kenneth Zadeck
2004-11-12 23:19       ` Geert Bosch
2004-11-25 13:22     ` Jan Hubicka
2004-11-11 15:09 Richard Kenner
2004-11-11 15:26 ` Steven Bosscher
2004-11-11 15:45 Richard Kenner

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