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]

[incremental] Patch: FYI: fork server before back end


I'm checking this in on the incremental-compiler branch.

This changes the server to fork after parsing a file.  The child
process compiles as usual while the parent waits for it.  This is
something of a hack to avoid having to look into running the back end
multiple times.  At some later point I may give this a real try.  I
suspect at the very least the long-term code generation plan will
require adding a new model to cgraph.

The resulting server still crashes if you feed it two real files.  I
think that at least the front end needs to have separate notions of
"initialize once" and "initialize per compilation".

Tom

ChangeLog:
2007-09-06  Tom Tromey  <tromey@redhat.com>

	* server.h (server_start_back_end): Declare.
	* server.c (server_start_back_end): New function.
	* cgraph.h (cgraph_unit_reset, cgraph_reset): Declare.
	* cgraphunit.c (cgraph_unit_reset): New function.
	* cgraph.c (cgraph_reset): New function.
	* toplev.c (server_callback): Garbage collect.  Reset cgraph
	modules.
	(server_mode): New global.
	(toplev_main): Set it.
	(compile_file): Call server_start_back_end.
	(do_compile): Only initialize front end once.

Index: cgraph.c
===================================================================
--- cgraph.c	(revision 127650)
+++ cgraph.c	(working copy)
@@ -131,6 +131,24 @@
    them, to support -fno-toplevel-reorder.  */
 int cgraph_order;
 
+void
+cgraph_reset (void)
+{
+  cgraph_hash = NULL;
+  cgraph_nodes = NULL;
+  cgraph_nodes_queue = NULL;
+  cgraph_new_nodes = NULL;
+  cgraph_n_nodes = 0;
+  cgraph_max_uid = 0;
+  cgraph_max_pid = 0;
+  cgraph_global_info_ready = false;
+  cgraph_state = CGRAPH_STATE_CONSTRUCTION;
+  cgraph_function_flags_ready = false;
+  cgraph_asm_nodes = NULL;
+  cgraph_asm_last_node = NULL;
+  cgraph_order = 0;
+}
+
 static hashval_t hash_node (const void *);
 static int eq_node (const void *, const void *);
 
Index: cgraph.h
===================================================================
--- cgraph.h	(revision 127650)
+++ cgraph.h	(working copy)
@@ -287,6 +287,7 @@
 extern GTY(()) int cgraph_order;
 
 /* In cgraph.c  */
+void cgraph_reset (void);
 void dump_cgraph (FILE *);
 void dump_cgraph_node (FILE *, struct cgraph_node *);
 void cgraph_insert_node_to_hashtable (struct cgraph_node *node);
@@ -324,6 +325,7 @@
 void cgraph_add_new_function (tree, bool);
 
 /* In cgraphunit.c  */
+void cgraph_unit_reset (void);
 void cgraph_finalize_function (tree, bool);
 void cgraph_finalize_compilation_unit (void);
 void cgraph_optimize (void);
Index: toplev.c
===================================================================
--- toplev.c	(revision 128155)
+++ toplev.c	(working copy)
@@ -119,6 +119,9 @@
 /* True if we don't need a backend (e.g. preprocessing only).  */
 static bool no_backend;
 
+/* True if we're running as a server.  */
+static bool server_mode;
+
 /* Length of line when printing switch values.  */
 #define MAX_LINE 75
 
@@ -1056,10 +1059,16 @@
   if (flag_syntax_only)
     return;
 
+  if (server_mode && server_start_back_end ())
+    return;
+
   lang_hooks.decls.final_write_globals ();
 
   if (errorcount || sorrycount)
-    return;
+    {
+      /* FIXME: server mode... */
+      return;
+    }
 
   varpool_assemble_pending_decls ();
   finish_aliases_2 ();
@@ -1114,6 +1123,14 @@
      into the assembly file here, and hence we can not output anything to the
      assembly file after this point.  */
   targetm.asm_out.file_end ();
+
+  /* FIXME: this is a bit lame, but our caller doesn't know if we
+     forked.  */
+  if (server_mode)
+    {
+      finalize ();
+      exit (0);
+    }
 }
 
 /* Parse a -d... command line switch.  */
@@ -2226,6 +2243,14 @@
       pex_free (px);
     }
 
+  /* Clean up after this compilation.  FIXME: instead of clean_up()
+     running before a job, as we have in a couple files, we should
+     clean each module after compilation.  This will reduce peak
+     memory use.  */
+  cgraph_reset ();
+  cgraph_unit_reset ();
+  ggc_collect ();
+
   /* Make sure to close dup'd stderr, so that client will terminate
      properly.  The server loop will take care of the fd we were
      passed.  */
@@ -2252,6 +2277,7 @@
       /* Unit-at-a-time is needed to enable the C type-merging
 	 machinery.  */
       flag_unit_at_a_time = 1;
+      server_mode = true;
       server_main_loop (argv[0], fd);
       return SUCCESS_EXIT_CODE;
     }
Index: cgraphunit.c
===================================================================
--- cgraphunit.c	(revision 127650)
+++ cgraphunit.c	(working copy)
@@ -170,6 +170,13 @@
 static GTY (()) tree static_ctors;
 static GTY (()) tree static_dtors;
 
+void
+cgraph_unit_reset (void)
+{
+  static_ctors = NULL_TREE;
+  static_dtors = NULL_TREE;
+}
+
 /* When target does not have ctors and dtors, we call all constructor
    and destructor by special initialization/destruction function
    recognized by collect2.  
Index: server.c
===================================================================
--- server.c	(revision 127995)
+++ server.c	(working copy)
@@ -316,6 +316,33 @@
     unlink (server_socket_name);
 }
 
+/* Fork to let the back end do its work.  Returns true in the parent,
+   false in the child.  Will print a message and return true if there
+   is an error.  The parent waits for the child to exit.  */
+bool
+server_start_back_end (void)
+{
+  pid_t child;
+  int status;
+
+  child = fork ();
+  if (child == -1)
+    {
+      error ("fork of server failed: %s", xstrerror (errno));
+      return true;
+    }
+  else if (child == 0)
+    {
+      /* Child process.  */
+      return false;
+    }
+
+  /* Parent.  */
+  waitpid (child, &status, 0);
+  /* FIXME: handle STATUS somehow.  */
+  return true;
+}
+
 /* Make a connection to a running server.  PROGNAME is the name of the
    server to connect to.  Returns true on success, false on
    failure.  */
Index: server.h
===================================================================
--- server.h	(revision 127995)
+++ server.h	(working copy)
@@ -23,6 +23,7 @@
 /* Functions for the server to use.  */
 extern void server_start (char *);
 extern void server_main_loop (const char *progname, int);
+extern bool server_start_back_end (void);
 
 /* Functions for the client to use.  */
 extern bool client_connect (const char *);


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