diff mbox

RFA: temp slot TLC [1/3]

Message ID Pine.LNX.4.64.1205270141450.25409@wotan.suse.de
State New
Headers show

Commit Message

Michael Matz May 27, 2012, 12:39 a.m. UTC
Hi,

I still had some cleanups for age-old code lying around, and thought to 
bring it up to date.  The whole dealing of slots for temporary stack space 
in function.c was never really updated to the way we're meanwhile 
expanding statements.  It has facilities that aren't useful anymore.  In 
the old days it worked like this: after a statement was expanded temporary 
slots that were allocated during that expansion would be freed.  The 
problem was that statements could be arbitrarily complex, including calls 
as call arguments or statement expressions.  So there had to be a way that 
some of these slots could be marked as to be kept until the next scope 
would be popped (the 'keep' flag to assign_temp), or at least that the 
slot might be used in the containing expression even after a 
free_temp_slots (the addr_taken flag for a slot).

Meanwhile the situation is like so:

1) There are only three places that still allocate a 'kept' slot (i.e. 
   keep==1 in a call to assign_temp, assign_stack_temp and 
   assign_stack_temp_for_type):

a) expand_expr_real_1, when expanding a reference from a constant object, 
   which must be in memory but isn't;
   this is meanwhile useless, the so allocated temporary will not be
   freed until the full statement is done, at which point the expanded 
   reference will either be consumed into the real objects, or will be 
   ignored; it's not necessary to artificially mark it kept
b) expand_asm_operands, for handling mem inputs on non-lvalues;
   this is dead code, we rewrite all such asms at gimple level already.
c) in expand_decl;
   this routine I'm going to remove (with removal of the reference from
   Ada it's all dead code)

2) The single place that still sometimes marks temp slots as addr_taken is 
   in expand_call.  It does so when the callee returns an aggregate and no 
   target is given (or no return slot optimization should happen).  The 
   temp slot will not go away until the next free_temp_slots at which 
   point it must already be copied out into the real LHS of the (gimple) 
   call statement or it'll be ignored, so marking it to be kept 
   isn't necessary.

expand_decl is dead code because it only does things for CONST_DECLs (for 
Ada, but I'm removing that use) and automatic vars.  But automatic vars 
are (supposed to be) allocated since quite some time in cfgexpand.  One 
call to expand_decl that still did something is for expansion of 
COMPOUND_LITERAL_EXPR, which we can have only in global ctors (usual 
problem of not gimplifying those).  That's easy to deal with, though, as 
in the patch.  The other expand_decl call that does something is for 
generating RTL for the nonlocal_goto_save_area in case it doesn't have RTL 
yet.  The latter shouldn't (and after the patch doesn't) happen: the 
underlying variable is supposed to be in local_decls and hence should have 
gotten RTL during cfgexpand.  This is only not true when it was unused, 
removed from local_decls, but the reference from cfun remains.  In that 
case we'd expand (unused) stack space.  Instead I simply remove the 
reference from cfun when the variable is removed.

As the data flow regarding temporaries in the old RTL code is a bit 
complicated I reassured myself regarding the above points with various 
gcc_unreachable and commenting code.  That is this first patch.  The 
second and third patch contain the more or less obvious cleanup followups.

I'm asking for approval for all three patches, but I have bootstrapped the 
first separately, so if approved I'm going to commit them as separate 
revisions so that in case I got something wrong with this touchy area it's 
easy to play with adjusting just parts of the patch, without always having 
to redo all the cleanup adjustments.

So, regstrapped on x86_64-linux all languages (+Ada,+obj-c++), this patch 
alone and in connection with [2/3] and [3/3].  Okay for trunk (I have 
approval for the Ada part already).


Ciao,
Michael.
-----------------------
	* expr.c (expand_expr_real_1 <normal_inner_ref>): Don't allocate
	a kept temp.
	(expand_expr_real_1 <COMPOUND_LITERAL_EXPR>): Make unreachable.
	* gimple-fold.c (canonicalize_constructor_val): Canonicalize 
	COMPOUND_LITERAL_EXPR.
	* function.c (expand_function_start): Don't call expand_decl,
	instead assert that we have RTL assigned.
	* tree-ssa-live.c (remove_unused_locals): Clear
	nonlocal_goto_save_area if its backing variable is removed.
	* stmt.c (expand_asm_operands): Remove handling of non-lvalues
	as mem inputs.
	(expand_decl): Assert that this does nothing.
	* calls.c (expand_call): Don't call mark_temp_addr_taken.

	* c-tree.h (c_expand_decl): Remove prototype.

c-family/
	* c-common.h (c_expand_decl): Remove prototype.

ada/
	* gcc-interface/utils.c (create_var_decl_1): Don't call expand_decl.
diff mbox

Patch

Index: expr.c
===================================================================
--- expr.c.orig	2012-05-25 17:03:54.000000000 +0200
+++ expr.c	2012-05-26 16:37:09.000000000 +0200
@@ -9922,7 +9922,7 @@  expand_expr_real_1 (tree exp, rtx target
 	    tree nt = build_qualified_type (TREE_TYPE (tem),
 					    (TYPE_QUALS (TREE_TYPE (tem))
 					     | TYPE_QUAL_CONST));
-	    memloc = assign_temp (nt, 1, 1, 1);
+	    memloc = assign_temp (nt, 0, 1, 1);
 	    emit_move_insn (memloc, op0);
 	    op0 = memloc;
 	    mem_attrs_from_type = true;
@@ -10425,6 +10425,7 @@  expand_expr_real_1 (tree exp, rtx target
     case POSTDECREMENT_EXPR:
     case LOOP_EXPR:
     case EXIT_EXPR:
+    case COMPOUND_LITERAL_EXPR:
       /* Lowered by gimplify.c.  */
       gcc_unreachable ();
 
@@ -10439,7 +10440,7 @@  expand_expr_real_1 (tree exp, rtx target
       return expand_expr_real (treeop0, original_target, tmode,
 			       modifier, alt_rtl);
 
-    case COMPOUND_LITERAL_EXPR:
+#if 0
       {
 	/* Initialize the anonymous variable declared in the compound
 	   literal, then return the variable.  */
@@ -10459,6 +10460,7 @@  expand_expr_real_1 (tree exp, rtx target
 	return expand_expr_real (decl, original_target, tmode,
 				 modifier, alt_rtl);
       }
+#endif
 
     default:
       return expand_expr_real_2 (&ops, target, tmode, modifier);
Index: function.c
===================================================================
--- function.c.orig	2012-05-25 17:03:13.000000000 +0200
+++ function.c	2012-05-26 16:37:08.000000000 +0200
@@ -4788,11 +4788,8 @@  expand_function_start (tree subr)
       tree t_save;
       rtx r_save;
 
-      /* ??? We need to do this save early.  Unfortunately here is
-	 before the frame variable gets declared.  Help out...  */
       tree var = TREE_OPERAND (cfun->nonlocal_goto_save_area, 0);
-      if (!DECL_RTL_SET_P (var))
-	expand_decl (var);
+      gcc_assert (DECL_RTL_SET_P (var));
 
       t_save = build4 (ARRAY_REF,
 		       TREE_TYPE (TREE_TYPE (cfun->nonlocal_goto_save_area)),
Index: gimple-fold.c
===================================================================
--- gimple-fold.c.orig	2012-05-25 17:03:54.000000000 +0200
+++ gimple-fold.c	2012-05-25 17:20:54.000000000 +0200
@@ -154,6 +154,12 @@  canonicalize_constructor_val (tree cval,
   if (TREE_CODE (cval) == ADDR_EXPR)
     {
       tree base = get_base_address (TREE_OPERAND (cval, 0));
+      if (!base && TREE_CODE (TREE_OPERAND (cval, 0)) == COMPOUND_LITERAL_EXPR)
+	{
+	  base = COMPOUND_LITERAL_EXPR_DECL (TREE_OPERAND (cval, 0));
+	  if (base)
+	    TREE_OPERAND (cval, 0) = base;
+	}
       if (!base)
 	return NULL_TREE;
 
Index: tree-ssa-live.c
===================================================================
--- tree-ssa-live.c.orig	2012-05-25 17:03:54.000000000 +0200
+++ tree-ssa-live.c	2012-05-26 18:24:14.000000000 +0200
@@ -835,6 +835,9 @@  remove_unused_locals (void)
 	    {
 	      if (var_ann (var))
 		remove_referenced_var (var);
+	      if (cfun->nonlocal_goto_save_area
+		  && TREE_OPERAND (cfun->nonlocal_goto_save_area, 0) == var)
+		cfun->nonlocal_goto_save_area = NULL;
 	      continue;
 	    }
 	}
Index: stmt.c
===================================================================
--- stmt.c.orig	2012-05-25 17:03:13.000000000 +0200
+++ stmt.c	2012-05-26 16:37:09.000000000 +0200
@@ -910,6 +910,8 @@  expand_asm_operands (tree string, tree o
 		 at this point.  Ignore it: clearly this *is* a memory.  */
 	    }
 	  else
+	    gcc_unreachable ();
+#if 0
 	    {
 	      warning (0, "use of memory input without lvalue in "
 		       "asm operand %d is deprecated", i + noutputs);
@@ -935,6 +937,7 @@  expand_asm_operands (tree string, tree o
 		  op = memloc;
 		}
 	    }
+#endif
 	}
 
       generating_concat_p = old_generating_concat_p;
@@ -1703,6 +1706,7 @@  expand_decl (tree decl)
      type in case this node is used in a reference.  */
   if (TREE_CODE (decl) == CONST_DECL)
     {
+      gcc_unreachable ();
       DECL_MODE (decl) = TYPE_MODE (type);
       DECL_ALIGN (decl) = TYPE_ALIGN (type);
       DECL_SIZE (decl) = TYPE_SIZE (type);
@@ -1720,6 +1724,7 @@  expand_decl (tree decl)
   if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
     return;
 
+  gcc_unreachable ();
   /* Create the RTL representation for the variable.  */
 
   if (type == error_mark_node)
Index: c-family/c-common.h
===================================================================
--- c-family/c-common.h.orig	2012-05-25 17:03:13.000000000 +0200
+++ c-family/c-common.h	2012-05-25 17:20:54.000000000 +0200
@@ -544,8 +544,6 @@  extern tree build_modify_expr (location_
 			       location_t, tree, tree);
 extern tree build_indirect_ref (location_t, tree, ref_operator);
 
-extern int c_expand_decl (tree);
-
 extern int field_decl_cmp (const void *, const void *);
 extern void resort_sorted_fields (void *, void *, gt_pointer_operator,
 				  void *);
Index: c-tree.h
===================================================================
--- c-tree.h.orig	2012-05-25 17:03:13.000000000 +0200
+++ c-tree.h	2012-05-25 17:20:54.000000000 +0200
@@ -535,7 +535,6 @@  extern void store_parm_decls (void);
 extern void store_parm_decls_from (struct c_arg_info *);
 extern tree xref_tag (enum tree_code, tree);
 extern struct c_typespec parser_xref_tag (location_t, enum tree_code, tree);
-extern int c_expand_decl (tree);
 extern struct c_parm *build_c_parm (struct c_declspecs *, tree,
 				    struct c_declarator *);
 extern struct c_declarator *build_attrs_declarator (tree,
Index: calls.c
===================================================================
--- calls.c.orig	2012-05-25 17:03:13.000000000 +0200
+++ calls.c	2012-05-26 16:37:09.000000000 +0200
@@ -2405,8 +2405,6 @@  expand_call (tree exp, rtx target, int i
 	       specified.  If we were to allocate space on the stack here,
 	       we would have no way of knowing when to free it.  */
 	    rtx d = assign_temp (rettype, 0, 1, 1);
-
-	    mark_temp_addr_taken (d);
 	    structure_value_addr = XEXP (d, 0);
 	    target = 0;
 	  }
Index: ada/gcc-interface/utils.c
===================================================================
--- ada/gcc-interface/utils.c.orig	2012-05-25 17:03:13.000000000 +0200
+++ ada/gcc-interface/utils.c	2012-05-25 17:20:54.000000000 +0200
@@ -2227,8 +2227,6 @@  create_var_decl_1 (tree var_name, tree a
       if (global_bindings_p ())
 	rest_of_decl_compilation (var_decl, true, 0);
     }
-  else
-    expand_decl (var_decl);
 
   return var_decl;
 }