This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Fix nested functions


> On Wed, Sep 15, 2004 at 03:32:28PM +0200, Jan Hubicka wrote:
> > +        cgraph_unnest_node (cgraph_node (root->context));
> > +        cgraph_finalize_function (root->context, true);
> 
> Ug.
> 
> You'll want to remove the code in the front end that tries
> to finalize them too.  Better yet, rearrange things such
> that all of the unnesting and finalization is under control
> of cgraph in the first place.
Ug...

Bootstrapped/regtested i686-pc-gnu-linux...

2004-09-15  Jan Hubicka  <jh@suse.cz>
	* cgraph.c (cgraph_unnest_node): New function.
	(c_finalize): Rename to ....
	(c_warn_unused_result_recursivly): ... this one; do only the warning
	(finish_function): Finalize the toplevel function; do not lower nested tree.
	* cgraph.h (cgraph_unnest_node): Declare.
	* cgraphunit.c (decide_is_function_needed): Do not use cgraph
	nestedness datastructure.
	* cse.c (cse_insn): Do not cprop nonlocal LABEL_REFs.
	* reload1.c (set_label_offsets): Fix call of set_label_offsets.
	* tree-nested.c (finlize_nesting_tree_1):  Use un-nesting code.

	* trans-decl.c (build_entry_thunks): Finalize the function; do not lower
	tree.
	(gfc_generate_function_code): Likewise.

Index: c-decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-decl.c,v
retrieving revision 1.584
diff -c -3 -p -r1.584 c-decl.c
*** c-decl.c	14 Sep 2004 18:59:33 -0000	1.584
--- c-decl.c	15 Sep 2004 22:59:06 -0000
*************** store_parm_decls (void)
*** 6299,6328 ****
    cfun->x_dont_save_pending_sizes_p = 1;
  }
  
! /* Give FNDECL and all its nested functions to cgraph for compilation.  */
  
  static void
! c_finalize (tree fndecl)
  {
    struct cgraph_node *cgn;
  
    /* Handle attribute((warn_unused_result)).  Relies on gimple input.  */
    c_warn_unused_result (&DECL_SAVED_TREE (fndecl));
  
-   /* ??? Objc emits functions after finalizing the compilation unit.
-      This should be cleaned up later and this conditional removed.  */
-   if (cgraph_global_info_ready)
-     {
-       c_expand_body (fndecl);
-       return;
-     }
- 
    /* Finalize all nested functions now.  */
    cgn = cgraph_node (fndecl);
    for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested)
!     c_finalize (cgn->decl);
! 
!   cgraph_finalize_function (fndecl, false);
  }
  
  /* Finish up a function declaration and compile that function
--- 6299,6319 ----
    cfun->x_dont_save_pending_sizes_p = 1;
  }
  
! /* Handle attribute((warn_unused_result)) on FNDECL and all its nested
!    functions.  */
  
  static void
! c_warn_unused_result_recursively (tree fndecl)
  {
    struct cgraph_node *cgn;
  
    /* Handle attribute((warn_unused_result)).  Relies on gimple input.  */
    c_warn_unused_result (&DECL_SAVED_TREE (fndecl));
  
    /* Finalize all nested functions now.  */
    cgn = cgraph_node (fndecl);
    for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested)
!     c_warn_unused_result_recursively (cgn->decl);
  }
  
  /* Finish up a function declaration and compile that function
*************** finish_function (void)
*** 6426,6433 ****
        if (!decl_function_context (fndecl))
          {
            c_genericize (fndecl);
! 	  lower_nested_functions (fndecl);
!           c_finalize (fndecl);
          }
        else
          {
--- 6417,6433 ----
        if (!decl_function_context (fndecl))
          {
            c_genericize (fndecl);
! 
! 	  /* ??? Objc emits functions after finalizing the compilation unit.
! 	     This should be cleaned up later and this conditional removed.  */
! 	  if (cgraph_global_info_ready)
! 	    {
! 	      c_expand_body (fndecl);
! 	      return;
! 	    }
! 
!           c_warn_unused_result_recursively (fndecl);
! 	  cgraph_finalize_function (fndecl, false);
          }
        else
          {
Index: cgraph.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cgraph.c,v
retrieving revision 1.57
diff -c -3 -p -r1.57 cgraph.c
*** cgraph.c	13 Sep 2004 22:51:00 -0000	1.57
--- cgraph.c	15 Sep 2004 22:59:06 -0000
*************** cgraph_clone_node (struct cgraph_node *n
*** 693,696 ****
--- 693,709 ----
  
    return new;
  }
+ 
+ /* NODE is no longer nested function; update cgraph accordingly.  */
+ void
+ cgraph_unnest_node (struct cgraph_node *node)
+ {
+   struct cgraph_node **node2 = &node->origin->nested;
+   gcc_assert (node->origin);
+ 
+   while (*node2 != node)
+     node2 = &(*node2)->next_nested;
+   *node2 = node->next_nested;
+   node->origin = NULL;
+ }
  #include "gt-cgraph.h"
Index: cgraph.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cgraph.h,v
retrieving revision 1.37
diff -c -3 -p -r1.37 cgraph.h
*** cgraph.h	14 Sep 2004 12:21:41 -0000	1.37
--- cgraph.h	15 Sep 2004 22:59:06 -0000
*************** bool cgraph_varpool_assemble_pending_dec
*** 266,271 ****
--- 266,272 ----
  void cgraph_redirect_edge_callee (struct cgraph_edge *, struct cgraph_node *);
  
  bool cgraph_function_possibly_inlined_p (tree);
+ void cgraph_unnest_node (struct cgraph_node *node);
  
  /* In cgraphunit.c  */
  bool cgraph_assemble_pending_functions (void);
Index: cgraphunit.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cgraphunit.c,v
retrieving revision 1.81
diff -c -3 -p -r1.81 cgraphunit.c
*** cgraphunit.c	14 Sep 2004 12:21:41 -0000	1.81
--- cgraphunit.c	15 Sep 2004 22:59:07 -0000
*************** static tree memory_identifier;
*** 263,269 ****
  static bool
  decide_is_function_needed (struct cgraph_node *node, tree decl)
  {
!   struct cgraph_node *origin;
  
    /* If we decided it was needed before, but at the time we didn't have
       the body of the function available, then it's still needed.  We have
--- 263,269 ----
  static bool
  decide_is_function_needed (struct cgraph_node *node, tree decl)
  {
!   tree origin;
  
    /* If we decided it was needed before, but at the time we didn't have
       the body of the function available, then it's still needed.  We have
*************** decide_is_function_needed (struct cgraph
*** 303,310 ****
      return false;
    /* Nested functions of extern inline function shall not be emit unless
       we inlined the origin.  */
!   for (origin = node->origin; origin; origin = origin->origin)
!     if (DECL_EXTERNAL (origin->decl))
        return false;
    /* We want to emit COMDAT functions only when absolutely necessary.  */
    if (DECL_COMDAT (decl))
--- 303,311 ----
      return false;
    /* Nested functions of extern inline function shall not be emit unless
       we inlined the origin.  */
!   for (origin = decl_function_context (decl); origin;
!        origin = decl_function_context (origin))
!     if (DECL_EXTERNAL (origin))
        return false;
    /* We want to emit COMDAT functions only when absolutely necessary.  */
    if (DECL_COMDAT (decl))
*************** cgraph_finalize_function (tree decl, boo
*** 586,591 ****
--- 587,595 ----
    notice_global_symbol (decl);
    node->decl = decl;
    node->local.finalized = true;
+   if (node->nested)
+     lower_nested_functions (decl);
+   gcc_assert (!node->nested);
  
    /* If not unit at a time, then we need to create the call graph
       now, so that called functions can be queued and emitted now.  */
Index: cse.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cse.c,v
retrieving revision 1.313
diff -c -3 -p -r1.313 cse.c
*** cse.c	7 Sep 2004 20:59:18 -0000	1.313
--- cse.c	15 Sep 2004 22:59:09 -0000
*************** cse_insn (rtx insn, rtx libcall_insn)
*** 5623,5629 ****
  
        /* If this SET is now setting PC to a label, we know it used to
  	 be a conditional or computed branch.  */
!       else if (dest == pc_rtx && GET_CODE (src) == LABEL_REF)
  	{
  	  /* Now emit a BARRIER after the unconditional jump.  */
  	  if (NEXT_INSN (insn) == 0
--- 5623,5630 ----
  
        /* If this SET is now setting PC to a label, we know it used to
  	 be a conditional or computed branch.  */
!       else if (dest == pc_rtx && GET_CODE (src) == LABEL_REF
! 	       && !LABEL_REF_NONLOCAL_P (src))
  	{
  	  /* Now emit a BARRIER after the unconditional jump.  */
  	  if (NEXT_INSN (insn) == 0
Index: reload1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reload1.c,v
retrieving revision 1.445
diff -c -3 -p -r1.445 reload1.c
*** reload1.c	15 Sep 2004 20:47:48 -0000	1.445
--- reload1.c	15 Sep 2004 22:59:13 -0000
*************** set_label_offsets (rtx x, rtx insn, int 
*** 2185,2191 ****
  	  return;
  
  	case LABEL_REF:
! 	  set_label_offsets (XEXP (SET_SRC (x), 0), insn, initial_p);
  	  return;
  
  	case IF_THEN_ELSE:
--- 2185,2191 ----
  	  return;
  
  	case LABEL_REF:
! 	  set_label_offsets (SET_SRC (x), insn, initial_p);
  	  return;
  
  	case IF_THEN_ELSE:
Index: tree-nested.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-nested.c,v
retrieving revision 2.17
diff -c -3 -p -r2.17 tree-nested.c
*** tree-nested.c	9 Sep 2004 10:36:11 -0000	2.17
--- tree-nested.c	15 Sep 2004 22:59:13 -0000
*************** finalize_nesting_tree_1 (struct nesting_
*** 1207,1212 ****
--- 1207,1213 ----
    tree stmt_list = NULL;
    tree context = root->context;
    struct function *sf;
+   struct cgraph_node *node;
  
    /* If we created a non-local frame type or decl, we need to lay them
       out at this time.  */
*************** finalize_nesting_tree_1 (struct nesting_
*** 1317,1322 ****
--- 1318,1332 ----
  
    /* Dump the translated tree function.  */
    dump_function (TDI_nested, root->context);
+   node = cgraph_node (root->context);
+ 
+   /* For nested functions update the cgraph to reflect unnesting.
+      We also delay finalizing of these functions up to this point.  */
+   if (node->origin)
+     {
+        cgraph_unnest_node (cgraph_node (root->context));
+        cgraph_finalize_function (root->context, true);
+     }
  }
  
  static void
Index: fortran/trans-decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fortran/trans-decl.c,v
retrieving revision 1.42
diff -c -3 -p -r1.42 trans-decl.c
*** fortran/trans-decl.c	8 Sep 2004 14:33:02 -0000	1.42
--- fortran/trans-decl.c	15 Sep 2004 22:59:15 -0000
*************** create_function_arglist (gfc_symbol * sy
*** 1255,1276 ****
    DECL_ARGUMENTS (fndecl) = arglist;
  }
  
- 
- /* Finalize DECL and all nested functions with cgraph.  */
- 
- static void
- gfc_finalize (tree decl)
- {
-   struct cgraph_node *cgn;
- 
-   cgn = cgraph_node (decl);
-   for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested)
-     gfc_finalize (cgn->decl);
- 
-   cgraph_finalize_function (decl, false);
- }
- 
- 
  /* Convert FNDECL's code to GIMPLE and handle any nested functions.  */
  
  static void
--- 1255,1260 ----
*************** build_entry_thunks (gfc_namespace * ns)
*** 1431,1438 ****
        current_function_decl = NULL_TREE;
  
        gfc_gimplify_function (thunk_fndecl);
!       lower_nested_functions (thunk_fndecl);
!       gfc_finalize (thunk_fndecl);
  
        /* We share the symbols in the formal argument list with other entry
  	 points and the master function.  Clear them so that they are
--- 1415,1421 ----
        current_function_decl = NULL_TREE;
  
        gfc_gimplify_function (thunk_fndecl);
!       cgraph_finalize_function (thunk_fndecl, false);
  
        /* We share the symbols in the formal argument list with other entry
  	 points and the master function.  Clear them so that they are
*************** gfc_generate_function_code (gfc_namespac
*** 2313,2320 ****
    else
      {
        gfc_gimplify_function (fndecl);
!       lower_nested_functions (fndecl);
!       gfc_finalize (fndecl);
      }
  }
  
--- 2296,2302 ----
    else
      {
        gfc_gimplify_function (fndecl);
!       cgraph_finalize_function (fndecl, false);
      }
  }
  


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]