This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Functions that are CSEable but not pure


On 10/04/2012 09:07 AM, Richard Guenther wrote:
Ugh.  Especially with the above (you can DCE those calls) makes this
severly mis-specified ... and any implementation error-prone (look what
mess our losely defined 'malloc' attribute opened ...).

I thought of a testcase like

  int *p = get_me ();
  .. = *p;
  int *q = get_me ();
  .. = *q;

and get_me allocating/initalizing and returning a singleton.

Right.


But you tell me it's more complicated and get_me () needs to
be a barrier for any load/store (as it may modify arbitrary memory,
but only on the "first" call).

Yes, because the initialization is user-written code.


I think that "may modify arbitrary memory" isn't going to fly and
my answer would be, better don't try to optimize anything here,
at least not in generic terms.  How would you handle this in
the alias oracle?  How would you then make CSE recognize
two functions return the same value and are CSEable?

For aliasing purposes, the call is like a call to a normal function. For CSE purposes, we want to recognize identical calls and combine them. I don't know the GCC bits well enough to be any more specific.


Can you come up with a short but complete testcase illustrating the issue
better (preferably C, so I don't need to read-in magic points where construction
happens)?

int init_count; int data;

void init()
{
  static int initialized;
  if (!initialized)
    {
      data = ++init_count;
      initialized = 1;
    }
}

inline int *get_me() __attribute ((pure));
inline int *get_me()
{
  init ();
  return &data;
}

int sink;

int main()
{
  sink = init_count;
  int *p = get_me();
  if (init_count != 1)
    __builtin_abort();
  int *q = get_me();
  if (init_count != 1)
    __builtin_abort();
  return *p + *q;
}

On this testcase, gcc -O2 doesn't reload init_count after the call to get_me because it thinks that the call can't have modified init_count. I want the compiler to know that it is safe to discard the redundant assignment, but not make assumptions about memory.

On 10/04/2012 08:59 AM, Jakub Jelinek wrote:> On Thu, Oct 04, 2012 at 08:56:03AM -0400, Jason Merrill wrote:
> Sure, but I thought you want to inline the wrapper function as soon as
> possible. Or do you want to keep it as some kind of builtin that gets
> expanded during expansion to the test and call?


Ah, I see your point; if get_me is inlined we end up with two calls to init, so it would be good to mark init with the same hypothetical attribute.

Jason


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]