Re: RFC: Add STB_GNU_SECONDARY

2012-04-21 Thread H.J. Lu
On Fri, Apr 20, 2012 at 6:08 PM, Joern Rennecke  wrote:
>>> Even better, you could use symbolic tags, and have the linker script
>>> assign precedence values to these tags.
>>
>>
>> It won't help us.
>
>
> Maybe it wouldn't buy you more than the secondary symbols right now, but
> it would give a lot of flexibility to rearrange and combine different
> peoples ideas of link priority.
>
> Another thought on symbols priorities: with pthread, using symbols of
> different priorities is really a crutch - and it doesn't really work
> that well for static linking.  What is really wanted is that
> whenever one of a set of object files is linked in, a whole set of symbols
> should be satisfied from a different place.  Maybe if, for a static pthread,
> we'd put the pthread-aware I/O etc. into a special .text.pthread section
> or somesuch, which would normally discarded, but had a mechanism to use them
> if a special symbol is set (or used?) from an object file that provides
> a pthread API function.

We want to provide a .o file which can take advantage of all versions of
Linux we support.  For a function, foo, in glibc, we can use it only if it is
available on all versions of glibc or we provide our own implementation of
foo inside the .o file.  With our own foo, the one in glibc will never be used.
When our own foo is marked as secondary, the one in glibc will be
used if it exists.  However we do want to use foo in glibc if it exists.

Putting our own foo in a section with a special prefix in section name,
like .secondary_*, works with linker support.  But it isn't very reliable.

-- 
H.J.


Re: RFC: Add STB_GNU_SECONDARY

2012-04-21 Thread Joern Rennecke

Quoting "H.J. Lu" :


Putting our own foo in a section with a special prefix in section name,
like .secondary_*, works with linker support.  But it isn't very reliable.


In what way is requiring linker support for STB_GNU_SECONDARY more reliable
than requiring linker support for .secondary_* sections?


gcc-4.7-20120421 is now available

2012-04-21 Thread gccadmin
Snapshot gcc-4.7-20120421 is now available on
  ftp://gcc.gnu.org/pub/gcc/snapshots/4.7-20120421/
and on various mirrors, see http://gcc.gnu.org/mirrors.html for details.

This snapshot has been generated from the GCC 4.7 SVN branch
with the following options: svn://gcc.gnu.org/svn/gcc/branches/gcc-4_7-branch 
revision 186657

You'll find:

 gcc-4.7-20120421.tar.bz2 Complete GCC

  MD5=2a973f4319e9b8abb46eee2e88c894a8
  SHA1=ad9dcdb20feac35ba0d682f35c13f082d895d83e

Diffs from 4.7-20120414 are available in the diffs/ subdirectory.

When a particular snapshot is ready for public consumption the LATEST-4.7
link is updated and a message is sent to the gcc list.  Please do not use
a snapshot before it has been announced that way.


in-class function definitions?

2012-04-21 Thread rick shelton
How does the compiler handle an in-class function definition?
Example:

// File A.h

class A {
 int foo(void) { return x; }
 int bar(void);
 int x;

}

// File A.cc
#include "A.h"
int A::bar(void) { ... }

How is "foo()" represented in the AST when parsing A.cc?


Thanks,
rick



[RFC] Converting end of loop computations to MIN_EXPRs.

2012-04-21 Thread Ramana Radhakrishnan
Hi,

A colleague noticed that we were not vectorizing loops that had end of
loop computations that were MIN type operations that weren't expressed
in the form of a typical min operation. A transform from  (i < x ) &&
( i < y)  to ( i < min (x, y)) is only something that we should do in
these situations rather than as a general transformation where we
might be able to end up generating slightly better code because the
condition would end up being dependent on an invariant outside the
loop. However in the general case such a transformation would is not
advisable - it's up to the reader to work that out.

#define min(x,y) ((x) <= (y) ? (x) : (y))

void foo (int x, int y, int *  a, int * b, int *c)
{
  int i;

  for (i = 0;
   i < x && i < y;
   /* i < min (x, y); */
   i++)
a[i] = b[i] * c[i];

}

The patch below deals with this case and I'm guessing that it could
also handle more of the comparison cases and come up with more
intelligent choices and should be made quite a lot more robust than
what it is right now.

regards,
Ramana



diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c
index ce5eb20..a529536 100644
--- a/gcc/tree-ssa-loop-im.c
+++ b/gcc/tree-ssa-loop-im.c
@@ -563,6 +563,7 @@ stmt_cost (gimple stmt)

   switch (gimple_assign_rhs_code (stmt))
 {
+case MIN_EXPR:
 case MULT_EXPR:
 case WIDEN_MULT_EXPR:
 case WIDEN_MULT_PLUS_EXPR:
@@ -971,6 +972,124 @@ rewrite_reciprocal (gimple_stmt_iterator *bsi)
   return stmt1;
 }

+/* We look for a sequence that is :
+   def_stmt1  : x = a < b
+   def_stmt2  : y = a < c
+   stmt: z = x & y
+   use_stmt_cond: if ( z != 0)
+
+   where b, c are loop invariant .
+
+   In which case we might as well replace this by :
+
+   t = min (b, c)
+   if ( a < t )
+*/
+
+static gimple
+rewrite_min_test (gimple_stmt_iterator *bsi)
+{
+  gimple stmt, def_stmt_x, def_stmt_y, use_stmt_cond, stmt1;
+  tree x, y, z, a, b, c, var, t, name;
+  use_operand_p use;
+  bool is_lhs_of_comparison = false;
+
+  stmt = gsi_stmt (*bsi);
+  z = gimple_assign_lhs (stmt);
+
+  /* We start by looking at whether x is used in the
+ right set of conditions.  */
+  if (TREE_CODE (z) != SSA_NAME
+  || !single_imm_use (z, &use, &use_stmt_cond)
+  || gimple_code (use_stmt_cond) != GIMPLE_COND)
+return stmt;
+
+  x = gimple_assign_rhs1 (stmt);
+  y = gimple_assign_rhs2 (stmt);
+
+  if (TREE_CODE (x) != SSA_NAME
+  || TREE_CODE (y) != SSA_NAME)
+return stmt;
+
+  def_stmt_x = SSA_NAME_DEF_STMT (x);
+  def_stmt_y = SSA_NAME_DEF_STMT (y);
+
+  /* def_stmt_x and def_stmt_y should be of the
+ form
+
+ x = a cmp b
+ y = a cmp c
+
+ or
+
+ x = b cmp a
+ y = c cmp a
+  */
+  if (!is_gimple_assign (def_stmt_x)
+  || !is_gimple_assign (def_stmt_y)
+  || (gimple_assign_rhs_code (def_stmt_x)
+ != gimple_assign_rhs_code (def_stmt_y)))
+return stmt;
+
+  if (gimple_assign_rhs1 (def_stmt_x) == gimple_assign_rhs1 (def_stmt_y)
+  && (gimple_assign_rhs_code (def_stmt_x) == LT_EXPR
+ || gimple_assign_rhs_code (def_stmt_x) == LE_EXPR))
+{
+  a = gimple_assign_rhs1 (def_stmt_x);
+  b = gimple_assign_rhs2 (def_stmt_x);
+  c = gimple_assign_rhs2 (def_stmt_y);
+  is_lhs_of_comparison = true;
+}
+  else
+{
+  if (gimple_assign_rhs2 (def_stmt_x) == gimple_assign_rhs2 (def_stmt_y)
+ && (gimple_assign_rhs_code (def_stmt_x) == GT_EXPR
+ || gimple_assign_rhs_code (def_stmt_x) == GE_EXPR))
+   {
+ a = gimple_assign_rhs2 (def_stmt_x);
+ b = gimple_assign_rhs1 (def_stmt_x);
+ c = gimple_assign_rhs1 (def_stmt_y);
+   }
+  else
+   return stmt;
+}
+
+  if (outermost_invariant_loop (b, loop_containing_stmt (def_stmt_x)) != NULL
+  && outermost_invariant_loop (c, loop_containing_stmt
(def_stmt_y)) != NULL)
+
+{  
+  if (dump_file)
+   fprintf (dump_file, "Found a potential transformation to min\n");
+
+  /* mintmp = min (b , c).  */
+
+  var = create_tmp_var (TREE_TYPE (b), "mintmp");
+  add_referenced_var (var);
+  t = fold_build2 (MIN_EXPR, TREE_TYPE (b), b, c);
+  stmt1 = gimple_build_assign (var, t);
+  name = make_ssa_name (var, stmt1);
+  gimple_assign_set_lhs (stmt1, name);
+  gimple_cond_set_code (use_stmt_cond, gimple_assign_rhs_code
(def_stmt_x));
+
+
+  if (is_lhs_of_comparison)
+   {
+ gimple_cond_set_lhs (use_stmt_cond, a);
+ gimple_cond_set_rhs (use_stmt_cond, name);
+   }
+  else
+   {
+ gimple_cond_set_lhs (use_stmt_cond, name);
+ gimple_cond_set_rhs (use_stmt_cond, a);
+   }
+  update_stmt (use_stmt_cond);
+  gsi_insert_before (bsi, stmt1, GSI_NEW_STMT);
+  return stmt1;
+}
+
+  return stmt;
+}
+
 /* Check if the pattern at *BSI is a bittest of the form
(A >> B) & 1 != 0 and in this case rewrite it to A & (1 << B) != 0.  */

@@ -1171,6 +1290,11 @@ determine_invariantness_stmt (struct