diff gcc/tree-ssa-phiprop.c @ 55:77e2b8dfacca gcc-4.4.5

update it from 4.4.3 to 4.5.0
author ryoma <e075725@ie.u-ryukyu.ac.jp>
date Fri, 12 Feb 2010 23:39:51 +0900
parents 58ad6c70ea60
children b7f97abdc517
line wrap: on
line diff
--- a/gcc/tree-ssa-phiprop.c	Sun Feb 07 18:28:00 2010 +0900
+++ b/gcc/tree-ssa-phiprop.c	Fri Feb 12 23:39:51 2010 +0900
@@ -90,12 +90,12 @@
 
 
 /* Structure to keep track of the value of a dereferenced PHI result
-   and the set of virtual operands used for that dereference.  */
+   and the virtual operand used for that dereference.  */
 
 struct phiprop_d
 {
   tree value;
-  gimple vop_stmt;
+  tree vuse;
 };
 
 /* Verify if the value recorded for NAME in PHIVN is still valid at
@@ -104,34 +104,27 @@
 static bool
 phivn_valid_p (struct phiprop_d *phivn, tree name, basic_block bb)
 {
-  gimple vop_stmt = phivn[SSA_NAME_VERSION (name)].vop_stmt;
-  ssa_op_iter ui;
-  tree vuse;
+  tree vuse = phivn[SSA_NAME_VERSION (name)].vuse;
+  gimple use_stmt;
+  imm_use_iterator ui2;
+  bool ok = true;
 
-  /* The def stmts of all virtual uses need to be post-dominated
-     by bb.  */
-  FOR_EACH_SSA_TREE_OPERAND (vuse, vop_stmt, ui, SSA_OP_VUSE)
-    {
-      gimple use_stmt;
-      imm_use_iterator ui2;
-      bool ok = true;
+  /* The def stmts of the virtual uses need to be dominated by bb.  */
+  gcc_assert (vuse != NULL_TREE);
 
-      FOR_EACH_IMM_USE_STMT (use_stmt, ui2, vuse)
+  FOR_EACH_IMM_USE_STMT (use_stmt, ui2, vuse)
+    {
+      /* If BB does not dominate a VDEF, the value is invalid.  */
+      if ((gimple_vdef (use_stmt) != NULL_TREE
+	   || gimple_code (use_stmt) == GIMPLE_PHI)
+	  && !dominated_by_p (CDI_DOMINATORS, gimple_bb (use_stmt), bb))
 	{
-	  /* If BB does not dominate a VDEF, the value is invalid.  */
-	  if ((!ZERO_SSA_OPERANDS (use_stmt, SSA_OP_VDEF)
-	       || gimple_code (use_stmt) == GIMPLE_PHI)
-	      && !dominated_by_p (CDI_DOMINATORS, gimple_bb (use_stmt), bb))
-	    {
-	      ok = false;
-	      BREAK_FROM_IMM_USE_STMT (ui2);
-	    }
+	  ok = false;
+	  BREAK_FROM_IMM_USE_STMT (ui2);
 	}
-      if (!ok)
-	return false;
     }
 
-  return true;
+  return ok;
 }
 
 /* Insert a new phi node for the dereference of PHI at basic_block
@@ -154,25 +147,45 @@
   res = gimple_assign_lhs (use_stmt);
   SSA_NAME_DEF_STMT (res) = new_phi = create_phi_node (res, bb);
 
+  if (dump_file && (dump_flags & TDF_DETAILS))
+    {
+      fprintf (dump_file, "Inserting PHI for result of load ");
+      print_gimple_stmt (dump_file, use_stmt, 0, 0);
+    }
+
   /* Add PHI arguments for each edge inserting loads of the
      addressable operands.  */
   FOR_EACH_EDGE (e, ei, bb->preds)
     {
       tree old_arg, new_var;
       gimple tmp;
+      source_location locus;
 
       old_arg = PHI_ARG_DEF_FROM_EDGE (phi, e);
+      locus = gimple_phi_arg_location_from_edge (phi, e);
       while (TREE_CODE (old_arg) == SSA_NAME
 	     && (SSA_NAME_VERSION (old_arg) >= n
 	         || phivn[SSA_NAME_VERSION (old_arg)].value == NULL_TREE))
 	{
 	  gimple def_stmt = SSA_NAME_DEF_STMT (old_arg);
 	  old_arg = gimple_assign_rhs1 (def_stmt);
+	  locus = gimple_location (def_stmt);
 	}
 
       if (TREE_CODE (old_arg) == SSA_NAME)
-	/* Reuse a formerly created dereference.  */
-	new_var = phivn[SSA_NAME_VERSION (old_arg)].value;
+	{
+	  if (dump_file && (dump_flags & TDF_DETAILS))
+	    {
+	      fprintf (dump_file, "  for edge defining ");
+	      print_generic_expr (dump_file, PHI_ARG_DEF_FROM_EDGE (phi, e), 0);
+	      fprintf (dump_file, " reusing PHI result ");
+	      print_generic_expr (dump_file,
+				  phivn[SSA_NAME_VERSION (old_arg)].value, 0);
+	      fprintf (dump_file, "\n");
+	    }
+	  /* Reuse a formerly created dereference.  */
+	  new_var = phivn[SSA_NAME_VERSION (old_arg)].value;
+	}
       else
 	{
 	  gcc_assert (TREE_CODE (old_arg) == ADDR_EXPR);
@@ -186,18 +199,28 @@
 	  add_referenced_var (new_var);
 	  new_var = make_ssa_name (new_var, tmp);
 	  gimple_assign_set_lhs (tmp, new_var);
+	  gimple_set_location (tmp, locus);
 
 	  gsi_insert_on_edge (e, tmp);
+	  update_stmt (tmp);
 
-	  update_stmt (tmp);
-	  mark_symbols_for_renaming (tmp);
+	  if (dump_file && (dump_flags & TDF_DETAILS))
+	    {
+	      fprintf (dump_file, "  for edge defining ");
+	      print_generic_expr (dump_file, PHI_ARG_DEF_FROM_EDGE (phi, e), 0);
+	      fprintf (dump_file, " inserting load ");
+	      print_gimple_stmt (dump_file, tmp, 0, 0);
+	    }
 	}
 
-      add_phi_arg (new_phi, new_var, e);
+      add_phi_arg (new_phi, new_var, e, locus);
     }
 
   update_stmt (new_phi);
 
+  if (dump_file && (dump_flags & TDF_DETAILS))
+    print_gimple_stmt (dump_file, new_phi, 0, 0);
+
   return res;
 }
 
@@ -228,8 +251,7 @@
   ssa_op_iter i;
   bool phi_inserted;
 
-  if (MTAG_P (SSA_NAME_VAR (ptr))
-      || !POINTER_TYPE_P (TREE_TYPE (ptr))
+  if (!POINTER_TYPE_P (TREE_TYPE (ptr))
       || !is_gimple_reg_type (TREE_TYPE (TREE_TYPE (ptr))))
     return false;
 
@@ -254,6 +276,7 @@
 	   /* Avoid to have to decay *&a to a[0] later.  */
 	   || !is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (arg, 0))))
 	  && !(TREE_CODE (arg) == SSA_NAME
+	       && SSA_NAME_VERSION (arg) < n
 	       && phivn[SSA_NAME_VERSION (arg)].value != NULL_TREE
 	       && phivn_valid_p (phivn, arg, bb)))
 	return false;
@@ -270,29 +293,27 @@
   phi_inserted = false;
   FOR_EACH_IMM_USE_STMT (use_stmt, ui, ptr)
     {
-      ssa_op_iter ui2;
+      gimple def_stmt;
       tree vuse;
 
       /* Check whether this is a load of *ptr.  */
       if (!(is_gimple_assign (use_stmt)
-	    && TREE_CODE (gimple_assign_lhs (use_stmt)) == SSA_NAME 
+	    && TREE_CODE (gimple_assign_lhs (use_stmt)) == SSA_NAME
 	    && gimple_assign_rhs_code (use_stmt) == INDIRECT_REF
 	    && TREE_OPERAND (gimple_assign_rhs1 (use_stmt), 0) == ptr
 	    /* We cannot replace a load that may throw or is volatile.  */
 	    && !stmt_can_throw_internal (use_stmt)))
 	continue;
 
-      /* Check if we can move the loads.  The def stmts of all virtual uses
-	 need to be post-dominated by bb.  */
-      FOR_EACH_SSA_TREE_OPERAND (vuse, use_stmt, ui2, SSA_OP_VUSE)
-	{
-	  gimple def_stmt = SSA_NAME_DEF_STMT (vuse);
-	  if (!SSA_NAME_IS_DEFAULT_DEF (vuse)
-	      && (gimple_bb (def_stmt) == bb
-		  || !dominated_by_p (CDI_DOMINATORS,
-				      bb, gimple_bb (def_stmt))))
-	    goto next;
-	}
+      /* Check if we can move the loads.  The def stmt of the virtual use
+	 needs to be in a different basic block dominating bb.  */
+      vuse = gimple_vuse (use_stmt);
+      def_stmt = SSA_NAME_DEF_STMT (vuse);
+      if (!SSA_NAME_IS_DEFAULT_DEF (vuse)
+	  && (gimple_bb (def_stmt) == bb
+	      || !dominated_by_p (CDI_DOMINATORS,
+				  bb, gimple_bb (def_stmt))))
+	goto next;
 
       /* Found a proper dereference.  Insert a phi node if this
 	 is the first load transformation.  */
@@ -302,7 +323,7 @@
 
 	  /* Remember the value we created for *ptr.  */
 	  phivn[SSA_NAME_VERSION (ptr)].value = res;
-	  phivn[SSA_NAME_VERSION (ptr)].vop_stmt = use_stmt;
+	  phivn[SSA_NAME_VERSION (ptr)].vuse = vuse;
 
 	  /* Remove old stmt.  The phi is taken care of by DCE, if we
 	     want to delete it here we also have to delete all intermediate
@@ -327,41 +348,35 @@
   return phi_inserted;
 }
 
-/* Helper walking the dominator tree starting from BB and processing
-   phi nodes with global data PHIVN and N.  */
-
-static bool
-tree_ssa_phiprop_1 (basic_block bb, struct phiprop_d *phivn, size_t n)
-{
-  bool did_something = false; 
-  basic_block son;
-  gimple_stmt_iterator gsi;
-
-  for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
-    did_something |= propagate_with_phi (bb, gsi_stmt (gsi), phivn, n);
-
-  for (son = first_dom_son (CDI_DOMINATORS, bb);
-       son;
-       son = next_dom_son (CDI_DOMINATORS, son))
-    did_something |= tree_ssa_phiprop_1 (son, phivn, n);
-
-  return did_something;
-}
-
 /* Main entry for phiprop pass.  */
 
 static unsigned int
 tree_ssa_phiprop (void)
 {
+  VEC(basic_block, heap) *bbs;
   struct phiprop_d *phivn;
+  bool did_something = false;
+  basic_block bb;
+  gimple_stmt_iterator gsi;
+  unsigned i;
+  size_t n;
 
   calculate_dominance_info (CDI_DOMINATORS);
 
-  phivn = XCNEWVEC (struct phiprop_d, num_ssa_names);
+  n = num_ssa_names;
+  phivn = XCNEWVEC (struct phiprop_d, n);
 
-  if (tree_ssa_phiprop_1 (ENTRY_BLOCK_PTR, phivn, num_ssa_names))
+  /* Walk the dominator tree in preorder.  */
+  bbs = get_all_dominated_blocks (CDI_DOMINATORS,
+				  single_succ (ENTRY_BLOCK_PTR));
+  for (i = 0; VEC_iterate (basic_block, bbs, i, bb); ++i)
+    for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+      did_something |= propagate_with_phi (bb, gsi_stmt (gsi), phivn, n);
+
+  if (did_something)
     gsi_commit_edge_inserts ();
 
+  VEC_free (basic_block, heap, bbs);
   free (phivn);
 
   return 0;
@@ -370,10 +385,10 @@
 static bool
 gate_phiprop (void)
 {
-  return 1;
+  return flag_tree_phiprop;
 }
 
-struct gimple_opt_pass pass_phiprop = 
+struct gimple_opt_pass pass_phiprop =
 {
  {
   GIMPLE_PASS,