Deferring-all-constants fallout (was Re: 5 GCC regressions, 1 new, with your patch on 2003-05-05T21:59:06Z.)

Zack Weinberg zack@codesourcery.com
Wed May 7 06:12:00 GMT 2003


Geoffrey Keating <geoffk@apple.com> writes:

>> The new failures are:
>> native gcc.sum gcc.c-torture/execute/920501-5.c
>>
> I'm pretty sure this is Zack's.  The routine is:
>
> x (int i)
> {
>    void *j[] = {&&x, &&y, &&z};
>    goto *j[i];
>   x:return 2;
>   y:return 3;
>   z:return 5;
>
> }

Yeah, it's mine.  I don't get exactly the same code with a cross
compiler to powerpc-darwin6.3 but I can reproduce the effect.  That
initialization makes a CONSTRUCTOR; formerly, expand_expr would see
the ADDR_EXPRs inside the CONSTRUCTOR immediately, and add the
LABEL_DECLs to the "forced_label" list, but now it doesn't see them
until final, which is much too late.

The appended patch should sort it.  Could you please try it on your
machine and report the results?  I will run an i686-linux bootstrap
overnight, but the x86 does something different with this test case
so it won't really exercise the problem scenario.  It does fix the
problem with my cross-compiler.  And all the dead code in

x (int i)
{
  void *j = { &&x, &&y, &&z; };
  return 0;
x:return 2;
y:return 3;
z:return 5;
}

still gets deleted.  In fact, it does better than it used to on that -
a compiler before my original change would emit the vector of label
addresses even though it wasn't referenced.  Now it all goes away
except the labels themselves, which are preserved in case the debugger
wants to see them.

zw

        * stmt.c (force_label_rtx): New function, based on logic
        formerly found in expand_expr.
        * expr.h: Prototype it.
        * expr.c (expand_expr <LABEL_DECL>): Use force_label_rtx if
        appropriate.
        * varasm.c (decode_addr_const <LABEL_DECL>): Use force_label_rtx.

===================================================================
Index: expr.c
--- expr.c	5 May 2003 17:56:35 -0000	1.536
+++ expr.c	7 May 2003 06:08:30 -0000
@@ -6753,25 +6753,17 @@ expand_expr (exp, target, tmode, modifie
     case LABEL_DECL:
       {
 	tree function = decl_function_context (exp);
-	/* Handle using a label in a containing function.  */
-	if (function != current_function_decl
-	    && function != inline_function_decl && function != 0)
-	  {
-	    struct function *p = find_function_data (function);
-	    p->expr->x_forced_labels
-	      = gen_rtx_EXPR_LIST (VOIDmode, label_rtx (exp),
-				   p->expr->x_forced_labels);
-	  }
+	/* Labels in containing functions, or labels used from initializers,
+	   must be forced.  */
+	if (modifier == EXPAND_INITIALIZER
+	    || (function != current_function_decl
+		&& function != inline_function_decl
+		&& function != 0))
+	  temp = force_label_rtx (exp);
 	else
-	  {
-	    if (modifier == EXPAND_INITIALIZER)
-	      forced_labels = gen_rtx_EXPR_LIST (VOIDmode,
-						 label_rtx (exp),
-						 forced_labels);
-	  }
+	  temp = label_rtx (exp);
 
-	temp = gen_rtx_MEM (FUNCTION_MODE,
-			    gen_rtx_LABEL_REF (Pmode, label_rtx (exp)));
+	temp = gen_rtx_MEM (FUNCTION_MODE, gen_rtx_LABEL_REF (Pmode, temp));
 	if (function != current_function_decl
 	    && function != inline_function_decl && function != 0)
 	  LABEL_REF_NONLOCAL_P (XEXP (temp, 0)) = 1;
===================================================================
Index: expr.h
--- expr.h	2 May 2003 14:22:07 -0000	1.134
+++ expr.h	7 May 2003 06:08:30 -0000
@@ -595,6 +595,11 @@ extern rtx expand_inline_function PARAMS
 
 /* Return the CODE_LABEL rtx for a LABEL_DECL, creating it if necessary.  */
 extern rtx label_rtx PARAMS ((tree));
+
+/* As label_rtx, but additionally the label is placed on the forced label
+   list of its containing function (i.e. it is treated as reachable even
+   if how is not obvious).  */
+extern rtx force_label_rtx PARAMS ((tree));
 #endif
 
 /* Indicate how an input argument register was promoted.  */
===================================================================
Index: stmt.c
--- stmt.c	3 May 2003 21:44:27 -0000	1.300
+++ stmt.c	7 May 2003 06:08:31 -0000
@@ -510,6 +510,29 @@ label_rtx (label)
   return DECL_RTL (label);
 }
 
+/* As above, but also put it on the forced-reference list of the
+   function that contains it.  */
+rtx
+force_label_rtx (label)
+     tree label;
+{
+  rtx ref = label_rtx (label);
+  tree function = decl_function_context (label);
+  struct function *p;
+
+  if (!function)
+    abort ();
+
+  if (function != current_function_decl
+      && function != inline_function_decl)
+    p = find_function_data (function);
+  else
+    p = cfun;
+
+  p->expr->x_forced_labels = gen_rtx_EXPR_LIST (VOIDmode, ref,
+						p->expr->x_forced_labels);
+  return ref;
+}
 
 /* Add an unconditional jump to LABEL as the next sequential instruction.  */
 
===================================================================
Index: varasm.c
--- varasm.c	5 May 2003 21:57:52 -0000	1.349
+++ varasm.c	7 May 2003 06:08:32 -0000
@@ -2088,8 +2088,7 @@ decode_addr_const (exp, value)
 
     case LABEL_DECL:
       x = gen_rtx_MEM (FUNCTION_MODE,
-		       gen_rtx_LABEL_REF (VOIDmode,
-					  label_rtx (TREE_OPERAND (exp, 0))));
+		       gen_rtx_LABEL_REF (VOIDmode, force_label_rtx (target)));
       break;
 
     case REAL_CST:



More information about the Gcc-regression mailing list