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: [c++/cgraph] use cgraph in expand_or_defer_fn


> 
> Work-in-progress patch appended.  It doesn't work because some functions
> needed by the generated constructor function don't get emitted.  Which 
> is what lead me down this path.  I've been trying to take tiny steps, so

I see.  It is very close to what I was thinking about for a while :)
comments:
@@ -256,6 +257,16 @@ cgraph_mark_reachable_node (struct cgrap
 	    if (!node2->reachable)
 	      cgraph_mark_reachable_node (node2);
 	}
+
+      /* When not unit at a time, we'll need to output any functions
+	 called by the reachable node.  */
+      if (!flag_unit_at_a_time)
+	{
+	  struct cgraph_edge *edge;
+	  for (edge = node->callees; edge ; edge = edge->next_callee)
+	    if (!edge->callee->reachable || !edge->callee->output)
+	      cgraph_mark_reachable_node (edge->callee);
+	}

I would preffer the cgraph_mark_reachable node to be simple marking
function and in particular to not do too much of recursion
(while recursion over nested function depth looks resonable to me,
recursive DFS search is bit too expensive).

There is some code in cgraphunit to solve the reachability problem and
we probably should share it.

Also concerning the reachability it looks like your problem is in the
fact that C++ frontend does not emit functions it don't see to be needed
via SYMBOL_REFERENCED flag when working in non-unit-at-a-time mode.

At the moment I believe that when constructor use specialization of
method that is not used elsewhere, C++ frontend won't synthetize it as
it is all guarded by DECL_NEEDED_P and we run into troubles.

I was planning to eventually kill this feature too - modify declaration
of DECL_NEEDED_P in C++ frontend to be always in C++ style and teach
cgraphunit to defer functions that are not referenced until they are
on special flag (as C frontend probably don't want to use this).
This would make C++ frontend to do some extra work, but it is doing so
in unit-at-a-time mode anyway and it does not appear to be overkill.
This needs benchmarking.

This would make things easier for you, so perhaps we should go for this
now, but I am not quite sure and unforutnately I won't be able to do so
before 22th when I return from trip :( Doing this single step should
instantly solve most of problems we are seeing except for the fact that
function declarations may change by special instantiation that is
relatively easy to deal with.

I am attaching completely untested patch that should implement that.
In addition to that we need to arrange variables to always go trought
varpool code so we get elliminated dead tables and such.  That should be
easy I hope.

Honza

Index: cgraphunit.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cgraphunit.c,v
retrieving revision 1.28
diff -c -3 -p -r1.28 cgraphunit.c
*** cgraphunit.c	10 Sep 2003 19:16:15 -0000	1.28
--- cgraphunit.c	11 Sep 2003 15:12:03 -0000
*************** static int ncalls_inlined;
*** 55,60 ****
--- 55,63 ----
  static int nfunctions_inlined;
  static int initial_insns;
  static int overall_insns;
+ /* Nonzero means that we defer emitting functions until they are actually
+    used.  */
+ int flag_remove_unreachable_functions;
  
  /* Records tree nodes seen in cgraph_create_edges.  Simply using
     walk_tree_without_duplicates doesn't guarantee each node is visited
*************** decide_is_function_needed (struct cgraph
*** 97,103 ****
        && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
      return true;
  
!   if (flag_unit_at_a_time)
      return false;
  
    /* If not doing unit at a time, then we'll only defer this function
--- 100,106 ----
        && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
      return true;
  
!   if (flag_unit_at_a_time || flag_remove_unreachable_functions)
      return false;
  
    /* If not doing unit at a time, then we'll only defer this function
Index: flags.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/flags.h,v
retrieving revision 1.120
diff -c -3 -p -r1.120 flags.h
*** flags.h	3 Sep 2003 20:57:31 -0000	1.120
--- flags.h	11 Sep 2003 15:12:03 -0000
*************** extern int flag_signaling_nans;
*** 692,697 ****
--- 692,701 ----
  
  extern int flag_unit_at_a_time;
  
+ /* Nonzero means that we defer emitting functions until they are actually
+    used.  */
+ extern int flag_remove_unreachable_functions;
+ 
  /* A string that's used when a random name is required.  NULL means
     to make it really random.  */
  
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.915
diff -c -3 -p -r1.915 cp-tree.h
*** cp/cp-tree.h	10 Sep 2003 19:16:20 -0000	1.915
--- cp/cp-tree.h	11 Sep 2003 15:12:05 -0000
*************** struct lang_decl GTY(())
*** 1743,1751 ****
     not something is comdat until end-of-file.  */
  #define DECL_NEEDED_P(DECL)					\
    ((at_eof && TREE_PUBLIC (DECL) && !DECL_COMDAT (DECL))	\
!    || (DECL_ASSEMBLER_NAME_SET_P (DECL)				\
!        && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (DECL)))	\
!    || (((flag_syntax_only || flag_unit_at_a_time) && TREE_USED (DECL))))
  
  /* For a FUNCTION_DECL or a VAR_DECL, the language linkage for the
     declaration.  Some entities (like a member function in a local
--- 1743,1749 ----
     not something is comdat until end-of-file.  */
  #define DECL_NEEDED_P(DECL)					\
    ((at_eof && TREE_PUBLIC (DECL) && !DECL_COMDAT (DECL))	\
!    || ((TREE_USED (DECL))))
  
  /* For a FUNCTION_DECL or a VAR_DECL, the language linkage for the
     declaration.  Some entities (like a member function in a local
Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.1125
diff -c -3 -p -r1.1125 decl.c
*** cp/decl.c	8 Sep 2003 15:56:19 -0000	1.1125
--- cp/decl.c	11 Sep 2003 15:12:08 -0000
*************** cxx_init_decl_processing (void)
*** 6147,6152 ****
--- 6147,6154 ----
  
    current_lang_name = NULL_TREE;
  
+   flag_remove_unreachable_functions = 1;
+ 
    /* Adjust various flags based on command-line settings.  */
    if (!flag_permissive)
      flag_pedantic_errors = 1;


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