Re: question about if_marked construct
Interesting. My first reaction is that this is an invalid use of the garbage collector. I think there is really only one valid function that can be used as an if_marked function: one which checks ggc_marked_p on the structure. Then how about tree_map_base_marked_p, the if_marked function for value_expr_for_decl? tree.h: ... struct GTY(()) tree_map_base { tree from; }; struct GTY(()) tree_decl_map { struct tree_map_base base; tree to; }; #define tree_decl_map_marked_p tree_map_base_marked_p ... tree.c: ... static GTY ((if_marked ("tree_decl_map_marked_p"), param_is (struct tree_decl_map))) htab_t value_expr_for_decl; int tree_map_base_marked_p (const void *p) { return ggc_marked_p (((const struct tree_map_base *) p)->from); } ... The tree_map_base_marked_p checks ggc_marked_p on the from field. During ggc_scan_cache_tab, if the from field is live, also the to field is marked live. I wrote some code to do sanity testing and found a similar scenario as before: - a register attribute is not marked live during root marking - reg_attrs_htab is traversed, and the hash table entry corresponding to the register attribute is removed - value_expr_for_decl is traversed, a from field is found live, so the to field is also marked live, marking the register attribute live. Is this valid use of the garbage collector?
Re: question about if_marked construct
On Mon, Jul 5, 2010 at 1:54 PM, Tom de Vries wrote: >> Interesting. My first reaction is that this is an invalid use of the >> garbage collector. I think there is really only one valid function >> that can be used as an if_marked function: one which checks >> ggc_marked_p on the structure. > > > Then how about tree_map_base_marked_p, the if_marked function for > value_expr_for_decl? > > tree.h: > ... > struct GTY(()) tree_map_base { > tree from; > }; > > struct GTY(()) tree_decl_map { > struct tree_map_base base; > tree to; > }; > > #define tree_decl_map_marked_p tree_map_base_marked_p > ... > > tree.c: > ... > static GTY ((if_marked ("tree_decl_map_marked_p"), param_is (struct > tree_decl_map))) > htab_t value_expr_for_decl; > > int > tree_map_base_marked_p (const void *p) > { > return ggc_marked_p (((const struct tree_map_base *) p)->from); > } > ... > > The tree_map_base_marked_p checks ggc_marked_p on the from field. During > ggc_scan_cache_tab, if the from field is live, also the to field is marked > live. > I wrote some code to do sanity testing and found a similar scenario as > before: > - a register attribute is not marked live during root marking > - reg_attrs_htab is traversed, and the hash table entry corresponding to the > register attribute is removed > - value_expr_for_decl is traversed, a from field is found live, so the to > field is also marked live, marking the register attribute live. > > Is this valid use of the garbage collector? Originally the if_marked hook was supposed to be used only for caching purposes. So it doesn't matter whether an element is collected or not for correctness. If we now have accumulated other uses we indeed have to worry about this scenario (and I think it won't work very well there). Richard.
Re: question about if_marked construct
Hi, The tree_map_base_marked_p checks ggc_marked_p on the from field. During ggc_scan_cache_tab, if the from field is live, also the to field is marked live. I wrote some code to do sanity testing and found a similar scenario as before: - a register attribute is not marked live during root marking - reg_attrs_htab is traversed, and the hash table entry corresponding to the register attribute is removed - value_expr_for_decl is traversed, a from field is found live, so the to field is also marked live, marking the register attribute live. Is this valid use of the garbage collector? Originally the if_marked hook was supposed to be used only for caching purposes. So it doesn't matter whether an element is collected or not for correctness. If we now have accumulated other uses we indeed have to worry about this scenario (and I think it won't work very well there). Richard. For my understanding: is it correct if I translate 'to be used only for caching purposes' to 'the compiler is free to ignore the if_marked function and remove all if_marked hash table entries'? I just tried that in a bootstrap build, and that breaks already in stage 1. From looking at all the if_marked functions in gcc, a typical use case seems to be the one of uniqueness (also the use case described in the docs): making sure there is only a single object with certain properties, such that a test for structural equality can be replaced with a pointer equality comparison. This is well supported by the current implementation, but correctness does depend on whether a hash table element is collected or not. What is not well supported, is marking live something else than hash table entries during ggc_scan_cache_tab. Following the scenario I mention above, we can end up with 2 structurally equal objects, while the code assumes that's not possible, and tests structural equality by pointer comparison. This is the scenario I worry about. I can image a few ways to go from here: - leave as is, fix this when it really bothers us (risk: exchange a known problem for unknown hard-to-debug and/or hard-to-reproduce problems) - instrument if_marked functions like the one for value_expr_for_decl to assert if the from field is live and the to field is not live, and fix the asserts - extend garbage colllector to handle the problematic case (problem: more runtime and/or memory usage for garbage collection) Any suggestions on which way to go? Regards Tom
random access memory cycle runs ten times faster on win32 platform than on linux - strange
Hi, I'm new on this list, and I hope I'm asking my question at right place. I tried to test the bandwidth of a DDR3 memory in random access mode, and I wrote a simple code for this purpose. I compiled it with gcc-4.1.1 for Linux and with mingw-4.2.1-sjlj for Windows. After I tried the executables I saw that the windows version runs more then 10 times faster than the linux version. My test routine is very simple. I fill up two arrays with random numbers: int *memRand1, *memRand2; And I also allocate two more arrays to move data between them (2 x 256MB). float *mem1, *mem2; So, I would like to move data from "mem2" into "mem1" randomly with this function: for ( i=0; i random-mem-test.tar.bz2 Description: BZip2 compressed data
Re: random access memory cycle runs ten times faster on win32 platform than on linux - strange
Quoting Béla MIHALIK : If I compile it with mingw32 compiler, or VisualC++ then it gives good result. Here are my results for memory bandwith test: Linux: 373.574249 MB/s Win32: 4468.297363 MB/s I don't think that has anything to do with the code generated by the compiler; rather, I think the random function you use on Windows is broken. The bandwidth is way too high for pages misses in most loop iterations.
Delegating constructors patch
Hi, I'd like to know if there's plans to merge Pedro Lamarão's implementation of delegating constructors into trunk. While we're at it, is there someone implementing C++0x's inheriting constructors? Regards, Rodolfo Lima
[GIMPLE] Local variables
Hello all, I am trying to get an access to local variables of a function thanks to the GIMPLE representation. When I read the dump file after the CFG pass, I can see a new temporary variable added. For example with the identity function I would like to get an access to the uid of this variable. A piece of code : float id (float x) { return x; } Dump file : ;; Function id (id) Merging blocks 2 and 3 id (float x) { float D.2718; : D.2718 = x; return D.2718; } In this example, I can have access to everything except the declaration of D.2718. It's the same thing with the explicit declaration of an int in an other example. Does anyone know how can I get this information ? Maybe I can't or maybe I do something wrong but I am a little bit stucked. Thank you for your time. Cheers -- Jeremie Salvucci
Attributes
Hey GCC devs, My name is Sean Hunt and I'm currently refactoring the attribute-handling system in clang, in order to better support C++0x[1] attributes and make attributes in general much easier to follows. One of the major issues I'm having is that there are a number of cases where concessions are made to GCC attributes for of compatibility with GCC but where the exact basis for making these concessions is either unclear or listed in the GCC spec[2] as being a case of things not implemented in GCC. More importantly, these concessions are prohibited from being made in C++0x. In a few cases, the incompatibilities are visible in the specifications, for instance, with the noreturn attribute: void foo () [[noreturn]]; // wrong per spec void foo [[noreturn]] (); // right per spec [[noreturn]] void foo (); // right per spec void foo () __attribute__((noreturn)); // right per spec void foo __attribute__((noreturn)) (); // works __attribute__((noreturn)) void foo (); // works It's obvious that the first example of each kind (noreturn appearing after the function declarator) must be accepted if it's a GCC attribute and not if it's a C++0x attributes. The later two (noreturn appearing before the declaration or after the identifier) must be accepted for C++0x attributes, but it's not clear if the GCC syntax being accepted is an accident or by design. There are more complex scenarios, such as if the function returns a pointer and the attribute appears between the pointer declarator and the identifier: void * [[noreturn]] foo (); // wrong per spec void * __attribute__((noreturn)) foo (); // works This also works with GCC syntax, but once again it is very unclear whether it's actually supposed to. Another incompatibility is with array declarators: int i [] [[aligned(4)]]; // wrong per spec int i [] __attribute__(align(4)); // right per spec Is anyone currently working on C++0x attributes in GCC and, if not, is there anyone who can help me through what we should and shouldn't accept in clang? Thanks, Sean
Re: random access memory cycle runs ten times faster on win32 platform than on linux - strange
On 05/07/2010 19:43, Joern Rennecke wrote: > Quoting Béla MIHALIK : > >> If I compile it with mingw32 compiler, or VisualC++ then it gives good >> result. >> >> Here are my results for memory bandwith test: >> >> Linux: 373.574249 MB/s Win32: 4468.297363 MB/s > > I don't think that has anything to do with the code generated by the > compiler; rather, I think the random function you use on Windows is broken. It's fine, it's just that the testcase doesn't account for RAND_MAX, which is only 0x7fff in MSVC runtime, so it only ever ends up swapping entries in the first 32k (array elements, not bytes) of each block: > const int nofElems = 64 * 1024 * 1024; > for ( i=0; i { > memRand1[i] = rand() % nofElems; > memRand2[i] = rand() % nofElems; > } > for ( i=0; i { > mem1[ memRand1[i] ] = mem2[ memRand2[i] ]; > } In the GLIBC runtime, RAND_MAX is 0x7fff, so that's big enough to cover the entire span of the nofElems-sized arrays. Since there's no compiler bug, this is gcc-help@ material; please send any follow-ups to that list. cheers, DaveK
[vect, gccint] Mistake about Vector-specific attributes?
Hi, In gccint, 7.2.3.3 Vector-specific attributes, there are two items talking about vect_int_mult: vect_int_mult Target supports a vector widening multiplication of short operands into an int result, or supports promotion (unpacking) from short to int and a non-widening multiplication of int. vect_int_mult Target supports vector int multiplication. I suspect that the first one should refer to vect_widen_mult_hi_to_si. Thanks Eric