+2005-06-24 Jan Hubicka <jh@suse.cz>
+
+ * tree-optimize.c (init_tree_optimization_passes): Fix flags of
+ all_passes and all_ipa_passes.
+
+ * c-common.c: Include cgraph.h
+ (handle_externally_visible_attribute): New function.
+ (c_common_att): Add "externally_visible" attribute.
+ * cgraph.c (decide_is_variable_needed): Obey externally
+ visible flag.
+ (cgraph_varpool_finalize_decl): Avoid redundant checking.
+ * cgraph.h (struct cgraph_node): New flag externally_visible.
+ (decide_is_function_needed): Obey externally visible flag.
+ (cgraph_finalize_function): Avoid redundant checks.
+ (cgraph_function_and_variable_visibility): Bring symbols local
+ when asked for.
+ * common.opt (fwhole-program): New flag.
+
+ * doc/invoke.texi (-fwhole-program): Document.
+
2005-06-24 Mark Mitchell <mark@codesourcery.com>
PR 22171
#include "tree-mudflap.h"
#include "opts.h"
#include "real.h"
+#include "cgraph.h"
cpp_reader *parse_in; /* Declared in c-pragma.h. */
bool *);
static tree handle_used_attribute (tree *, tree, tree, int, bool *);
static tree handle_unused_attribute (tree *, tree, tree, int, bool *);
+static tree handle_externally_visible_attribute (tree *, tree, tree, int,
+ bool *);
static tree handle_const_attribute (tree *, tree, tree, int, bool *);
static tree handle_transparent_union_attribute (tree *, tree, tree,
int, bool *);
handle_used_attribute },
{ "unused", 0, 0, false, false, false,
handle_unused_attribute },
+ { "externally_visible", 0, 0, true, false, false,
+ handle_externally_visible_attribute },
/* The same comments as for noreturn attributes apply to const ones. */
{ "const", 0, 0, true, false, false,
handle_const_attribute },
return NULL_TREE;
}
+/* Handle a "externally_visible" attribute; arguments as in
+ struct attribute_spec.handler. */
+
+static tree
+handle_externally_visible_attribute (tree *pnode, tree name,
+ tree ARG_UNUSED (args),
+ int ARG_UNUSED (flags),
+ bool *no_add_attrs)
+{
+ tree node = *pnode;
+
+ if ((!TREE_STATIC (node) && TREE_CODE (node) != FUNCTION_DECL)
+ || !TREE_PUBLIC (node))
+ {
+ warning (OPT_Wattributes,
+ "%qE attribute have effect only on public objects", name);
+ *no_add_attrs = true;
+ }
+ else if (TREE_CODE (node) == FUNCTION_DECL)
+ {
+ struct cgraph_node *n = cgraph_node (node);
+ n->local.externally_visible = true;
+ if (n->local.finalized)
+ cgraph_mark_needed_node (n);
+ }
+ else if (TREE_CODE (node) == VAR_DECL)
+ {
+ struct cgraph_varpool_node *n = cgraph_varpool_node (node);
+ n->externally_visible = true;
+ if (n->finalized)
+ cgraph_varpool_mark_needed_node (n);
+ }
+ else
+ {
+ warning (OPT_Wattributes, "%qE attribute ignored", name);
+ *no_add_attrs = true;
+ }
+
+ return NULL_TREE;
+}
+
/* Handle a "const" attribute; arguments as in
struct attribute_spec.handler. */
decide_is_variable_needed (struct cgraph_varpool_node *node, tree decl)
{
/* If the user told us it is used, then it must be so. */
- if (lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
+ if (node->externally_visible
+ || lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
return true;
/* ??? If the assembler name is set by hand, it is possible to assemble
/* Since we reclaim unreachable nodes at the end of every language
level unit, we need to be conservative about possible entry points
there. */
- if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
+ else if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
cgraph_varpool_mark_needed_node (node);
if (cgraph_global_info_ready || !flag_unit_at_a_time)
cgraph_varpool_assemble_pending_decls ();
bool analyzed;
/* Set when function is scheduled to be assembled. */
bool output;
+ /* Set when function is visible by other units. */
+ bool externally_visible;
/* Set for aliases once they got through assemble_alias. */
bool alias;
};
decide_is_function_needed (struct cgraph_node *node, tree decl)
{
tree origin;
+ if (MAIN_NAME_P (DECL_NAME (decl))
+ && TREE_PUBLIC (decl))
+ {
+ node->local.externally_visible = true;
+ return true;
+ }
/* If the user told us it is used, then it must be so. */
- if (lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
+ if (node->local.externally_visible
+ || lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
return true;
/* ??? If the assembler name is set by hand, it is possible to assemble
/* Externally visible functions must be output. The exception is
COMDAT functions that must be output only when they are needed. */
- if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
+ if ((TREE_PUBLIC (decl) && !flag_whole_program)
+ && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
return true;
/* Constructors and destructors are reachable from the runtime by
/* Since we reclaim unreachable nodes at the end of every language
level unit, we need to be conservative about possible entry points
there. */
- if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
+ if ((TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl)))
cgraph_mark_reachable_node (node);
/* If not unit at a time, go ahead and emit everything we've found
if (node->reachable
&& (DECL_COMDAT (node->decl)
|| (TREE_PUBLIC (node->decl) && !DECL_EXTERNAL (node->decl))))
- node->local.externally_visible = 1;
+ node->local.externally_visible = true;
+ if (!node->local.externally_visible && node->analyzed
+ && !DECL_EXTERNAL (node->decl))
+ {
+ gcc_assert (flag_whole_program || !TREE_PUBLIC (node->decl));
+ TREE_PUBLIC (node->decl) = 0;
+ }
node->local.local = (!node->needed
&& node->analyzed
&& !DECL_EXTERNAL (node->decl)
if (vnode->needed
&& (DECL_COMDAT (vnode->decl) || TREE_PUBLIC (vnode->decl)))
vnode->externally_visible = 1;
+ if (!vnode->externally_visible)
+ {
+ gcc_assert (flag_whole_program || !TREE_PUBLIC (vnode->decl));
+ TREE_PUBLIC (vnode->decl) = 0;
+ }
gcc_assert (TREE_STATIC (vnode->decl));
}
Common Report Var(flag_web) Init(0)
Construct webs and split unrelated uses of single variable
+fwhole-program
+Common Report Var(flag_whole_program) Init(0)
+Perform whole program optimizations
+
fwrapv
Common Report Var(flag_wrapv)
Assume signed arithmetic overflow wraps around
@code{format}, @code{format_arg}, @code{no_instrument_function},
@code{section}, @code{constructor}, @code{destructor}, @code{used},
@code{unused}, @code{deprecated}, @code{weak}, @code{malloc},
-@code{alias}, @code{warn_unused_result} and @code{nonnull}. Several other
+@code{alias}, @code{warn_unused_result}, @code{nonnull}
+and @code{externally_visible}. Several other
attributes are defined for functions on particular target systems. Other
attributes, including @code{section} are supported for variables declarations
(@pxref{Variable Attributes}) and for types (@pxref{Type Attributes}).
for ELF targets, and also for a.out targets when using the GNU assembler
and linker.
+@item externally_visible
+@cindex @code{externally_visible} attribute.
+This attribute, attached to a global variable or function nullify
+effect of @option{-fwhole-program} command line option, so the object
+remain visible outside the current compilation unit
+
@end table
You can specify multiple attributes in a declaration by separating them
-ftree-dominator-opts -ftree-dse -ftree-copyrename -ftree-sink @gol
-ftree-ch -ftree-sra -ftree-ter -ftree-lrs -ftree-fre -ftree-vectorize @gol
-ftree-salias -fweb @gol
--ftree-copy-prop -ftree-store-ccp -ftree-store-copy-prop @gol
+-ftree-copy-prop -ftree-store-ccp -ftree-store-copy-prop -fwhole-program @gol
--param @var{name}=@var{value}
-O -O0 -O1 -O2 -O3 -Os}
on targets where the default format for debugging information supports
variable tracking.
+@item -fwhole-program
+@opindex fwhole-program
+Assume that the current compilation unit represents whole program being
+compiled. All public functions and variables with the exception of @code{main}
+and those marged by attribute @code{externally_visible} become static functions
+and in a affect gets more aggresively optimized by interprocedural optimizers.
+While this option is equivalent to proper use of @code{static} keyword for
+programs consitsting of single file, in combination with option
+@option{--combine} this flag can be used to compile most of smaller scale C
+programs since the functions and variables become local for the whole combined
+compilation unit, not for the single source file itself.
+
+
@item -fno-cprop-registers
@opindex fno-cprop-registers
After register allocation and post-register allocation instruction splitting,
+2005-06-22 Jan Hubicka <jh@suse.cz>
+
+ * wholeprogram-1.c: New testcase.
+ * wholeprogram-2.c: New testcase.
+
2005-06-24 Mark Mitchell <mark@codesourcery.com>
PR 22171
--- /dev/null
+/* { dg-options "-O2 -fdump-tree-optimized -fwhole-program" } */
+int b[100];
+void abort (void);
+
+void
+large_function ()
+{
+ int i;
+ for (i = 0; i < 99; i++)
+ if (b[i] / (b[i+1] + 1))
+ abort ();
+}
+
+main ()
+{
+ large_function ();
+}
+
+/* Function should be inlined as called once. */
+/* { dg-final { scan-tree-dump-not "large_function" "optimized"} } */
+
+/* { dg-final { cleanup-tree-dump "optimized" } } */
+
--- /dev/null
+/* { dg-options "-O2 -fdump-tree-optimized -fwhole-program" } */
+__attribute__ ((externally_visible))
+void
+externally_visible_function ()
+{
+}
+/* { dg-final { scan-tree-dump "externally_visible_function" "optimized"} } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */