tree-optimize.c (init_tree_optimization_passes): Fix flags of all_passes and all_ipa_...
authorJan Hubicka <jh@suse.cz>
Fri, 24 Jun 2005 15:14:04 +0000 (17:14 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Fri, 24 Jun 2005 15:14:04 +0000 (15:14 +0000)
* 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.

From-SVN: r101295

gcc/ChangeLog
gcc/c-common.c
gcc/cgraph.c
gcc/cgraph.h
gcc/cgraphunit.c
gcc/common.opt
gcc/doc/extend.texi
gcc/doc/invoke.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/wholeprogram-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/wholeprogram-2.c [new file with mode: 0644]

index 818aea5..f1c680c 100644 (file)
@@ -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
index b7263aa..c9ebb58 100644 (file)
@@ -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.  */
 
index b9b1b14..af84ebf 100644 (file)
@@ -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 ();
index 9406e09..9b7306b 100644 (file)
@@ -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;
 };
index 2f993f3..f3d718d 100644 (file)
@@ -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));
     }
 
index f54eabc..f1e27d5 100644 (file)
@@ -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
index 6a31e9c..c0363dd 100644 (file)
@@ -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
index ebb783e..4e229b0 100644 (file)
@@ -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,
index f699cd2..503bb09 100644 (file)
@@ -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 (file)
index 0000000..9d0af1f
--- /dev/null
@@ -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 (file)
index 0000000..bbdd0dd
--- /dev/null
@@ -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" } } */