./:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 17 Jan 2006 07:04:20 +0000 (07:04 +0000)
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 17 Jan 2006 07:04:20 +0000 (07:04 +0000)
* common.opt (ftoplevel-reorder): New option.
* cgraph.c (cgraph_asm_nodes): New global variable.
(cgraph_asm_last_node): New static variable.
(cgraph_order): New global variable.
(cgraph_create_node): Set new order field.
(cgraph_varpool_node): Likewise.
(decide_is_variable_needed): Return true if not
flag_toplevel_reorder.
(cgraph_add_asm_node): New function.
* cgraph.h (struct cgraph_node): Add order field.
(struct cgraph_varpool_node): Add order field.
(struct cgraph_asm_node): Define.
(cgraph_asm_nodes, cgraph_order): Declare.
(cgraph_add_asm_node): Declare.
* cgraphunit.c (cgraph_varpool_assemble_decl): New static
function.
(cgraph_varpool_assemble_pending_decls): Call it.
(cgraph_output_pending_asms): New static function.
(cgraph_finalize_compilation_unit): Call it.
(struct cgraph_order_sort): Define.
(cgraph_output_in_order): New static function.
(cgraph_optimize): Call cgraph_output_pending_asms.  Add code for
!flag_toplevel_reorder case.
* c-parser.c: Include "cgraph.h".
(c_parser_asm_definition): Call cgraph_add_asm_node rather than
assemble_asm.
* Makefile.in (CRTSTUFF_CFLAGS): Use -fno-toplevel-reorder rather
than -fno-unit-at-a-time.
* doc/invoke.texi (Option Summary): Mention
-fno-toplevel-reorder.
(Optimize Options): Document -fno-toplevel-reorder.  Mention it in
-funit-at-a-time documentation.
cp/:
* parser.c: Include "cgraph.h".
(cp_parser_asm_definition): Call cgraph_add_asm_node rather than
assemble_asm.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@109811 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/Makefile.in
gcc/c-parser.c
gcc/cgraph.c
gcc/cgraph.h
gcc/cgraphunit.c
gcc/common.opt
gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/doc/invoke.texi

index 6813fe0..030333b 100644 (file)
@@ -1,3 +1,38 @@
+2006-01-16  Ian Lance Taylor  <ian@airs.com>
+
+       * common.opt (ftoplevel-reorder): New option.
+       * cgraph.c (cgraph_asm_nodes): New global variable.
+       (cgraph_asm_last_node): New static variable.
+       (cgraph_order): New global variable.
+       (cgraph_create_node): Set new order field.
+       (cgraph_varpool_node): Likewise.
+       (decide_is_variable_needed): Return true if not
+       flag_toplevel_reorder.
+       (cgraph_add_asm_node): New function.
+       * cgraph.h (struct cgraph_node): Add order field.
+       (struct cgraph_varpool_node): Add order field.
+       (struct cgraph_asm_node): Define.
+       (cgraph_asm_nodes, cgraph_order): Declare.
+       (cgraph_add_asm_node): Declare.
+       * cgraphunit.c (cgraph_varpool_assemble_decl): New static
+       function.
+       (cgraph_varpool_assemble_pending_decls): Call it.
+       (cgraph_output_pending_asms): New static function.
+       (cgraph_finalize_compilation_unit): Call it.
+       (struct cgraph_order_sort): Define.
+       (cgraph_output_in_order): New static function.
+       (cgraph_optimize): Call cgraph_output_pending_asms.  Add code for
+       !flag_toplevel_reorder case.
+       * c-parser.c: Include "cgraph.h".
+       (c_parser_asm_definition): Call cgraph_add_asm_node rather than
+       assemble_asm.
+       * Makefile.in (CRTSTUFF_CFLAGS): Use -fno-toplevel-reorder rather
+       than -fno-unit-at-a-time.
+       * doc/invoke.texi (Option Summary): Mention
+       -fno-toplevel-reorder.
+       (Optimize Options): Document -fno-toplevel-reorder.  Mention it in
+       -funit-at-a-time documentation.
+
 2006-01-17  Hans-Peter Nilsson  <hp@axis.com>
            Kazu Hirata  <kazu@codesourcery.com>
 
index 4950feb..93e95dc 100644 (file)
@@ -554,7 +554,7 @@ TARGET_LIBGCC2_CFLAGS =
 # Options to use when compiling crtbegin/end.
 CRTSTUFF_CFLAGS = -O2 $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -g0 \
   -finhibit-size-directive -fno-inline-functions -fno-exceptions \
-  -fno-zero-initialized-in-bss -fno-unit-at-a-time \
+  -fno-zero-initialized-in-bss -fno-toplevel-reorder \
   $(INHIBIT_LIBC_CFLAGS)
 
 # Additional sources to handle exceptions; overridden by targets as needed.
index 91a9d29..522f2d2 100644 (file)
@@ -56,6 +56,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 #include "c-common.h"
 #include "vec.h"
 #include "target.h"
+#include "cgraph.h"
 
 \f
 /* Miscellaneous data and functions needed for the parser.  */
@@ -1387,12 +1388,8 @@ static void
 c_parser_asm_definition (c_parser *parser)
 {
   tree asm_str = c_parser_simple_asm_expr (parser);
-  /* ??? This only works sensibly in the presence of
-     -fno-unit-at-a-time; file-scope asms really need to be passed to
-     cgraph which needs to preserve the order of functions and
-     file-scope asms.  */
   if (asm_str)
-    assemble_asm (asm_str);
+    cgraph_add_asm_node (asm_str);
   c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
 }
 
index 88cf8ac..10a2233 100644 (file)
@@ -131,13 +131,23 @@ static GTY((param_is (struct cgraph_varpool_node))) htab_t cgraph_varpool_hash;
 /* Queue of cgraph nodes scheduled to be lowered and output.  */
 struct cgraph_varpool_node *cgraph_varpool_nodes_queue, *cgraph_varpool_first_unanalyzed_node;
 
-
 /* The linked list of cgraph varpool nodes.  */
 static GTY(()) struct cgraph_varpool_node *cgraph_varpool_nodes;
 
 /* End of the varpool queue.  Needs to be QTYed to work with PCH.  */
 static GTY(()) struct cgraph_varpool_node *cgraph_varpool_last_needed_node;
 
+/* Linked list of cgraph asm nodes.  */
+struct cgraph_asm_node *cgraph_asm_nodes;
+
+/* Last node in cgraph_asm_nodes.  */
+static GTY(()) struct cgraph_asm_node *cgraph_asm_last_node;
+
+/* The order index of the next cgraph node to be created.  This is
+   used so that we can sort the cgraph nodes in order by when we saw
+   them, to support -fno-toplevel-reorder.  */
+int cgraph_order;
+
 static hashval_t hash_node (const void *);
 static int eq_node (const void *, const void *);
 
@@ -169,6 +179,7 @@ cgraph_create_node (void)
   node = GGC_CNEW (struct cgraph_node);
   node->next = cgraph_nodes;
   node->uid = cgraph_max_uid++;
+  node->order = cgraph_order++;
   if (cgraph_nodes)
     cgraph_nodes->previous = node;
   node->previous = NULL;
@@ -745,6 +756,7 @@ cgraph_varpool_node (tree decl)
     return *slot;
   node = GGC_CNEW (struct cgraph_varpool_node);
   node->decl = decl;
+  node->order = cgraph_order++;
   node->next = cgraph_varpool_nodes;
   cgraph_varpool_nodes = node;
   *slot = node;
@@ -847,12 +859,11 @@ decide_is_variable_needed (struct cgraph_varpool_node *node, tree decl)
   if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
     return true;
 
-  if (flag_unit_at_a_time)
+  /* When not reordering top level variables, we have to assume that
+     we are going to keep everything.  */
+  if (flag_unit_at_a_time && flag_toplevel_reorder)
     return false;
 
-  /* If not doing unit at a time, then we'll only defer this function
-     if its marked for inlining.  Otherwise we want to emit it now.  */
-
   /* We want to emit COMDAT variables only when absolutely necessary.  */
   if (DECL_COMDAT (decl))
     return false;
@@ -889,6 +900,25 @@ cgraph_varpool_finalize_decl (tree decl)
     cgraph_varpool_assemble_pending_decls ();
 }
 
+/* Add a top-level asm statement to the list.  */
+
+struct cgraph_asm_node *
+cgraph_add_asm_node (tree asm_str)
+{
+  struct cgraph_asm_node *node;
+
+  node = GGC_CNEW (struct cgraph_asm_node);
+  node->asm_str = asm_str;
+  node->order = cgraph_order++;
+  node->next = NULL;
+  if (cgraph_asm_nodes == NULL)
+    cgraph_asm_nodes = node;
+  else
+    cgraph_asm_last_node->next = node;
+  cgraph_asm_last_node = node;
+  return node;
+}
+
 /* Return true when the DECL can possibly be inlined.  */
 bool
 cgraph_function_possibly_inlined_p (tree decl)
index 78b0fad..82cf2d9 100644 (file)
@@ -144,6 +144,8 @@ struct cgraph_node GTY((chain_next ("%h.next"), chain_prev ("%h.previous")))
   gcov_type count;
   /* Unique id of the node.  */
   int uid;
+  /* Ordering of all cgraph nodes.  */
+  int order;
   /* Set when function must be output - it is externally visible
      or its address is taken.  */
   bool needed;
@@ -197,6 +199,8 @@ struct cgraph_varpool_node GTY(())
   struct cgraph_varpool_node *next;
   /* Pointer to the next function in cgraph_varpool_nodes_queue.  */
   struct cgraph_varpool_node *next_needed;
+  /* Ordering of all cgraph nodes.  */
+  int order;
 
   /* Set when function must be output - it is externally visible
      or its address is taken.  */
@@ -217,6 +221,18 @@ struct cgraph_varpool_node GTY(())
   bool alias;
 };
 
+/* Every top level asm statement is put into a cgraph_asm_node.  */
+
+struct cgraph_asm_node GTY(())
+{
+  /* Next asm node.  */
+  struct cgraph_asm_node *next;
+  /* String for this asm node.  */
+  tree asm_str;
+  /* Ordering of all cgraph nodes.  */
+  int order;
+};
+
 extern GTY(()) struct cgraph_node *cgraph_nodes;
 extern GTY(()) int cgraph_n_nodes;
 extern GTY(()) int cgraph_max_uid;
@@ -226,6 +242,8 @@ extern GTY(()) struct cgraph_node *cgraph_nodes_queue;
 
 extern GTY(()) struct cgraph_varpool_node *cgraph_varpool_first_unanalyzed_node;
 extern GTY(()) struct cgraph_varpool_node *cgraph_varpool_nodes_queue;
+extern GTY(()) struct cgraph_asm_node *cgraph_asm_nodes;
+extern GTY(()) int cgraph_order;
 
 /* In cgraph.c  */
 void dump_cgraph (FILE *);
@@ -258,6 +276,8 @@ void cgraph_varpool_mark_needed_node (struct cgraph_varpool_node *);
 void cgraph_varpool_finalize_decl (tree);
 void cgraph_redirect_edge_callee (struct cgraph_edge *, struct cgraph_node *);
 
+struct cgraph_asm_node *cgraph_add_asm_node (tree);
+
 bool cgraph_function_possibly_inlined_p (tree);
 void cgraph_unnest_node (struct cgraph_node *);
 void cgraph_varpool_enqueue_needed_node (struct cgraph_varpool_node *);
index ae2dd51..ae9f690 100644 (file)
@@ -807,6 +807,34 @@ verify_cgraph (void)
     verify_cgraph_node (node);
 }
 
+/* Output one variable, if necessary.  Return whether we output it.  */
+static bool
+cgraph_varpool_assemble_decl (struct cgraph_varpool_node *node)
+{
+  tree decl = node->decl;
+
+  if (!TREE_ASM_WRITTEN (decl)
+      && !node->alias
+      && !DECL_EXTERNAL (decl)
+      && (TREE_CODE (decl) != VAR_DECL || !DECL_HAS_VALUE_EXPR_P (decl)))
+    {
+      assemble_variable (decl, 0, 1, 0);
+      /* Local static variables are never seen by check_global_declarations
+        so we need to output debug info by hand.  */
+      if (DECL_CONTEXT (decl) 
+         && (TREE_CODE (DECL_CONTEXT (decl)) == BLOCK
+             || TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL)
+         && errorcount == 0 && sorrycount == 0)
+       {
+         timevar_push (TV_SYMOUT);
+         (*debug_hooks->global_decl) (decl);
+         timevar_pop (TV_SYMOUT);
+       }
+      return true;
+    }
+
+  return false;
+}
 
 /* Output all variables enqueued to be assembled.  */
 bool
@@ -824,31 +852,31 @@ cgraph_varpool_assemble_pending_decls (void)
 
   while (cgraph_varpool_nodes_queue)
     {
-      tree decl = cgraph_varpool_nodes_queue->decl;
       struct cgraph_varpool_node *node = cgraph_varpool_nodes_queue;
 
       cgraph_varpool_nodes_queue = cgraph_varpool_nodes_queue->next_needed;
-      if (!TREE_ASM_WRITTEN (decl) && !node->alias && !DECL_EXTERNAL (decl))
-       {
-         assemble_variable (decl, 0, 1, 0);
-         /* Local static variables are never seen by check_global_declarations
-            so we need to output debug info by hand.  */
-         if (DECL_CONTEXT (decl) 
-             && (TREE_CODE (DECL_CONTEXT (decl)) == BLOCK
-                 || TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL)
-             && errorcount == 0 && sorrycount == 0)
-           {
-             timevar_push (TV_SYMOUT);
-             (*debug_hooks->global_decl) (decl);
-             timevar_pop (TV_SYMOUT);
-           }
-         changed = true;
-       }
+      if (cgraph_varpool_assemble_decl (node))
+       changed = true;
       node->next_needed = NULL;
     }
   return changed;
 }
 
+/* Output all asm statements we have stored up to be output.  */
+
+static void
+cgraph_output_pending_asms (void)
+{
+  struct cgraph_asm_node *can;
+
+  if (errorcount || sorrycount)
+    return;
+
+  for (can = cgraph_asm_nodes; can; can = can->next)
+    assemble_asm (can->asm_str);
+  cgraph_asm_nodes = NULL;
+}
+
 /* Analyze the function scheduled to be output.  */
 static void
 cgraph_analyze_function (struct cgraph_node *node)
@@ -892,6 +920,7 @@ cgraph_finalize_compilation_unit (void)
 
   if (!flag_unit_at_a_time)
     {
+      cgraph_output_pending_asms ();
       cgraph_assemble_pending_functions ();
       return;
     }
@@ -1125,6 +1154,97 @@ cgraph_expand_all_functions (void)
   free (order);
 }
 
+/* This is used to sort the node types by the cgraph order number.  */
+
+struct cgraph_order_sort
+{
+  enum { ORDER_UNDEFINED = 0, ORDER_FUNCTION, ORDER_VAR, ORDER_ASM } kind;
+  union
+  {
+    struct cgraph_node *f;
+    struct cgraph_varpool_node *v;
+    struct cgraph_asm_node *a;
+  } u;
+};
+
+/* Output all functions, variables, and asm statements in the order
+   according to their order fields, which is the order in which they
+   appeared in the file.  This implements -fno-toplevel-reorder.  In
+   this mode we may output functions and variables which don't really
+   need to be output.  */
+
+static void
+cgraph_output_in_order (void)
+{
+  int max;
+  size_t size;
+  struct cgraph_order_sort *nodes;
+  int i;
+  struct cgraph_node *pf;
+  struct cgraph_varpool_node *pv;
+  struct cgraph_asm_node *pa;
+
+  max = cgraph_order;
+  size = max * sizeof (struct cgraph_order_sort);
+  nodes = (struct cgraph_order_sort *) alloca (size);
+  memset (nodes, 0, size);
+
+  cgraph_varpool_analyze_pending_decls ();
+
+  for (pf = cgraph_nodes; pf; pf = pf->next)
+    {
+      if (pf->output)
+       {
+         i = pf->order;
+         gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
+         nodes[i].kind = ORDER_FUNCTION;
+         nodes[i].u.f = pf;
+       }
+    }
+
+  for (pv = cgraph_varpool_nodes_queue; pv; pv = pv->next_needed)
+    {
+      i = pv->order;
+      gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
+      nodes[i].kind = ORDER_VAR;
+      nodes[i].u.v = pv;
+    }
+
+  for (pa = cgraph_asm_nodes; pa; pa = pa->next)
+    {
+      i = pa->order;
+      gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
+      nodes[i].kind = ORDER_ASM;
+      nodes[i].u.a = pa;
+    }
+  cgraph_asm_nodes = NULL;
+
+  for (i = 0; i < max; ++i)
+    {
+      switch (nodes[i].kind)
+       {
+       case ORDER_FUNCTION:
+         nodes[i].u.f->output = 0;
+         cgraph_expand_function (nodes[i].u.f);
+         break;
+
+       case ORDER_VAR:
+         cgraph_varpool_assemble_decl (nodes[i].u.v);
+         break;
+
+       case ORDER_ASM:
+         assemble_asm (nodes[i].u.a->asm_str);
+         break;
+
+       case ORDER_UNDEFINED:
+         break;
+
+       default:
+         gcc_unreachable ();
+       }
+    }
+}
+
 /* Mark visibility of all functions.
    
    A local function is one whose calls can occur only in the current
@@ -1232,6 +1352,7 @@ cgraph_optimize (void)
 #endif
   if (!flag_unit_at_a_time)
     {
+      cgraph_output_pending_asms ();
       cgraph_varpool_assemble_pending_decls ();
       return;
     }
@@ -1271,12 +1392,20 @@ cgraph_optimize (void)
 #ifdef ENABLE_CHECKING
   verify_cgraph ();
 #endif
-  
+
   cgraph_mark_functions_to_output ();
-  cgraph_expand_all_functions ();
-  cgraph_varpool_remove_unreferenced_decls ();
 
-  cgraph_varpool_assemble_pending_decls ();
+  if (!flag_toplevel_reorder)
+    cgraph_output_in_order ();
+  else
+    {
+      cgraph_output_pending_asms ();
+
+      cgraph_expand_all_functions ();
+      cgraph_varpool_remove_unreferenced_decls ();
+
+      cgraph_varpool_assemble_pending_decls ();
+    }
 
   if (cgraph_dump_file)
     {
index 1239960..8fe9bee 100644 (file)
@@ -868,6 +868,10 @@ ftls-model=
 Common Joined RejectNegative
 -ftls-model=[global-dynamic|local-dynamic|initial-exec|local-exec]     Set the default thread-local storage code generation model
 
+ftoplevel-reorder
+Common Report Var(flag_toplevel_reorder) Init(1)
+Reorder top level functions, variables, and asms
+
 ftracer
 Common Report Var(flag_tracer)
 Perform superblock formation via tail duplication
index e158f62..3453893 100644 (file)
@@ -1,3 +1,9 @@
+2006-01-16  Ian Lance Taylor  <ian@airs.com>
+
+       * parser.c: Include "cgraph.h".
+       (cp_parser_asm_definition): Call cgraph_add_asm_node rather than
+       assemble_asm.
+
 2006-01-16  Rafael Ávila de Espíndola  <rafael.espindola@gmail.com>
 
        * g++spec.c (lang_specific_spec_functions): Remove.
@@ -43,7 +49,7 @@
        * parser.c (cp_parser_primary_expression): Document the grammar
        for the built-in offsetof, a GNU extension.
 
-2005-01-04  Zdenek Dvorak <dvorakz@suse.cz>
+2006-01-04  Zdenek Dvorak <dvorakz@suse.cz>
 
        PR c++/25632
        * init.c (constant_value_1): Unshare use of DECL_INITIAL.  Fix a typo
index 8e11d43..ec4c2ea 100644 (file)
@@ -36,6 +36,7 @@
 #include "toplev.h"
 #include "output.h"
 #include "target.h"
+#include "cgraph.h"
 #include "c-common.h"
 
 \f
@@ -10741,7 +10742,7 @@ cp_parser_asm_definition (cp_parser* parser)
        }
     }
   else
-    assemble_asm (string);
+    cgraph_add_asm_node (string);
 }
 
 /* Declarators [gram.dcl.decl] */
index 9791453..c1c87f2 100644 (file)
@@ -319,7 +319,7 @@ Objective-C and Objective-C++ Dialects}.
 -fno-function-cse  -fno-guess-branch-probability @gol
 -fno-inline  -fno-math-errno  -fno-peephole  -fno-peephole2 @gol
 -funsafe-math-optimizations  -funsafe-loop-optimizations  -ffinite-math-only @gol
--fno-trapping-math  -fno-zero-initialized-in-bss @gol
+-fno-toplevel-reorder -fno-trapping-math  -fno-zero-initialized-in-bss @gol
 -fomit-frame-pointer  -foptimize-register-move @gol
 -foptimize-sibling-calls  -fprefetch-loop-arrays @gol
 -fprofile-generate -fprofile-use @gol
@@ -5336,14 +5336,16 @@ Enabled at levels @option{-O2}, @option{-O3}.
 Parse the whole compilation unit before starting to produce code.
 This allows some extra optimizations to take place but consumes
 more memory (in general).  There are some compatibility issues
-with @emph{unit-at-at-time} mode:
+with @emph{unit-at-a-time} mode:
 @itemize @bullet
 @item
 enabling @emph{unit-at-a-time} mode may change the order
 in which functions, variables, and top-level @code{asm} statements
 are emitted, and will likely break code relying on some particular
 ordering.  The majority of such top-level @code{asm} statements,
-though, can be replaced by @code{section} attributes.
+though, can be replaced by @code{section} attributes.  The
+@option{fno-toplevel-reorder} option may be used to keep the ordering
+used in the input file, at the cost of some optimizations.
 
 @item
 @emph{unit-at-a-time} mode removes unreferenced static variables
@@ -5365,6 +5367,14 @@ but this scheme may not be supported by future releases of GCC@.
 
 Enabled at levels @option{-O2}, @option{-O3}.
 
+@item -fno-toplevel-reorder
+Do not reorder top-level functions, variables, and @code{asm}
+statements.  Output them in the same order that they appear in the
+input file.  When this option is used, unreferenced static variables
+will not be removed.  This option is intended to support existing code
+which relies on a particular ordering.  For new code, it is better to
+use attributes.
+
 @item -fweb
 @opindex fweb
 Constructs webs as commonly used for register allocation purposes and assign