Commit 474eccc6 by Ian Lance Taylor

common.opt (ftoplevel-reorder): New option.

./:	* 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.

From-SVN: r109811
parent 2fbdae36
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>
......
......@@ -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.
......
......@@ -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"
/* 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 %<;%>");
}
......
......@@ -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)
......
......@@ -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 *);
......
......@@ -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)
{
......
......@@ -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
......
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 Espndola <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
......
......@@ -36,6 +36,7 @@
#include "toplev.h"
#include "output.h"
#include "target.h"
#include "cgraph.h"
#include "c-common.h"
......@@ -10741,7 +10742,7 @@ cp_parser_asm_definition (cp_parser* parser)
}
}
else
assemble_asm (string);
cgraph_add_asm_node (string);
}
/* Declarators [gram.dcl.decl] */
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment