This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH, 4.5] Make fwprop find out that non-virtual constant member pointers are non-virtual


Hi,

this is a second attempt to partially fix PR 3713 - partial in the
sence that it does away with the rather embarrasing run-time
condition, for more details see the thread that started with the first
attempt:

http://gcc.gnu.org/ml/gcc-patches/2009-03/msg00536.html

The patch below takes the core of the fix to fold-const.c by partially
undoing the fix  for PR 35705.  I believe that  this shouls still work
on any target on which member pointers work.  I have not verified on a
hppa yet because gcc61 was down  until recently.  I will test it there
tomorrow.  The hunks in tree-ssa-forwprop.c is not necessary (a tleast
not for the  test case), FRE would manage to get  rid of the condition
even without it.  However, this way  we get rid of it sooner (and hey,
once we might be able to do so in the early fwprop).

I have bootstrapped and tested this on x86_64-linux.  Provided it does
not reintroduce PR 35705, is it OK for 4.5?

Thanks,

Martin

2009-03-24  Martin Jambor  <mjambor@suse.cz>

	* fold-const.c (get_pointer_modulus_and_residue): New parameter
	allow_func_align.
	(fold_binary): Allow function decl aligment consideration is the
	second argument is integer constant one.
	* tree-ssa-forwprop.c (simplify_bitwise_and): New function.
	(tree_ssa_forward_propagate_single_use_vars): Handle assing statements
	with BIT_AND_EXPR on the RHS by calling simplify_bitwise_and.

Index: iinln/gcc/tree-ssa-forwprop.c
===================================================================
--- iinln.orig/gcc/tree-ssa-forwprop.c
+++ iinln/gcc/tree-ssa-forwprop.c
@@ -147,6 +147,14 @@ along with GCC; see the file COPYING3.
 
      ptr2 = &x[index];
 
+  Or
+    ssa = (int) decl
+    res = ssa & 1
+
+  Provided that decl has known alignment >= 2, will get turned into
+
+    res = 0
+
   We also propagate casts into SWITCH_EXPR and COND_EXPR conditions to
   allow us to remove the cast and {NOT_EXPR,NEG_EXPR} into a subsequent
   {NOT_EXPR,NEG_EXPR}.
@@ -1124,6 +1132,42 @@ simplify_gimple_switch (gimple stmt)
     }
 }
 
+/* Run bitwise and assignments throug the folder.  If the first argument is an
+   ssa name that is itself a result of a typecast of an ADDR_EXPR to an
+   integer, feed the ADDR_EXPR to the folder rather than the ssa name.
+*/
+
+static void
+simplify_bitwise_and (gimple_stmt_iterator *gsi, gimple stmt)
+{
+  tree res;
+  tree arg1 = gimple_assign_rhs1 (stmt);
+  tree arg2 = gimple_assign_rhs2 (stmt);
+
+  if (TREE_CODE (arg1) == SSA_NAME && !SSA_NAME_IS_DEFAULT_DEF (arg1))
+    {
+      gimple def = SSA_NAME_DEF_STMT (arg1);
+
+      if (gimple_assign_cast_p (def)
+	  && INTEGRAL_TYPE_P (gimple_expr_type (def)))
+	{
+	  tree op = gimple_assign_rhs1 (def);
+
+	  if (TREE_CODE (op) == ADDR_EXPR)
+	    arg1 = op;
+	}
+    }
+
+  res = fold_binary (BIT_AND_EXPR, TREE_TYPE (gimple_assign_lhs (stmt)),
+		     arg1, arg2);
+  if (res)
+    {
+      gimple_assign_set_rhs_from_tree (gsi, res);
+      update_stmt (stmt);
+    }
+  return;
+}
+
 /* Main entry point for the forward propagation optimizer.  */
 
 static unsigned int
@@ -1206,6 +1250,11 @@ tree_ssa_forward_propagate_single_use_va
 		  else
 		    gsi_next (&gsi);
 		}
+	      else if (gimple_assign_rhs_code (stmt) == BIT_AND_EXPR)
+		{
+		  simplify_bitwise_and (&gsi, stmt);
+		  gsi_next (&gsi);
+		}
 	      else
 		gsi_next (&gsi);
 	    }
Index: iinln/gcc/testsuite/g++.dg/tree-ssa/fwprop-align.C
===================================================================
--- /dev/null
+++ iinln/gcc/testsuite/g++.dg/tree-ssa/fwprop-align.C
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-forwprop2" } */
+
+struct A
+{
+  void foo ()
+  {
+  }
+};
+
+int main()
+{
+  void (A::* const p)() = & A::foo;
+  A a;
+  (a.*p)();
+}
+
+/* We should eliminate the check if p points to a virtual function. */
+/* { dg-final { scan-tree-dump-times "& 1" 0 "forwprop2" } } */
+/* { dg-final { cleanup-tree-dump "forwprop2" } } */
Index: iinln/gcc/fold-const.c
===================================================================
--- iinln.orig/gcc/fold-const.c
+++ iinln/gcc/fold-const.c
@@ -9590,10 +9590,15 @@ fold_mult_zconjz (tree type, tree expr)
    0 <= N < M as is common.  In general, the precise value of P is unknown.
    M is chosen as large as possible such that constant N can be determined.
 
-   Returns M and sets *RESIDUE to N.  */
+   Returns M and sets *RESIDUE to N.
+
+   If ALLOW_FUNC_ALIGN is true, do take functions' DECL_ALIGN_UNIT into
+   account.  This is not always possible due to PR 35705.
+ */
 
 static unsigned HOST_WIDE_INT
-get_pointer_modulus_and_residue (tree expr, unsigned HOST_WIDE_INT *residue)
+get_pointer_modulus_and_residue (tree expr, unsigned HOST_WIDE_INT *residue,
+				 bool allow_func_align)
 {
   enum tree_code code;
 
@@ -9623,7 +9628,8 @@ get_pointer_modulus_and_residue (tree ex
 	    }
 	}
 
-      if (DECL_P (expr) && TREE_CODE (expr) != FUNCTION_DECL)
+      if (DECL_P (expr)
+	  && (allow_func_align || TREE_CODE (expr) != FUNCTION_DECL))
 	return DECL_ALIGN_UNIT (expr);
     }
   else if (code == POINTER_PLUS_EXPR)
@@ -9634,7 +9640,8 @@ get_pointer_modulus_and_residue (tree ex
       
       op0 = TREE_OPERAND (expr, 0);
       STRIP_NOPS (op0);
-      modulus = get_pointer_modulus_and_residue (op0, residue);
+      modulus = get_pointer_modulus_and_residue (op0, residue,
+						 allow_func_align);
 
       op1 = TREE_OPERAND (expr, 1);
       STRIP_NOPS (op1);
@@ -11274,7 +11281,8 @@ fold_binary (enum tree_code code, tree t
 	  unsigned HOST_WIDE_INT modulus, residue;
 	  unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (arg1);
 
-	  modulus = get_pointer_modulus_and_residue (arg0, &residue);
+	  modulus = get_pointer_modulus_and_residue (arg0, &residue,
+						     integer_onep (arg1));
 
 	  /* This works because modulus is a power of 2.  If this weren't the
 	     case, we'd have to replace it by its greatest power-of-2


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]