summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2005-06-24 15:14:04 +0000
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2005-06-24 15:14:04 +0000
commit62eec3b440a3c0f2b1c6b26fc88262837ebf21db (patch)
treecb74c75feb0a3380d0f1a108528cdc35a05f7892 /gcc
parent55459e6c6f278a09cdac19118b4256c42ce95660 (diff)
downloadgcc-62eec3b440a3c0f2b1c6b26fc88262837ebf21db.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@101295 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog20
-rw-r--r--gcc/c-common.c46
-rw-r--r--gcc/cgraph.c5
-rw-r--r--gcc/cgraph.h2
-rw-r--r--gcc/cgraphunit.c27
-rw-r--r--gcc/common.opt4
-rw-r--r--gcc/doc/extend.texi9
-rw-r--r--gcc/doc/invoke.texi15
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/wholeprogram-1.c23
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/wholeprogram-2.c8
11 files changed, 156 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 818aea579ca..f1c680c5b82 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,23 @@
+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
diff --git a/gcc/c-common.c b/gcc/c-common.c
index b7263aac48a..c9ebb58cf8b 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -47,6 +47,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "tree-mudflap.h"
#include "opts.h"
#include "real.h"
+#include "cgraph.h"
cpp_reader *parse_in; /* Declared in c-pragma.h. */
@@ -514,6 +515,8 @@ static tree handle_always_inline_attribute (tree *, tree, tree, int,
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 *);
@@ -580,6 +583,8 @@ const struct attribute_spec c_common_attribute_table[] =
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 },
@@ -4129,6 +4134,47 @@ handle_unused_attribute (tree *node, tree name, tree ARG_UNUSED (args),
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. */
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index b9b1b14f646..af84ebf2156 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -807,7 +807,8 @@ bool
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
@@ -863,7 +864,7 @@ cgraph_varpool_finalize_decl (tree decl)
/* 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 ();
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 9406e090f33..9b7306bbbee 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -159,6 +159,8 @@ struct cgraph_node GTY((chain_next ("%h.next"), chain_prev ("%h.previous")))
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;
};
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 2f993f3d443..f3d718d8bcf 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -189,9 +189,16 @@ static bool
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
@@ -209,7 +216,8 @@ decide_is_function_needed (struct cgraph_node *node, tree decl)
/* 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
@@ -428,7 +436,7 @@ cgraph_finalize_function (tree decl, bool nested)
/* 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
@@ -1059,7 +1067,13 @@ cgraph_function_and_variable_visibility (void)
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)
@@ -1070,6 +1084,11 @@ cgraph_function_and_variable_visibility (void)
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));
}
diff --git a/gcc/common.opt b/gcc/common.opt
index f54eabce8a1..f1e27d5773c 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -986,6 +986,10 @@ fweb
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
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 6a31e9cd325..c0363ddbe0f 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -1525,7 +1525,8 @@ attributes are currently defined for functions on all targets:
@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}).
@@ -2345,6 +2346,12 @@ also be used with non-function declarations. Weak symbols are supported
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
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index ebb783e95d0..4e229b03c86 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -335,7 +335,7 @@ Objective-C and Objective-C++ Dialects}.
-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}
@@ -5256,6 +5256,19 @@ Enabled at levels @option{-O2}, @option{-O3}, @option{-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,
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f699cd2eb0b..503bb0992cd 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+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
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/wholeprogram-1.c b/gcc/testsuite/gcc.dg/tree-ssa/wholeprogram-1.c
new file mode 100644
index 00000000000..9d0af1f2391
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/wholeprogram-1.c
@@ -0,0 +1,23 @@
+/* { 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" } } */
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/wholeprogram-2.c b/gcc/testsuite/gcc.dg/tree-ssa/wholeprogram-2.c
new file mode 100644
index 00000000000..bbdd0dd48cc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/wholeprogram-2.c
@@ -0,0 +1,8 @@
+/* { 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" } } */