On May 30, 2011, Alexandre Oliva <aol...@redhat.com> wrote:

> On May 30, 2011, Alexandre Oliva <aol...@redhat.com> wrote:
>> 3. expand dominators before dominated blocks, so that DEFs of
>> replaceable SSA names are expanded before their uses.  Expand them when
>> they're encountered, but not requiring a REG as a result.  Save the RTL
>> expression that results from the expansion for use in debug insns and at
>> the non-debug use.

> This patch addresses some of the problems in 2, avoiding expanding code
> out of order within a block, and (hopefully) ensuring that, expanding
> dominators before dominatedblocks, DEFs are expanded before USEs.  There
> is a theoretical possibility that a USE may be expanded before a DEF,
> depending on internal details of out-of-ssa, but should this ever
> happen, we'll get a failed assertion, and then disabling TER will work
> around the problem.

I also posted the wrong patch upthread for this variant.  The one I
posted didn't work at all, because it contained a last-minute
optimization that changed the expansion of replaceable stmts from
EXPAND_NORMAL to EXPAND_SUM.  IIRC the former always yielded a pseudo,
whereas the former enabled replacements, but it also exposed the need
for better handling of non-general_operands when the use expects one.

This revised and retested version also drops the reordering of the
expansion of basic blocks, that Matz pointed out was unnecessary, and
switches to an array rather than a pointer_map to record the expansions.

for  gcc/ChangeLog
from  Alexandre Oliva  <aol...@redhat.com>

	PR debug/48866
	* cfgexpand.c (def_expansions): New.
	(def_expansion_recent_tree, def_expansion_recent_rtx): New.
	(def_expansions_init, def_expansions_fini): New.
	(def_has_expansion_ptr, def_get_expansion_ptr): New.
	(expand_debug_expr): Use recorded expansion if available.
	(expand_gimple_basic_block): Prepare to record expansion of
	replaceable defs.  Change return type to void.
	(gimple_expand_cfg): Initialize and finalize expansions cache.
	Expand dominator blocks before dominated.
	* expr.c (expand_expr_real_1): Use recorded expansion of
	replaceable defs.
	* expr.h (def_has_expansion_ptr): Declare.

Index: gcc/cfgexpand.c
===================================================================
--- gcc/cfgexpand.c.orig	2011-06-01 20:39:58.244953408 -0300
+++ gcc/cfgexpand.c	2011-06-01 21:44:38.005879125 -0300
@@ -2337,6 +2337,42 @@ convert_debug_memory_address (enum machi
   return x;
 }
 
+/* Map replaceable SSA_NAMEs to their RTL expansions.  */
+static rtx *def_expansions;
+
+/* Initialize the def_expansions data structure.  This is to be called
+   before expansion of a function starts.  */
+
+static void
+def_expansions_init (void)
+{
+  gcc_checking_assert (!def_expansions);
+  def_expansions = XCNEWVEC (rtx, num_ssa_names);
+}
+
+/* Finalize the def_expansions data structure.  This is to be called
+   at the end of the expansion of a function.  */
+
+static void
+def_expansions_fini (void)
+{
+  gcc_checking_assert (def_expansions);
+  XDELETEVEC (def_expansions);
+  def_expansions = NULL;
+}
+
+/* Return a pointer to the rtx expanded from EXP.  EXP must be a
+   replaceable SSA_NAME.  */
+
+rtx *
+def_get_expansion_ptr (tree exp)
+{
+  gcc_checking_assert (def_expansions);
+  gcc_checking_assert (TREE_CODE (exp) == SSA_NAME);
+  gcc_checking_assert (bitmap_bit_p (SA.values, SSA_NAME_VERSION (exp)));
+  return &def_expansions[SSA_NAME_VERSION (exp)];
+}
+
 /* Return an RTX equivalent to the value of the tree expression
    EXP.  */
 
@@ -3131,7 +3167,16 @@ expand_debug_expr (tree exp)
 	gimple g = get_gimple_for_ssa_name (exp);
 	if (g)
 	  {
-	    op0 = expand_debug_expr (gimple_assign_rhs_to_tree (g));
+	    rtx *xp = def_get_expansion_ptr (exp);
+
+	    if (xp)
+	      op0 = copy_rtx (*xp);
+	    else
+	      op0 = NULL;
+
+	    if (!op0)
+	      op0 = expand_debug_expr (gimple_assign_rhs_to_tree (g));
+
 	    if (!op0)
 	      return NULL;
 	  }
@@ -3618,20 +3663,38 @@ expand_gimple_basic_block (basic_block b
 	    }
 	  else
 	    {
+	      rtx *xp = NULL;
 	      def_operand_p def_p;
 	      def_p = SINGLE_SSA_DEF_OPERAND (stmt, SSA_OP_DEF);
 
-	      if (def_p != NULL)
+	      /* Ignore this stmt if it is in the list of
+		 replaceable expressions.  */
+	      if (def_p != NULL
+		  && SA.values
+		  && bitmap_bit_p (SA.values,
+				   SSA_NAME_VERSION (DEF_FROM_PTR (def_p))))
 		{
-		  /* Ignore this stmt if it is in the list of
-		     replaceable expressions.  */
-		  if (SA.values
-		      && bitmap_bit_p (SA.values,
-				       SSA_NAME_VERSION (DEF_FROM_PTR (def_p))))
-		    continue;
+		  tree def = DEF_FROM_PTR (def_p);
+		  gimple g = get_gimple_for_ssa_name (def);
+		  rtx retval;
+
+		  last = get_last_insn ();
+
+		  retval = expand_expr (gimple_assign_rhs_to_tree (g),
+					NULL_RTX, VOIDmode, EXPAND_SUM);
+
+		  xp = def_get_expansion_ptr (def);
+		  gcc_checking_assert (!*xp);
+		  *xp = retval;
 		}
-	      last = expand_gimple_stmt (stmt);
+	      else
+		last = expand_gimple_stmt (stmt);
 	      maybe_dump_rtl_for_gimple_stmt (stmt, last);
+	      if (xp && dump_file && (dump_flags & TDF_DETAILS))
+		{
+		  fprintf (dump_file, "\n=> ");
+		  print_rtl (dump_file, *xp);
+		}
 	    }
 	}
     }
@@ -4112,11 +4175,14 @@ gimple_expand_cfg (void)
     e->flags &= ~EDGE_EXECUTABLE;
 
   lab_rtx_for_bb = pointer_map_create ();
+  def_expansions_init ();
+
   FOR_BB_BETWEEN (bb, init_block->next_bb, EXIT_BLOCK_PTR, next_bb)
     bb = expand_gimple_basic_block (bb);
 
   if (MAY_HAVE_DEBUG_INSNS)
     expand_debug_locations ();
+  def_expansions_fini ();
 
   execute_free_datastructures ();
   timevar_push (TV_OUT_OF_SSA);
Index: gcc/expr.c
===================================================================
--- gcc/expr.c.orig	2011-06-01 20:39:58.604953351 -0300
+++ gcc/expr.c	2011-06-01 22:44:52.659524628 -0300
@@ -8424,10 +8424,40 @@ expand_expr_real_1 (tree exp, rtx target
 	  && !SSA_NAME_IS_DEFAULT_DEF (exp)
 	  && (optimize || DECL_IGNORED_P (SSA_NAME_VAR (exp)))
 	  && stmt_is_replaceable_p (SSA_NAME_DEF_STMT (exp)))
-	g = SSA_NAME_DEF_STMT (exp);
+	{
+	  g = SSA_NAME_DEF_STMT (exp);
+	  if (g)
+	    return expand_expr_real (gimple_assign_rhs_to_tree (g),
+				     target, tmode, modifier, NULL);
+	}
       if (g)
-	return expand_expr_real (gimple_assign_rhs_to_tree (g), target, tmode,
-				 modifier, NULL);
+	{
+	  rtx retval = *def_get_expansion_ptr (exp);
+
+	  gcc_assert (retval);
+
+	  switch (modifier)
+	    {
+	    case EXPAND_SUM:
+	      return retval;
+
+	    case EXPAND_STACK_PARM:
+	    case EXPAND_NORMAL:
+	      if (!target || !REG_P (target) || GET_MODE (target) != mode
+		  || !general_operand (retval, mode))
+		return force_reg (mode, retval);
+
+	      emit_move_insn (target, retval);
+	      return target;
+
+	    case EXPAND_MEMORY:
+	    case EXPAND_CONST_ADDRESS:
+	    case EXPAND_INITIALIZER:
+	    case EXPAND_WRITE:
+	    default:
+	      gcc_unreachable ();
+	    }
+	}
 
       ssa_name = exp;
       decl_rtl = get_rtx_for_ssa_name (ssa_name);
Index: gcc/expr.h
===================================================================
--- gcc/expr.h.orig	2011-06-01 20:39:58.742953327 -0300
+++ gcc/expr.h	2011-06-01 20:47:22.640844048 -0300
@@ -693,4 +693,7 @@ extern tree build_libfunc_function (cons
 /* Get the personality libfunc for a function decl.  */
 rtx get_personality_function (tree);
 
+/* In cfgexpand.c.  */
+rtx *def_get_expansion_ptr (tree);
+
 #endif /* GCC_EXPR_H */

-- 
Alexandre Oliva, freedom fighter    http://FSFLA.org/~lxoliva/
You must be the change you wish to see in the world. -- Gandhi
Be Free! -- http://FSFLA.org/   FSF Latin America board member
Free Software Evangelist      Red Hat Brazil Compiler Engineer

Reply via email to