Re: RFC: Hack to make restrict more useful

2007-09-01 Thread Richard Guenther
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)

2007-09-01 Thread Dominique Dhumieres
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

2007-09-01 Thread Brendon Costa
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

2007-09-01 Thread Mark Mitchell
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?

2007-09-01 Thread Gary Funck

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?

2007-09-01 Thread Diego Novillo
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?

2007-09-01 Thread Gary Funck
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

2007-09-01 Thread Richard Guenther
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

2007-09-01 Thread Mark Mitchell
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

2007-09-01 Thread Mark Mitchell
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

2007-09-01 Thread Richard Guenther
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.