Re: RFC: Hack to make restrict more useful
On 9/1/07, Mark Mitchell <[EMAIL PROTECTED]> wrote: > This bug: > > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33272 > > is about a situation in which -fargument-noalias works better than > putting "restrict" on all pointer arguments to a function, even though > that should be logically equivalent. Using "restrict" for all arguments > to a function is probably one of the most common cases of "restrict"; > that's what you want for things like the test case I posted, and for > other Fortran-ish code. > > I have a prototype hack which changes checks of flag_argument_noalias != > 0 to also check for the presence of "restrict" on all pointer arguments. > This fixes the test case, modulo a C front-end bug which Joseph has > volunteered to fix. > > To make that a real patch, here's what I plan to do: > > (1) Add a flag to "struct function" to say "all pointer arguments are > restrict". > > (2) Lazily set it, when something wants to check it. > > (3) Change checks of flag_argument_noalias to call a function > argument_noalias() which will return an "int" with the same meaning as > flag_argument_noalias. > > Does that plan sound OK to folks? AFAIK Danny had been "fixing restrict" on his working agenda lately. No idea what the status on that is, though. Richard.
Build failure on Darwin, revision 127998 (solved)
Following http://gcc.gnu.org/ml/gcc/2007-08/msg00544.html I have updated to revision 128003 and tried 'make bootstrap', then 'configure' + 'make bootstrap' without success (the same kind of failure in libgcc). I the tried a fresh install: new directory, configure, and make, and it worked. So now I have a few questions: (1) is there a simpler (cheaper) way to solve this kind of problems (deleting some files, directories, ...)? (2) is there a way to detect this kind of problem from the update result? Thanks for the help. Dominique
GCC Plugin Branch
Hi all, I have just recently had time to checkout and build the GCC plugin branch. I am interested in building a simple plugin to give it a try. After reading through the patches it seems simple enough, I just need to create a shared library that defines the symbols: pre_translation_unit transform_ctrees transform_gimple transform_cgraph transform_rtl post_translation_unit Does anyone have a template/example autoconf project that is already setup with the needed gcc headers + build infrastructure to create a GCC plugin? Also i noticed that it uses the -export-dynamic flag with libtool which means some platforms like Cygwin are unable to support plugins (Noted in the documentation). Are there any plans for supporting the libtool dlpreopening for plugins so that they can still be used on systems if the plugins are built into GCC? One other thing I noticed is that the configure check for plugin support and inclusion of libltdl is $host based, I.e. pre-defined which hosts support plugins instead of doing a generic check for plugin support. I assume it should be possible to find out from libtool whether shared library support is enabled or not. But then again the $host based check seems to be the way a lot of the other checks in the GCC configure.ac files are done. I mention this because i often use NetBSD which supports shared libraries and is not listed for including libltdl or for enabling plugin support. Otherwise seems like a nice simple implementation. Thanks, Brendon.
Re: RFC: Hack to make restrict more useful
Richard Guenther wrote: >> I have a prototype hack which changes checks of flag_argument_noalias != >> 0 to also check for the presence of "restrict" on all pointer arguments. >> This fixes the test case, modulo a C front-end bug which Joseph has >> volunteered to fix. > AFAIK Danny had been "fixing restrict" on his working agenda lately. No > idea what the status on that is, though. I fully concede that my trick isn't a general solution to making full use of restrict. But, given that I think it'll take about 20-50 lines of code, and that it will get a lot of the common cases, I think it's worth it. Do you agree? Thanks, -- Mark Mitchell CodeSourcery [EMAIL PROTECTED] (650) 331-3385 x713
(gcc 4.2) how to create an ADDR_EXPR that refers to a linkage name?
We are in the process of updating GCC/UPC's support for the UPC dialect of C to version 4.2.0 of GCC. GCC/UPC is described here: http://www.intrepid.com/upc.html Generally, things are working. However, at the moment, all tests fail when optimizations are enabled. For example: test00.upc:35: internal compiler error: in referenced_var_check_and_insert, at tree-dfa.c:639 It is failing on this check: (gdb) l 634 635 if (h) 636 { 637 /* DECL_UID has already been entered in the table. Verify that it is 638 the same entry as TO. See PR 27793. */ 639 gcc_assert (h->to == to); 640 return false; 641 } 642 643 h = GGC_NEW (struct int_tree_map); (gdb) p h->to $1 = 0x2e1ad160 (gdb) pt unit size align 8 symtab 0 alias set -1 precision 8 min max pointer_to_this > addressable used public static common QI defer-output file test00.upc line 26 size unit size align 8> (gdb) p to $2 = 0x2e1b7630 (gdb) pt unit size align 8 symtab 0 alias set -1 precision 8 min max pointer_to_this > addressable used public static common QI defer-output file test00.upc line 26 size unit size align 8> Above, the two tree nodes are clones of each other created by the following UPC-specific code: 1109/* Convert shared variable reference VAR into a shared pointer 1110 value of the form {0, 0, &VAR} */ 1112tree 1113upc_build_shared_var_addr (tree type, tree var) 1114{ 1115 tree new_var, var_addr, val; 1116 if (!(TREE_CODE (var) == VAR_DECL && TREE_SHARED (var))) 1117abort (); 1118 if (!(TREE_CODE (type) == POINTER_TYPE && TYPE_SHARED (TREE_TYPE (type 1119abort (); 1120 1121 /* Create a VAR_DECL that is the same as VAR, but 1122 with qualifiers (esp. TYPE_QUAL_SHARED) removed so that 1123 we can create the actual address of the variable (in the shared 1124 section) without infinite recursion in the 1125 gimplification pass. Make sure the new copy has 1126 the same UID as the old. In the future, we might need 1127 to reference the symbol name directly. */ 1128 1129 new_var = copy_node (var); 1130 DECL_UID (new_var) = DECL_UID (var); 1131 TREE_TYPE (new_var) = TYPE_MAIN_VARIANT (TREE_TYPE (var)); 1132 TREE_SHARED (new_var) = 0; 1133 TREE_STRICT (new_var) = 0; 1134 TREE_RELAXED (new_var) = 0; 1135 var_addr = build_fold_addr_expr (new_var); 1136 TREE_CONSTANT (var_addr) = 1; 1137 val = upc_build_shared_ptr_value (type, 1138integer_zero_node, 1139integer_zero_node, 1140var_addr); 1141 return val; 1142} As background, GCC/UPC adds a new qualifier, "shared" to indicate that a value must be accessed remotely and that it is shared across all UPC "threads" (which can be thought of as processes all running the same program, but with differing local copies of data). The UPC specific aspects of the language are translated by a gimplify pass into normal gimple trees that are then passed to the middle and back ends of GCC. For example a reference to a value of a type that is qualified as "shared" will result in a call to a (possibly inlined) remote "get" library routine. Where this gimplify pass can get confused is when it sees a reference to a shared variable. If it sees a reference to a shared variable on the right hand side of an assignment, it assumes that its value is needed and generates a remote get call. The address of a shared variable has three parts (phase, thread, virtual address). For declared variables, the phase and thread are always 0. A constructor is used to create a shared address. That's what upc_build_shared_ptr_value() does above. The virtual address part of the shared address is simply the regular address of the variable, because all shared variables are collected together in their own "upc_shared" linkage section. This section is needed simply for address assignment purposes. The actual shared data is located in a global shared address region. The code above clones a shared variable, stripping its type qualifiers (most importantly the "shared" qualifier). When the address of the cloned variable is taken, its normal C pointer-sized address will result, and the special gimplify pass doesn't get confused, thinking that the address of the variable is a shared address. The code above isn't clever. It clones the variable each time it needs to generate a shared address. In GCC 4.2, this runs into problems in the optimization pass that implements special checks for this sort of inconsistency. The discussion above is a (very) long lead up to a request for ideas and suggestions for better handling this situation. O
Re: (gcc 4.2) how to create an ADDR_EXPR that refers to a linkage name?
On 9/1/07, Gary Funck <[EMAIL PROTECTED]> wrote: > All suggestions/help appreciated, - Gary Have you considered using the data sharing machinery in OpenMP? We simply create a data structure holding all shared variables, allocate that in shared memory and re-write all references to shared variables as dereferences to that structure. See the implementation of the 'shared' clauses in omp-low.c. It will mostly depend on the threading semantics of UPC. In OpenMP, we operate on a pthread-like environment, so we can pass around pointers to the stack in the parent thread which can then be shared with the children threads. This trick you are implementing with cloning the VAR_DECLs is guaranteed not to work, sorry. We very explicitly assume that if DECL_UID (x1) == DECL_UID (x2) then x1 == x2. This is not something that will change.
Re: (gcc 4.2) how to create an ADDR_EXPR that refers to a linkage name?
On Sat, Sep 01, 2007 at 01:43:37PM -0400, Diego Novillo wrote: > > Have you considered using the data sharing machinery in OpenMP? We > simply create a data structure holding all shared variables, allocate > that in shared memory and re-write all references to shared variables > as dereferences to that structure. Diego, thanks. Some other implmentations of UPC reference all shared variables indirectly through a table, built at runtime. The compiler tells the runtime how much space each variable reauires, and the runtime alloctes this from the shared memory region. The current strategy used by GCC/UPC is somewhat simpler; it lets the linker create the layout of the shared variable section. Perhaps we need to re-visit this design decision, and adopt a scheme similar to that used by GOMP. I'll review omp-low.c for ideas. GCC/UPC does have a pthreads mode of operation, but that is a special case. UPC threads are usually mapped to separate processes. The shared memory region is potentially distributed across network nodes, often accessed via a high speed interconnect. The runtime that is part of the GCC/UPC's release supports only SMP configurations and relies on mmap(). However, GCC/UPC also works with a more general runtime developed by Berkeley, which supports many network interconnects. > > This trick you are implementing with cloning the VAR_DECLs is > guaranteed not to work, sorry. We very explicitly assume that if > DECL_UID (x1) == DECL_UID (x2) then x1 == x2. This is not something > that will change. Yeah, I suspected as much when I first wrote that code. I wasn't too surprised to see that it failed a consistency check in GCC 4.2.
Re: RFC: Hack to make restrict more useful
On 9/1/07, Mark Mitchell <[EMAIL PROTECTED]> wrote: > Richard Guenther wrote: > > >> I have a prototype hack which changes checks of flag_argument_noalias != > >> 0 to also check for the presence of "restrict" on all pointer arguments. > >> This fixes the test case, modulo a C front-end bug which Joseph has > >> volunteered to fix. > > > AFAIK Danny had been "fixing restrict" on his working agenda lately. No > > idea what the status on that is, though. > > I fully concede that my trick isn't a general solution to making full > use of restrict. But, given that I think it'll take about 20-50 lines > of code, and that it will get a lot of the common cases, I think it's > worth it. Do you agree? Yes, I agree. I just was curious on the status of Dannys work and if it would obsolete what you propose. Richard.
Re: RFC: Hack to make restrict more useful
Richard Guenther wrote: >> I fully concede that my trick isn't a general solution to making full >> use of restrict. But, given that I think it'll take about 20-50 lines >> of code, and that it will get a lot of the common cases, I think it's >> worth it. Do you agree? > > Yes, I agree. I just was curious on the status of Dannys work and if it > would obsolete what you propose. OK, great. Here's a draft patch for the trick; this works on the test case I had, and I'll be testing it now. If it passes testing, and I add testcases, does this look OK to you? Thanks, -- Mark Mitchell CodeSourcery [EMAIL PROTECTED] (650) 331-3385 x713 2007-09-01 Mark Mitchell <[EMAIL PROTECTED]> * function.h (struct function): Add argument_noalias. * alias.h (argument_noalias): Declare it. * alias.c (argument_noalias): New function. (base_alias_check): Use it. * tree-ssa-structalias.c (intra_create_variable_infos): Use argument_noalias. Index: function.h === --- function.h (revision 127950) +++ function.h (working copy) @@ -473,6 +473,12 @@ struct function GTY(()) function has been gimplified, so we can make sure we're not creating non GIMPLE tuples after gimplification. */ unsigned gimplified : 1; + + /* 0 if we have not yet determined whether arguments to this + function might alias each other. 1 if we have determined they + may alias each other. 2 if we have determined they cannot alias + each other. */ + unsigned argument_noalias : 2; }; /* If va_list_[gf]pr_size is set to this, it means we don't know how Index: alias.c === --- alias.c (revision 127950) +++ alias.c (working copy) @@ -1452,6 +1452,56 @@ find_base_term (rtx x) } } +/* Returns an integer indicating to what extent arguments to the + current function may alias one-another or global variables. In + particular, the return value is: + + 0 if pointer arguments may alias each other. + 1 if pointer arguments may not alias each other but may alias + global variables. + 2 if pointer arguments may not alias each other and may not + alias global variables. + 3 if pointer arguments may not alias anything. + + Unlike FLAG_ARGUMENT_NOALIAS, the value returned may differ + depending on the function presently being processed. */ + +int +argument_noalias (void) +{ + tree t; + + /* If FLAG_ARGUMENT_NOALIAS tells us that arguments cannot alias, we + do not have to try to prove that ourselves. And, if we're + outside of a function, there's nothing we can prove. */ + if (flag_argument_noalias || !cfun) +return flag_argument_noalias; + + /* If we have not already determined whether this function's + arguments can alias each other, figure that out now. */ + if (!cfun->argument_noalias) +{ + /* If all the arguments to the current function are pointers with +the "restrict" qualifier, then none of them can point to one +another. Assume that's the case. */ + cfun->argument_noalias = 2; + for (t = DECL_ARGUMENTS (current_function_decl); t; t = TREE_CHAIN (t)) + { + tree type = TREE_TYPE (t); + /* If we find a pointer argument that does not have the +"restrict" qualifier, then some of the arguments to this +function might alias other arguments. */ + if (POINTER_TYPE_P (type) && !TYPE_RESTRICT (type)) + { + cfun->argument_noalias = 1; + break; + } + } +} + + return cfun->argument_noalias - 1; +} + /* Return 0 if the addresses X and Y are known to point to different objects, 1 if they might be pointers to the same object. */ @@ -1461,6 +1511,7 @@ base_alias_check (rtx x, rtx y, enum mac { rtx x_base = find_base_term (x); rtx y_base = find_base_term (y); + int noalias; /* If the address itself has no known base see if a known equivalent value has one. If either address still has no known base, nothing @@ -1521,10 +1572,11 @@ base_alias_check (rtx x, rtx y, enum mac || (GET_CODE (y_base) == ADDRESS && GET_MODE (y_base) == Pmode)) return 0; - if (! flag_argument_noalias) + noalias = argument_noalias (); + if (! noalias) return 1; - if (flag_argument_noalias > 1) + if (noalias > 1) return 0; /* Weak noalias assertion (arguments are distinct, but may match globals). */ Index: alias.h === --- alias.h (revision 127950) +++ alias.h (working copy) @@ -28,6 +28,7 @@ extern alias_set_type get_varargs_alias_ extern alias_set_type get_frame_alias_set (void); extern bool component_uses_parent_alias_set (const_tree); extern bool alias_set_subset_of (alias_set_type, alias_set_type); +extern int argument_noalias (void); /* This alia
Re: RFC: Hack to make restrict more useful
Richard Guenther wrote: >> OK, great. Here's a draft patch for the trick; this works on the test >> case I had, and I'll be testing it now. If it passes testing, and I add >> testcases, does this look OK to you? Thanks for the speedy and accurate review! >> + bool noalias; > > it's an int. Doh, fixed. >> + /* For each incoming pointer argument arg, ARG = ESCAPED_VARS or a >> + dummy variable if flag_argument_noalias > 2. */ > > What's this comment for? Brain leakage. I cut-and-paste that from an older version; sorry, will remove. >> + if (POINTER_TYPE_P (TREE_TYPE (t)) && noalias) > > noalias > 0 I suppose. If you like. (Since noalias is never negative, this is logically equivalent.) I've made the change. >> { >> varinfo_t vi; >> tree heapvar = heapvar_lookup (t); >> @@ -4579,7 +4583,7 @@ intra_create_variable_infos (void) >> heapvar_insert (t, heapvar); >> >> ann = get_var_ann (heapvar); >> - if (flag_argument_noalias == 1) >> + if (flag_argument_noalias <= 1) >> ann->noalias_state = NO_ALIAS; >> else if (flag_argument_noalias == 2) >> ann->noalias_state = NO_ALIAS_GLOBAL; > > That looks wrong. Shouldn't this just replace flag_argument_noalias > for noalias everywhere? Either will work, but you're right; using noalias is clearer. (In an earlier version I'd not organized things in the same way, so that wouldn't have worked.) I'll make those changes too. As you suggest, I'll finish up testing and wait for Danny's comments. Thanks! -- Mark Mitchell CodeSourcery [EMAIL PROTECTED] (650) 331-3385 x713
Re: RFC: Hack to make restrict more useful
On 9/1/07, Mark Mitchell <[EMAIL PROTECTED]> wrote: > Richard Guenther wrote: > > >> I fully concede that my trick isn't a general solution to making full > >> use of restrict. But, given that I think it'll take about 20-50 lines > >> of code, and that it will get a lot of the common cases, I think it's > >> worth it. Do you agree? > > > > Yes, I agree. I just was curious on the status of Dannys work and if it > > would obsolete what you propose. > > OK, great. Here's a draft patch for the trick; this works on the test > case I had, and I'll be testing it now. If it passes testing, and I add > testcases, does this look OK to you? > > --- tree-ssa-structalias.c (revision 127950) > +++ tree-ssa-structalias.c (working copy) > @@ -4544,7 +4544,12 @@ intra_create_variable_infos (void) > { >tree t; >struct constraint_expr lhs, rhs; > + bool noalias; it's an int. > + noalias = argument_noalias (); > + > + /* For each incoming pointer argument arg, ARG = ESCAPED_VARS or a > + dummy variable if flag_argument_noalias > 2. */ What's this comment for? >/* For each incoming pointer argument arg, create the constraint ARG > = ANYTHING or a dummy variable if flag_argument_noalias is set. */ >for (t = DECL_ARGUMENTS (current_function_decl); t; t = TREE_CHAIN (t)) > @@ -4554,11 +4559,10 @@ intra_create_variable_infos (void) >if (!could_have_pointers (t)) > continue; > > - /* If flag_argument_noalias is set, then function pointer > -arguments are guaranteed not to point to each other. In that > -case, create an artificial variable PARM_NOALIAS and the > -constraint ARG = &PARM_NOALIAS. */ > - if (POINTER_TYPE_P (TREE_TYPE (t)) && flag_argument_noalias > 0) > + /* If the arguments are guaranteed not to point to each other, > +create an artificial variable PARM_NOALIAS and the constraint > +ARG = &PARM_NOALIAS. */ > + if (POINTER_TYPE_P (TREE_TYPE (t)) && noalias) noalias > 0 I suppose. > { > varinfo_t vi; > tree heapvar = heapvar_lookup (t); > @@ -4579,7 +4583,7 @@ intra_create_variable_infos (void) > heapvar_insert (t, heapvar); > > ann = get_var_ann (heapvar); > - if (flag_argument_noalias == 1) > + if (flag_argument_noalias <= 1) > ann->noalias_state = NO_ALIAS; > else if (flag_argument_noalias == 2) > ann->noalias_state = NO_ALIAS_GLOBAL; That looks wrong. Shouldn't this just replace flag_argument_noalias for noalias everywhere? Otherwise it looks good, but let's wait for Danny to comment. Richard.