Richard Guenther wrote:
On Mon, Jan 12, 2009 at 12:03 AM, Raoul Gough <raoulgo...@yahoo.co.uk> wrote:
Richard Guenther wrote:
[snip]
This is also invalid.  You have to use placement new to change the dynamic
type of memory.


Yes, I guess that makes sense. I've modified the example like this:

#include <new>

void** global_free_list = 0;

inline void operator delete(void* p2) throw()
{
  // Save "next" pointer in re-used client storage
  new (p2) (void *) (global_free_list);
  global_free_list = static_cast<void **>(p2);
}

double foo(double* p1)
{
  double result = *p1;
  delete p1;
  return result;
}


[snip]
So how is this example looking now? Does the alias analysis mean that g++
will never reorder the read and write via p1 and p2?

Yes, as that would now be an invalid thing to do.  Note that for C
there is no way to do "placement new", but the memory model of C
only has static typing, not the notion of a dynamic type.  Which is
why some people (including me) say you cannot do a C conforming
implementation of malloc that ever re-uses memory.

I don't really see which part of the alias analysis shows that g++ won't reorder the accesses via the double* and the void**. Is it because the intersection of the "may aliases" lists is non-empty?

----8<--------  start
Symbol memory tags

SMT.7, UID D.1868, void *, is addressable, is global, score: 556356, direct reads: 0, direct writes: 0, indirect reads: 0, indirect writes: 1, call clobbered (stored in global, is global var), may aliases: { global_free_list } SMT.8, UID D.1869, double, is addressable, is global, score: 320002, direct reads: 0, direct writes: 0, indirect reads: 1, indirect writes: 0, call clobbered (is global var, is incoming pointer), may aliases: { global_free_list }
[...]
Name memory tags

NMT.9, UID D.1870, double, is addressable, is global, score: 8, direct reads: 1, direct writes: 0, indirect reads: 0, indirect writes: 0, call clobbered (is global var, is incoming pointer), may aliases: { global_free_list SMT.8 } NMT.10, UID D.1871, void *, is addressable, is global, score: 16, direct reads: 0, direct writes: 1, indirect reads: 0, indirect writes: 0, call clobbered (stored in global, is global var), may aliases: { global_free_list SMT.7 }
----8<--------  end


By the way, if I change the example very slightly, so it uses char* for p1, the aliasing information is somewhat different. In particular, it includes the void* in the may-aliases list for the char.

double bar(char* p1)
{
   double result = *p1;
   delete p1;
   return result;

}

Alias information for double bar(char*)

[...]

Symbol memory tags

SMT.22, UID D.1898, void *, is addressable, is global, score: 876358, direct reads: 0, direct writes: 0, indirect reads: 1, indirect writes: 1, call clobbered (stored in global, is global var, is incoming pointer), may aliases: { global_free_list } SMT.23, UID D.1899, char, is addressable, is global, score: 320002, direct reads: 0, direct writes: 0, indirect reads: 1, indirect writes: 0, call clobbered (is global var, is incoming pointer), may aliases: { global_free_list SMT.22 }

[...]

Name memory tags

NMT.24, UID D.1900, char, is addressable, is global, score: 8, direct reads: 1, direct writes: 0, indirect reads: 0, indirect writes: 0, call clobbered (is global var, is incoming pointer), may aliases: { global_free_list SMT.22 SMT.23 } NMT.25, UID D.1901, void *, is addressable, is global, score: 16, direct reads: 0, direct writes: 1, indirect reads: 0, indirect writes: 0, call clobbered (stored in global, is global var), may aliases: { global_free_list SMT.22 }


So I guess I'm just trying to understand how the alias data structures are used. In the one case (with a char*) it's pretty easy I guess, but I don't really understand how it represents the potential aliasing in the void** versus double* example.

--
Thanks,
Raoul Gough.


Reply via email to