From 2ea9dc6459761bae70146f8ea85436f70eca25eb Mon Sep 17 00:00:00 2001
From: Richard Guenther <rguenther@suse.de>
Date: Wed, 7 Apr 2010 15:31:37 +0000
Subject: [PATCH] ipa-reference.c (mark_load): Use get_base_address.

2010-04-07  Richard Guenther  <rguenther@suse.de>

	* ipa-reference.c (mark_load): Use get_base_address.
	(mark_store): Likewise.

	* tree-ssa-ccp.c (gimplify_and_update_call_from_tree): Avoid
	inserting GIMPLE_NOPs into the IL.
	* tree-ssa-structalias.c (get_constraint_for_component_ref):
	Explicitly strip handled components and indirect references.

	* fold-const.c (fold_unary_loc): Do not strip qualifiers when
	folding address expressions.
	* gimple.c (gimple_ior_addresses_taken_1): Use get_base_address.
	* tree-ssa-alias.c (decl_refs_may_alias_p): Do not use
	operand_equal_p to compare decls.
	(ptr_deref_may_alias_decl_p): Likewise.
	* tree-ssa-operands.c (get_asm_expr_operands): Simplify
	* tree-ssa-forwprop.c (forward_propagate_into_gimple_cond):
	Handle reversed comparison ops.
	* tree-sra.c (asm_visit_addr): Use get_base_address.
	* ipa-prop.c (visit_store_addr_for_mod_analysis): Use
	get_base_address.
	* ipa-reference.c (mark_address): Use get_base_address.

From-SVN: r158069
---
 gcc/ChangeLog              | 24 ++++++++++++++++++++++++
 gcc/fold-const.c           |  5 +++--
 gcc/gimple.c               |  6 +++---
 gcc/ipa-prop.c             |  4 +++-
 gcc/ipa-reference.c        | 12 +++++++-----
 gcc/tree-sra.c             |  4 +++-
 gcc/tree-ssa-alias.c       |  4 ++--
 gcc/tree-ssa-ccp.c         | 26 ++++++++++++++++++--------
 gcc/tree-ssa-forwprop.c    | 22 ++++++++++++----------
 gcc/tree-ssa-operands.c    | 12 ++----------
 gcc/tree-ssa-structalias.c |  3 ++-
 11 files changed, 79 insertions(+), 43 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 20aa611e134d..693d69de50a3 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,27 @@
+2010-04-07  Richard Guenther  <rguenther@suse.de>
+
+	* ipa-reference.c (mark_load): Use get_base_address.
+	(mark_store): Likewise.
+
+	* tree-ssa-ccp.c (gimplify_and_update_call_from_tree): Avoid
+	inserting GIMPLE_NOPs into the IL.
+	* tree-ssa-structalias.c (get_constraint_for_component_ref):
+	Explicitly strip handled components and indirect references.
+  
+	* fold-const.c (fold_unary_loc): Do not strip qualifiers when
+	folding address expressions.
+	* gimple.c (gimple_ior_addresses_taken_1): Use get_base_address.
+	* tree-ssa-alias.c (decl_refs_may_alias_p): Do not use
+	operand_equal_p to compare decls.
+	(ptr_deref_may_alias_decl_p): Likewise.
+	* tree-ssa-operands.c (get_asm_expr_operands): Simplify
+	* tree-ssa-forwprop.c (forward_propagate_into_gimple_cond):
+	Handle reversed comparison ops.
+	* tree-sra.c (asm_visit_addr): Use get_base_address.
+	* ipa-prop.c (visit_store_addr_for_mod_analysis): Use
+	get_base_address.
+	* ipa-reference.c (mark_address): Use get_base_address.
+
 2010-04-07  Richard Guenther  <rguenther@suse.de>
 
 	* tree-ssa-forwprop.c (forward_propagate_addr_expr):
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 62c86254ea12..03598a59a6f0 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -8561,10 +8561,11 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0)
 				      &mode, &unsignedp, &volatilep, false);
 	  /* If the reference was to a (constant) zero offset, we can use
 	     the address of the base if it has the same base type
-	     as the result type.  */
+	     as the result type and the pointer type is unqualified.  */
 	  if (! offset && bitpos == 0
-	      && TYPE_MAIN_VARIANT (TREE_TYPE (type))
+	      && (TYPE_MAIN_VARIANT (TREE_TYPE (type))
 		  == TYPE_MAIN_VARIANT (TREE_TYPE (base)))
+	      && TYPE_QUALS (type) == TYPE_UNQUALIFIED)
 	    return fold_convert_loc (loc, type,
 				     build_fold_addr_expr_loc (loc, base));
         }
diff --git a/gcc/gimple.c b/gcc/gimple.c
index 717a020296df..ae0be4e86bc9 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -4532,9 +4532,9 @@ gimple_ior_addresses_taken_1 (gimple stmt ATTRIBUTE_UNUSED,
 			      tree addr, void *data)
 {
   bitmap addresses_taken = (bitmap)data;
-  while (handled_component_p (addr))
-    addr = TREE_OPERAND (addr, 0);
-  if (DECL_P (addr))
+  addr = get_base_address (addr);
+  if (addr
+      && DECL_P (addr))
     {
       bitmap_set_bit (addresses_taken, DECL_UID (addr));
       return true;
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index a3ab8b3b2875..82a78a3b60e9 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -199,7 +199,9 @@ visit_store_addr_for_mod_analysis (gimple stmt ATTRIBUTE_UNUSED,
 {
   struct ipa_node_params *info = (struct ipa_node_params *) data;
 
-  if (TREE_CODE (op) == PARM_DECL)
+  op = get_base_address (op);
+  if (op
+      && TREE_CODE (op) == PARM_DECL)
     {
       int index = ipa_get_param_decl_index (info, op);
       gcc_assert (index >= 0);
diff --git a/gcc/ipa-reference.c b/gcc/ipa-reference.c
index cc790fdbc12c..9eac3b10e829 100644
--- a/gcc/ipa-reference.c
+++ b/gcc/ipa-reference.c
@@ -352,9 +352,9 @@ static bool
 mark_address (gimple stmt ATTRIBUTE_UNUSED, tree addr,
 	      void *data ATTRIBUTE_UNUSED)
 {
-  while (handled_component_p (addr))
-    addr = TREE_OPERAND (addr, 0);
-  mark_address_taken (addr);
+  addr = get_base_address (addr);
+  if (addr)
+    mark_address_taken (addr);
   return false;
 }
 
@@ -364,7 +364,8 @@ static bool
 mark_load (gimple stmt ATTRIBUTE_UNUSED, tree t, void *data)
 {
   ipa_reference_local_vars_info_t local = (ipa_reference_local_vars_info_t)data;
-  if (TREE_CODE (t) == VAR_DECL
+  t = get_base_address (t);
+  if (t && TREE_CODE (t) == VAR_DECL
       && has_proper_scope_for_analysis (t))
     bitmap_set_bit (local->statics_read, DECL_UID (t));
   return false;
@@ -376,7 +377,8 @@ static bool
 mark_store (gimple stmt ATTRIBUTE_UNUSED, tree t, void *data)
 {
   ipa_reference_local_vars_info_t local = (ipa_reference_local_vars_info_t)data;
-  if (TREE_CODE (t) == VAR_DECL
+  t = get_base_address (t);
+  if (t && TREE_CODE (t) == VAR_DECL
       && has_proper_scope_for_analysis (t))
     {
       if (local)
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index d4adb61ae6a5..56531687f34c 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -1066,7 +1066,9 @@ static bool
 asm_visit_addr (gimple stmt ATTRIBUTE_UNUSED, tree op,
 		void *data ATTRIBUTE_UNUSED)
 {
-  if (DECL_P (op))
+  op = get_base_address (op);
+  if (op
+      && DECL_P (op))
     disqualify_candidate (op, "Non-scalarizable GIMPLE_ASM operand.");
 
   return false;
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index 47d611c9cac5..282148ce5e9b 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -189,7 +189,7 @@ ptr_deref_may_alias_decl_p (tree ptr, tree decl)
 	ptr = TREE_OPERAND (base, 0);
       else if (base
 	       && SSA_VAR_P (base))
-	return operand_equal_p (base, decl, 0);
+	return base == decl;
       else if (base
 	       && CONSTANT_CLASS_P (base))
 	return false;
@@ -629,7 +629,7 @@ decl_refs_may_alias_p (tree base1,
   gcc_assert (SSA_VAR_P (base1) && SSA_VAR_P (base2));
 
   /* If both references are based on different variables, they cannot alias.  */
-  if (!operand_equal_p (base1, base2, 0))
+  if (base1 != base2)
     return false;
 
   /* If both references are based on the same variable, they cannot alias if
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index fcfdd18d1bfd..f0106ebc9403 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -3354,6 +3354,7 @@ gimplify_and_update_call_from_tree (gimple_stmt_iterator *si_p, tree expr)
   gimple_stmt_iterator i;
   gimple_seq stmts = gimple_seq_alloc();
   struct gimplify_ctx gctx;
+  gimple last = NULL;
 
   stmt = gsi_stmt (*si_p);
 
@@ -3375,22 +3376,31 @@ gimplify_and_update_call_from_tree (gimple_stmt_iterator *si_p, tree expr)
 
   /* The replacement can expose previously unreferenced variables.  */
   for (i = gsi_start (stmts); !gsi_end_p (i); gsi_next (&i))
-  {
-    new_stmt = gsi_stmt (i);
-    find_new_referenced_vars (new_stmt);
-    gsi_insert_before (si_p, new_stmt, GSI_NEW_STMT);
-    mark_symbols_for_renaming (new_stmt);
-    gsi_next (si_p);
-  }
+    {
+      if (last)
+	{
+	  gsi_insert_before (si_p, last, GSI_NEW_STMT);
+	  gsi_next (si_p);
+	}
+      new_stmt = gsi_stmt (i);
+      find_new_referenced_vars (new_stmt);
+      mark_symbols_for_renaming (new_stmt);
+      last = new_stmt;
+    }
 
   if (lhs == NULL_TREE)
     {
-      new_stmt = gimple_build_nop ();
       unlink_stmt_vdef (stmt);
       release_defs (stmt);
+      new_stmt = last;
     }
   else
     {
+      if (last)
+	{
+	  gsi_insert_before (si_p, last, GSI_NEW_STMT);
+	  gsi_next (si_p);
+	}
       new_stmt = gimple_build_assign (lhs, tmp);
       gimple_set_vuse (new_stmt, gimple_vuse (stmt));
       gimple_set_vdef (new_stmt, gimple_vdef (stmt));
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index d7d378b0f929..fc40bf46eac2 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -398,25 +398,27 @@ forward_propagate_into_gimple_cond (gimple stmt)
 
   do {
     tree tmp = NULL_TREE;
-    tree name, rhs0 = NULL_TREE, rhs1 = NULL_TREE;
+    tree name = NULL_TREE, rhs0 = NULL_TREE, rhs1 = NULL_TREE;
     gimple def_stmt;
     bool single_use0_p = false, single_use1_p = false;
     enum tree_code code = gimple_cond_code (stmt);
 
     /* We can do tree combining on SSA_NAME and comparison expressions.  */
-    if (TREE_CODE_CLASS (gimple_cond_code (stmt)) == tcc_comparison
-        && TREE_CODE (gimple_cond_lhs (stmt)) == SSA_NAME)
+    if (TREE_CODE_CLASS (gimple_cond_code (stmt)) == tcc_comparison)
       {
 	/* For comparisons use the first operand, that is likely to
 	   simplify comparisons against constants.  */
-	name = gimple_cond_lhs (stmt);
-	def_stmt = get_prop_source_stmt (name, false, &single_use0_p);
-	if (def_stmt && can_propagate_from (def_stmt))
+	if (TREE_CODE (gimple_cond_lhs (stmt)) == SSA_NAME)
 	  {
-	    tree op1 = gimple_cond_rhs (stmt);
-	    rhs0 = rhs_to_tree (TREE_TYPE (op1), def_stmt);
-	    tmp = combine_cond_expr_cond (loc, code, boolean_type_node, rhs0,
-					  op1, !single_use0_p);
+	    name = gimple_cond_lhs (stmt);
+	    def_stmt = get_prop_source_stmt (name, false, &single_use0_p);
+	    if (def_stmt && can_propagate_from (def_stmt))
+	      {
+		tree op1 = gimple_cond_rhs (stmt);
+		rhs0 = rhs_to_tree (TREE_TYPE (op1), def_stmt);
+		tmp = combine_cond_expr_cond (loc, code, boolean_type_node,
+					      rhs0, op1, !single_use0_p);
+	      }
 	  }
 	/* If that wasn't successful, try the second operand.  */
 	if (tmp == NULL_TREE
diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c
index de2985f1b03b..cd8b6f8935a9 100644
--- a/gcc/tree-ssa-operands.c
+++ b/gcc/tree-ssa-operands.c
@@ -798,11 +798,7 @@ get_asm_expr_operands (gimple stmt)
       /* Memory operands are addressable.  Note that STMT needs the
 	 address of this operand.  */
       if (!allows_reg && allows_mem)
-	{
-	  tree t = get_base_address (TREE_VALUE (link));
-	  if (t && DECL_P (t))
-	    mark_address_taken (t);
-	}
+	mark_address_taken (TREE_VALUE (link));
 
       get_expr_operands (stmt, &TREE_VALUE (link), opf_def);
     }
@@ -818,11 +814,7 @@ get_asm_expr_operands (gimple stmt)
       /* Memory operands are addressable.  Note that STMT needs the
 	 address of this operand.  */
       if (!allows_reg && allows_mem)
-	{
-	  tree t = get_base_address (TREE_VALUE (link));
-	  if (t && DECL_P (t))
-	    mark_address_taken (t);
-	}
+	mark_address_taken (TREE_VALUE (link));
 
       get_expr_operands (stmt, &TREE_VALUE (link), 0);
     }
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index 1516634b8713..2384099a242b 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -2951,7 +2951,8 @@ get_constraint_for_component_ref (tree t, VEC(ce_s, heap) **results,
   /* Some people like to do cute things like take the address of
      &0->a.b */
   forzero = t;
-  while (!SSA_VAR_P (forzero) && !CONSTANT_CLASS_P (forzero))
+  while (handled_component_p (forzero)
+	 || INDIRECT_REF_P (forzero))
     forzero = TREE_OPERAND (forzero, 0);
 
   if (CONSTANT_CLASS_P (forzero) && integer_zerop (forzero))
-- 
GitLab