C++ PATCH for function-at-a-time infrastructure

Mark Mitchell markATcodesourcery.com
Fri Sep 17 16:15:00 GMT 1999


This patch doesn't actually *do* anything, but it adds some new tree
nodes and helper functions in preparation for function-at-a-time
processing.  Cleans house in a couple of places.

--
Mark Mitchell                   mark@codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com

1999-09-17  Mark Mitchell  <mark@codesourcery.com>

	* cp-tree.def (CLEANUP_STMT): Fix spelling in dumps.
	(TRY_BLOCK): Likewise.
	(HANDLER): Likewise.
	(START_CATCH_STMT): New tree node.
	(SCOPE_STMT): Likewise.
	* cp-tree.h (SCOPE_BEGIN_P): New macro.
	(SCOPE_NULLIFIED_P): Likewise.
	(struct lang_decl_flags): Add pending_inline_p.  Adjust dummy.
	(struct lang_decl): Add saved_language_function.
	(DECL_PENDING_INLINE_INFO): Adjust documentation.
	(DECL_PENDING_INLINE_P): New macro.
	(TYPE_TI_ARGS): Fix typo in comment.
	(DECL_SAVED_TREE): Add to documentation.
	(DECL_SAVED_FUNCTION_DATA): New macro.
	(START_CATCH_TYPE): Likewise.
	(SCOPE_END_P): New macro.
	(declare_parm_level): Don't declare.
	* decl.c (mark_lang_function): New function, split out from
	mark_cp_function_context.
	(save_function_data): New function.
	(declare_parm_level): Remove.
	(finish_function): Use save_function_data to squirrel away
	important stuff for later use.
	(mark_cp_function_context): Use mark_function_data.
	(lang_mark_tree): Likewise.
	* lex.c (begin_definition_of_inclass_inline): Set
	DECL_PENDING_INLINE_P.
	(store_pending_inline): Clear it.
	* pt.c (tsubst_decl): Likewise.

Index: cp-tree.def
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/cp-tree.def,v
retrieving revision 1.36
diff -c -p -r1.36 cp-tree.def
*** cp-tree.def	1999/09/12 01:12:56	1.36
--- cp-tree.def	1999/09/17 23:09:42
*************** DEFTREECODE (SUBOBJECT, "subobject", 'e'
*** 238,249 ****
  /* A CLEANUP_STMT marks the point at which a declaration is fully
     constructed.  If, after this point, the CLEANUP_DECL goes out of
     scope, the CLEANUP_EXPR must be run.  */
! DEFTREECODE (CLEANUP_STMT, "cleanup", 'e', 2)
  DEFTREECODE (CTOR_INITIALIZER, "ctor_initializer", 'e', 2)
  DEFTREECODE (CASE_LABEL, "case_label", 'e', 2)
  DEFTREECODE (RETURN_INIT, "return_init", 'e', 2)
! DEFTREECODE (TRY_BLOCK, "try_stmt", 'e', 2)
! DEFTREECODE (HANDLER, "catch_stmt", 'e', 2)
  
  /* A STMT_EXPR represents a statement-expression.  The
     STMT_EXPR_STMT is the statement given by the expression.  */
--- 238,259 ----
  /* A CLEANUP_STMT marks the point at which a declaration is fully
     constructed.  If, after this point, the CLEANUP_DECL goes out of
     scope, the CLEANUP_EXPR must be run.  */
! DEFTREECODE (CLEANUP_STMT, "cleanup_stmt", 'e', 2)
! /* A START_CATCH_STMT marks the beginning of a catch handler for the
!    the START_CATCH_TYPE.  If this is CATCH_ALL_TYPE, then the handler
!    catches all types.  */
! DEFTREECODE (START_CATCH_STMT, "start_catch_stmt", 'e', 0)
! /* A SCOPE_STMT marks the beginning or end of a scope.  If
!    SCOPE_BEGIN_P holds, then this is the start of a scope.  If
!    SCOPE_END_P holds, then this is the end of a scope.  If
!    SCOPE_NULLIFIED_P holds then there turned out to be no variables in
!    this scope.  */
! DEFTREECODE (SCOPE_STMT, "scope_stmt", 'e', 0)
  DEFTREECODE (CTOR_INITIALIZER, "ctor_initializer", 'e', 2)
  DEFTREECODE (CASE_LABEL, "case_label", 'e', 2)
  DEFTREECODE (RETURN_INIT, "return_init", 'e', 2)
! DEFTREECODE (TRY_BLOCK, "try_block", 'e', 2)
! DEFTREECODE (HANDLER, "handler", 'e', 2)
  
  /* A STMT_EXPR represents a statement-expression.  The
     STMT_EXPR_STMT is the statement given by the expression.  */
Index: cp-tree.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.306
diff -c -p -r1.306 cp-tree.h
*** cp-tree.h	1999/09/17 07:34:52	1.306
--- cp-tree.h	1999/09/17 23:09:45
*************** Boston, MA 02111-1307, USA.  */
*** 40,45 ****
--- 40,46 ----
        ICS_USER_FLAG (in _CONV)
        CLEANUP_P (in TRY_BLOCK)
        AGGR_INIT_VIA_CTOR_P (in AGGR_INIT_EXPR)
+       SCOPE_BEGIN_P (in SCOPE_STMT)
     1: IDENTIFIER_VIRTUAL_P.
        TI_PENDING_TEMPLATE_FLAG.
        TEMPLATE_PARMS_FOR_INLINE.
*************** Boston, MA 02111-1307, USA.  */
*** 64,69 ****
--- 65,71 ----
        (TREE_REFERENCE_EXPR) (in NON_LVALUE_EXPR) (commented-out).
        ICS_BAD_FLAG (in _CONV)
        FN_TRY_BLOCK_P (in TRY_BLOCK)
+       SCOPE_NULLIFIED_P (in SCOPE_STMT)
     4: BINFO_NEW_VTABLE_MARKED.
        TREE_HAS_CONSTRUCTOR (in INDIRECT_REF, SAVE_EXPR, CONSTRUCTOR,
            or FIELD_DECL).
*************** struct lang_decl_flags
*** 1505,1511 ****
  
    unsigned bitfield : 1;
    unsigned defined_in_class : 1;
!   unsigned dummy : 6;
  
    tree access;
    tree context;
--- 1507,1514 ----
  
    unsigned bitfield : 1;
    unsigned defined_in_class : 1;
!   unsigned pending_inline_p : 1;
!   unsigned dummy : 5;
  
    tree access;
    tree context;
*************** struct lang_decl
*** 1533,1538 ****
--- 1536,1542 ----
    {
      tree sorted_fields;
      struct pending_inline *pending_inline_info;
+     struct language_function *saved_language_function;
    } u;
  };
  
*************** struct lang_decl
*** 1717,1726 ****
  /* Points back to the decl which caused this lang_decl to be allocated.  */
  #define DECL_MAIN_VARIANT(NODE) (DECL_LANG_SPECIFIC(NODE)->main_decl_variant)
  
! /* For a FUNCTION_DECL: if this function was declared inline inside of
!    a class declaration, this is where the text for the function is
!    squirreled away.  */
! #define DECL_PENDING_INLINE_INFO(NODE) (DECL_LANG_SPECIFIC(NODE)->u.pending_inline_info)
  
  /* For a TYPE_DECL: if this function has many fields, we'll sort them
     and put them into a TREE_VEC. */
--- 1721,1736 ----
  /* Points back to the decl which caused this lang_decl to be allocated.  */
  #define DECL_MAIN_VARIANT(NODE) (DECL_LANG_SPECIFIC(NODE)->main_decl_variant)
  
! /* In a FUNCTION_DECL, this is nonzero if this function was defined in
!    the class definition.  We have saved away the text of the function,
!    but have not yet processed it.  */
! #define DECL_PENDING_INLINE_P(NODE) \
!   (DECL_LANG_SPECIFIC (NODE)->decl_flags.pending_inline_p)
!    
! /* If DECL_PENDING_INLINE_P holds, this is the saved text of the
!    function.  */
! #define DECL_PENDING_INLINE_INFO(NODE) \
!   (DECL_LANG_SPECIFIC(NODE)->u.pending_inline_info)
  
  /* For a TYPE_DECL: if this function has many fields, we'll sort them
     and put them into a TREE_VEC. */
*************** struct lang_decl
*** 1804,1810 ****
  #define TYPE_TI_TEMPLATE(NODE)			\
    (TI_TEMPLATE (TYPE_TEMPLATE_INFO (NODE)))
  
! /* Like DECL_TI_ARGS, , but for an ENUMERAL_, RECORD_, or UNION_TYPE.  */
  #define TYPE_TI_ARGS(NODE)			\
    (TI_ARGS (TYPE_TEMPLATE_INFO (NODE)))
  
--- 1814,1820 ----
  #define TYPE_TI_TEMPLATE(NODE)			\
    (TI_TEMPLATE (TYPE_TEMPLATE_INFO (NODE)))
  
! /* Like DECL_TI_ARGS, but for an ENUMERAL_, RECORD_, or UNION_TYPE.  */
  #define TYPE_TI_ARGS(NODE)			\
    (TI_ARGS (TYPE_TEMPLATE_INFO (NODE)))
  
*************** struct lang_decl
*** 1815,1825 ****
     the class definition is complete.  */
  #define TEMPLATE_PARMS_FOR_INLINE(NODE) TREE_LANG_FLAG_1 (NODE)
  
! /* In a template FUNCTION_DECL, the tree structure that will be
!    substituted into to obtain instantiations.  */
  #define DECL_SAVED_TREE(NODE) \
    (DECL_LANG_SPECIFIC ((NODE))->saved_tree)
  
  #define COMPOUND_STMT_NO_SCOPE(NODE)	TREE_LANG_FLAG_0 (NODE)
  #define NEW_EXPR_USE_GLOBAL(NODE)	TREE_LANG_FLAG_0 (NODE)
  #define DELETE_EXPR_USE_GLOBAL(NODE)	TREE_LANG_FLAG_0 (NODE)
--- 1825,1840 ----
     the class definition is complete.  */
  #define TEMPLATE_PARMS_FOR_INLINE(NODE) TREE_LANG_FLAG_1 (NODE)
  
! /* In a FUNCTION_DECL, the saved representation of the body of the
!    entire function.  Usually a COMPOUND_STMT, but this may also be a
!    RETURN_INIT, CTOR_INITIALIZER, or TRY_BLOCK.  */
  #define DECL_SAVED_TREE(NODE) \
    (DECL_LANG_SPECIFIC ((NODE))->saved_tree)
  
+ /* In a FUNCTION_DECL, the saved language-specific per-function data.  */
+ #define DECL_SAVED_FUNCTION_DATA(NODE) \
+   (DECL_LANG_SPECIFIC ((NODE))->u.saved_language_function)
+ 
  #define COMPOUND_STMT_NO_SCOPE(NODE)	TREE_LANG_FLAG_0 (NODE)
  #define NEW_EXPR_USE_GLOBAL(NODE)	TREE_LANG_FLAG_0 (NODE)
  #define DELETE_EXPR_USE_GLOBAL(NODE)	TREE_LANG_FLAG_0 (NODE)
*************** extern int flag_new_for_scope;
*** 2446,2453 ****
--- 2461,2481 ----
  #define SUBOBJECT_CLEANUP(NODE) TREE_OPERAND (NODE, 0)
  #define CLEANUP_DECL(NODE)      TREE_OPERAND (NODE, 0)
  #define CLEANUP_EXPR(NODE)      TREE_OPERAND (NODE, 1)
+ #define START_CATCH_TYPE(NODE)  TREE_TYPE (NODE)
  #define LABEL_STMT_LABEL(NODE)  TREE_OPERAND (NODE, 0)
  
+ /* Nonzero if this SCOPE_STMT is for the beginning of a scope.  */
+ #define SCOPE_BEGIN_P(NODE) \
+   (TREE_LANG_FLAG_0 ((NODE))) 
+ 
+ /* Nonzero if this SCOPE_STMT is for the end of a scope.  */
+ #define SCOPE_END_P(NODE) \
+   (!SCOPE_BEGIN_P ((NODE)))
+ 
+ /* Nonzero for a SCOPE_STMT if there were no variables in this scope.  */
+ #define SCOPE_NULLIFIED_P(NODE) \
+   (TREE_LANG_FLAG_3 ((NODE)))
+ 
  /* Nonzero for an ASM_STMT if the assembly statement is volatile.  */
  #define ASM_VOLATILE_P(NODE)			\
    (ASM_CV_QUAL ((NODE)) != NULL_TREE)
*************** extern int toplevel_bindings_p			PROTO((
*** 3106,3119 ****
  extern int namespace_bindings_p			PROTO((void));
  extern void keep_next_level			PROTO((int));
  extern int kept_level_p				PROTO((void));
- extern void declare_parm_level			PROTO((void));
  extern void declare_pseudo_global_level		PROTO((void));
  extern int pseudo_global_level_p		PROTO((void));
  extern void set_class_shadows			PROTO((tree));
  extern void pushlevel				PROTO((int));
  extern void note_level_for_for			PROTO((void));
  extern void pushlevel_temporary			PROTO((int));
- extern tree poplevel				PROTO((int, int, int));
  extern void resume_level			PROTO((struct binding_level *));
  extern void delete_block			PROTO((tree));
  extern void insert_block			PROTO((tree));
--- 3134,3145 ----
Index: decl.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/decl.c,v
retrieving revision 1.455
diff -c -p -r1.455 decl.c
*** decl.c	1999/09/17 07:34:53	1.455
--- decl.c	1999/09/17 23:09:54
*************** static void pop_cp_function_context PROT
*** 175,180 ****
--- 175,182 ----
  static void mark_binding_level PROTO((void *));
  static void mark_cp_function_context PROTO((struct function *));
  static void mark_saved_scope PROTO((void *));
+ static void mark_lang_function PROTO((struct language_function *));
+ static void save_function_data PROTO((tree));
  static void check_function_type PROTO((tree));
  static void destroy_local_static PROTO((tree));
  static void destroy_local_var PROTO((tree));
*************** kept_level_p ()
*** 787,801 ****
  	      && !current_binding_level->tag_transparent));
  }
  
- /* Identify this binding level as a level of parameters.  */
- 
  void
- declare_parm_level ()
- {
-   current_binding_level->parm_flag = 1;
- }
- 
- void
  declare_pseudo_global_level ()
  {
    current_binding_level->pseudo_global = 1;
--- 789,795 ----
*************** store_return_init (decl)
*** 13235,13240 ****
--- 13229,13271 ----
  }
  
  
+ /* We have finished doing semantic analysis on DECL, but have not yet
+    generated RTL for its body.  Save away our current state, so that
+    when we want to generate RTL later we know what to do.  */
+ 
+ static void
+ save_function_data (decl)
+      tree decl;
+ {
+   struct language_function *f;
+ 
+   /* Save the language-specific per-function data so that we can
+      get it back when we really expand this function.  */
+   my_friendly_assert (!DECL_PENDING_INLINE_P (decl),
+ 		      19990908);
+       
+   /* Make a copy.  */
+   f = ((struct language_function *) 
+        xmalloc (sizeof (struct language_function)));
+   bcopy ((char *) cp_function_chain, (char *) f,
+ 	 sizeof (struct language_function));
+   DECL_SAVED_FUNCTION_DATA (decl) = f;
+ 
+   /* Clear out the bits we don't need.  */
+   f->x_base_init_list = NULL_TREE;
+   f->x_member_init_list = NULL_TREE;
+   f->x_last_tree = NULL_TREE;
+   f->x_last_expr_type = NULL_TREE;
+   f->x_last_dtor_insn = NULL_RTX;
+   f->x_last_parm_cleanup_insn = NULL_RTX;
+   f->x_result_rtx = NULL_RTX;
+   f->x_named_label_uses = NULL;
+   f->bindings = NULL;
+ 
+   /* When we get back here again, we will be expanding.  */
+   f->x_expanding_p = 1;
+ }
+ 
  /* Finish up a function declaration and compile that function
     all the way to assembler language output.  The free the storage
     for the function definition.
*************** finish_function (lineno, flags)
*** 13715,13720 ****
--- 13746,13755 ----
    /* Undo the call to push_momentary in start_function.  */
    pop_momentary ();
  
+   /* Save away current state, if appropriate.  */
+   if (!expanding_p && !processing_template_decl)
+     save_function_data (fndecl);
+ 
    if (expand_p)
      {
        int returns_null;
*************** pop_cp_function_context (f)
*** 14284,14295 ****
    f->language = 0;
  }
  
! void
! mark_cp_function_context (f)
!      struct function *f;
! {
!   struct language_function *p = f->language;
  
    if (!p)
      return;
  
--- 14319,14330 ----
    f->language = 0;
  }
  
! /* Mark P for GC.  */
  
+ static void
+ mark_lang_function (p)
+      struct language_function *p;
+ {
    if (!p)
      return;
  
*************** mark_cp_function_context (f)
*** 14311,14316 ****
--- 14346,14359 ----
    mark_binding_level (&p->bindings);
  }
  
+ /* Mark the language-specific data in F for GC.  */
+ 
+ void
+ mark_cp_function_context (f)
+      struct function *f;
+ {
+   mark_lang_function (f->language);
+ }
  
  int
  in_function_p ()
*************** lang_mark_tree (t)
*** 14378,14383 ****
--- 14421,14429 ----
  	      ggc_mark_tree (ld->saved_tree);
  	      if (TREE_CODE (t) == TYPE_DECL)
  		ggc_mark_tree (ld->u.sorted_fields);
+ 	      else if (TREE_CODE (t) == FUNCTION_DECL
+ 		       && !DECL_PENDING_INLINE_P (t))
+ 		mark_lang_function (DECL_SAVED_FUNCTION_DATA (t));
  	    }
  	}
      }
Index: lex.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/lex.c,v
retrieving revision 1.152
diff -c -p -r1.152 lex.c
*** lex.c	1999/09/16 22:33:10	1.152
--- lex.c	1999/09/17 23:09:56
*************** begin_definition_of_inclass_inline (pi)
*** 1288,1293 ****
--- 1288,1294 ----
    /* Pass back a handle to the rest of the inline functions, so that they
       can be processed later.  */
    DECL_PENDING_INLINE_INFO (pi->fndecl) = 0;
+   DECL_PENDING_INLINE_P (pi->fndecl) = 0;
    interface_unknown = pi->interface == 1;
    interface_only  = pi->interface == 0;
  }
*************** store_pending_inline (decl, t)
*** 1510,1515 ****
--- 1511,1517 ----
  {
    t->fndecl = decl;
    DECL_PENDING_INLINE_INFO (decl) = t;
+   DECL_PENDING_INLINE_P (decl) = 1;
  
    /* Because we use obstacks, we must process these in precise order.  */
    t->next = pending_inlines;
Index: pt.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/pt.c,v
retrieving revision 1.359
diff -c -p -r1.359 pt.c
*** pt.c	1999/09/15 22:49:32	1.359
--- pt.c	1999/09/17 23:10:02
*************** tsubst_decl (t, args, type, in_decl)
*** 5874,5879 ****
--- 5874,5880 ----
  	DECL_DEFER_OUTPUT (r) = 0;
  	TREE_CHAIN (r) = NULL_TREE;
  	DECL_PENDING_INLINE_INFO (r) = 0;
+ 	DECL_PENDING_INLINE_P (r) = 0;
  	TREE_USED (r) = 0;
  
  	/* Set up the DECL_TEMPLATE_INFO for R and compute its mangled


More information about the Gcc-patches mailing list