This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFA][lto merge]: support for gcc @file


This patch http://gcc.gnu.org/ml/gcc-patches/2009-02/msg00063.html adds
support to the gcc driver to be invoked with @file to avoid
massive command lines that are sometimes generated in the context
of LTO.

This feature is not necessarily related to LTO, but we have found
it useful.  I don't think we have maintainers for this area, so I
need global reviewers to approve it.

Bootstrapped and tested on x86_64.  The feature is heavily tested
by -fwhopr, which I'm still not merging in.


Thanks.  Diego.

Index: tree-pretty-print.c
===================================================================
--- tree-pretty-print.c	(revision 146200)
+++ tree-pretty-print.c	(working copy)
@@ -51,10 +51,10 @@ static void do_niy (pretty_printer *, co

 #define NIY do_niy(buffer,node)

-#define PRINT_FUNCTION_NAME(NODE)  pp_printf             \
-  (buffer, "%s", TREE_CODE (NODE) == NOP_EXPR ?              \
-   lang_hooks.decl_printable_name (TREE_OPERAND (NODE, 0), 1) : \
-   lang_hooks.decl_printable_name (NODE, 1))
+#define PRINT_FUNCTION_NAME(NODE)  pp_printf	\
+  (buffer, "%s", TREE_CODE (NODE) == NOP_EXPR	\
+   ? get_name (TREE_OPERAND (NODE, 0))		\
+   : get_name (NODE))

 static pretty_printer buffer;
 static int initialized = 0;
@@ -488,6 +488,7 @@ dump_generic_node (pretty_printer *buffe

     case TREE_BINFO:
       dump_generic_node (buffer, BINFO_TYPE (node), spc, flags, false);
+      break;

     case TREE_VEC:
       {
@@ -551,8 +552,7 @@ dump_generic_node (pretty_printer *buffe
 	    else if (TREE_CODE (node) == VECTOR_TYPE)
 	      {
 		pp_string (buffer, "vector ");
-		dump_generic_node (buffer, TREE_TYPE (node),
-				   spc, flags, false);
+		dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
 	      }
 	    else if (TREE_CODE (node) == INTEGER_TYPE)
 	      {
@@ -562,6 +562,24 @@ dump_generic_node (pretty_printer *buffe
 		pp_decimal_int (buffer, TYPE_PRECISION (node));
 		pp_string (buffer, ">");
 	      }
+	    else if (TREE_CODE (node) == COMPLEX_TYPE)
+	      {
+		pp_string (buffer, "__complex__ ");
+		dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
+	      }
+	    else if (TREE_CODE (node) == REAL_TYPE)
+	      {
+		pp_string (buffer, "<float:");
+		pp_decimal_int (buffer, TYPE_PRECISION (node));
+		pp_string (buffer, ">");
+	      }
+	    else if (TREE_CODE (node) == FIXED_POINT_TYPE)
+	      {
+		pp_string (buffer, "<fixed-point-");
+		pp_string (buffer, TYPE_SATURATING (node) ? "sat:" : "nonsat:");
+		pp_decimal_int (buffer, TYPE_PRECISION (node));
+		pp_string (buffer, ">");
+	      }
 	    else
               pp_string (buffer, "<unnamed type>");
 	  }
@@ -572,7 +590,12 @@ dump_generic_node (pretty_printer *buffe
     case REFERENCE_TYPE:
       str = (TREE_CODE (node) == POINTER_TYPE ? "*" : "&");

-      if (TREE_CODE (TREE_TYPE (node)) == FUNCTION_TYPE)
+      if (TREE_TYPE (node) == NULL)
+        {
+	  pp_string (buffer, str);
+          pp_string (buffer, "<null type>");
+        }
+      else if (TREE_CODE (TREE_TYPE (node)) == FUNCTION_TYPE)
         {
 	  tree fnode = TREE_TYPE (node);

@@ -612,11 +635,6 @@ dump_generic_node (pretty_printer *buffe
       NIY;
       break;

-    case METHOD_TYPE:
-      dump_decl_name (buffer, TYPE_NAME (TYPE_METHOD_BASETYPE (node)), flags);
-      pp_string (buffer, "::");
-      break;
-
     case TARGET_MEM_REF:
       {
 	const char *sep = "";
@@ -710,7 +728,12 @@ dump_generic_node (pretty_printer *buffe

         if (TYPE_NAME (node))
 	  dump_generic_node (buffer, TYPE_NAME (node), spc, flags, false);
-        else
+	else if (!(flags & TDF_SLIM))
+	  /* FIXME: If we eliminate the 'else' above and attempt
+	     to show the fields for named types, we may get stuck
+	     following a cycle of pointers to structs.  The alleged
+	     self-reference check in print_struct_decl will not detect
+	     cycles involving more than one pointer or struct type.  */
 	  print_struct_decl (buffer, node, spc, flags);
         break;
       }
@@ -836,6 +859,23 @@ dump_generic_node (pretty_printer *buffe
       break;

     case FUNCTION_TYPE:
+    case METHOD_TYPE:
+      dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
+      pp_space (buffer);
+      if (TREE_CODE (node) == METHOD_TYPE)
+	{
+	  if (TYPE_METHOD_BASETYPE (node))
+	    dump_decl_name (buffer, TYPE_NAME (TYPE_METHOD_BASETYPE (node)),
+			    flags);
+	  else
+	    pp_string (buffer, "<null method basetype>");
+	  pp_string (buffer, "::");
+	}
+      if (TYPE_NAME (node) && DECL_NAME (TYPE_NAME (node)))
+	dump_decl_name (buffer, TYPE_NAME (node), flags);
+      else
+	pp_printf (buffer, "<T%x>", TYPE_UID (node));
+      dump_function_declaration (buffer, node, spc, flags);
       break;

     case FUNCTION_DECL:
@@ -2206,8 +2246,8 @@ print_struct_decl (pretty_printer *buffe
 	   Maybe this could be solved by looking at the scope in which the
 	   structure was declared.  */
 	if (TREE_TYPE (tmp) != node
-	    || (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
-		&& TREE_TYPE (TREE_TYPE (tmp)) != node))
+	    && (TREE_CODE (TREE_TYPE (tmp)) != POINTER_TYPE
+		|| TREE_TYPE (TREE_TYPE (tmp)) != node))
 	  {
 	    print_declaration (buffer, tmp, spc+2, flags);
 	    pp_newline (buffer);
Index: cgraph.c
===================================================================
--- cgraph.c	(revision 146200)
+++ cgraph.c	(working copy)
@@ -1527,4 +1527,172 @@ cgraph_add_new_function (tree fndecl, bo
     }
 }

+/*
+ * A call-graph set is a collection of call-graph nodes.  A node can
+ * appear in multiple sets.  Call-graph sets are garbage-collected.
+ */
+
+/* Hash a cgraph node set element.  */
+
+static hashval_t
+hash_cgraph_node_set_element (const void *p)
+{
+  const_cgraph_node_set_element element = (const_cgraph_node_set_element) p;
+  return htab_hash_pointer (element->node);
+}
+
+/* Compare two cgraph node set elements.  */
+
+static int
+eq_cgraph_node_set_element (const void *p1, const void *p2)
+{
+  const_cgraph_node_set_element e1 = (const_cgraph_node_set_element) p1;
+  const_cgraph_node_set_element e2 = (const_cgraph_node_set_element) p2;
+
+  return e1->node == e2->node;
+}
+
+/* Create a new cgraph node set.  */
+
+cgraph_node_set
+cgraph_node_set_new (void)
+{
+  cgraph_node_set new_node_set;
+
+  new_node_set = GGC_NEW (struct cgraph_node_set_def);
+  new_node_set->hashtab = htab_create_ggc (10,
+					   hash_cgraph_node_set_element,
+					   eq_cgraph_node_set_element,
+					   NULL);
+  new_node_set->nodes = NULL;
+  return new_node_set;
+}
+
+/* Add cgraph_node NODE to cgraph_node_set SET. */
+
+void
+cgraph_node_set_add (cgraph_node_set set, struct cgraph_node *node)
+{
+  void **slot;
+  cgraph_node_set_element element;
+  struct cgraph_node_set_element_def dummy;
+
+  dummy.node = node;
+  slot = htab_find_slot (set->hashtab, &dummy, INSERT);
+
+  if (*slot != HTAB_EMPTY_ENTRY)
+    {
+#ifdef ENABLE_CHECKING
+      element = (cgraph_node_set_element) *slot;
+      gcc_assert (node == element->node
+		  && (VEC_index (cgraph_node_ptr, set->nodes, element->index)
+		      == node));
+#endif
+      return;
+    }
+
+  /* Insert node into hash table. */
+  element =
+    (cgraph_node_set_element) GGC_NEW (struct cgraph_node_set_element_def);
+  element->node = node;
+  element->index = VEC_length (cgraph_node_ptr, set->nodes);
+  *slot = element;
+
+  /* Insert into node vector. */
+  VEC_safe_push (cgraph_node_ptr, gc, set->nodes, node);
+}
+
+/* Remove cgraph_node NODE from cgraph_node_set SET. */
+
+void
+cgraph_node_set_remove (cgraph_node_set set, struct cgraph_node *node)
+{
+  void **slot, **last_slot;
+  cgraph_node_set_element element, last_element;
+  struct cgraph_node *last_node;
+  struct cgraph_node_set_element_def dummy;
+
+  dummy.node = node;
+  slot = htab_find_slot (set->hashtab, &dummy, NO_INSERT);
+  if (slot == NULL)
+    return;
+
+  element = (cgraph_node_set_element) *slot;
+#ifdef ENABLE_CHECKING
+  gcc_assert (VEC_index (cgraph_node_ptr, set->nodes, element->index)
+	      == node);
+#endif
+
+  /* Remove from vector. We do this by swapping node with the last element
+     of the vector.  */
+  last_node = VEC_pop (cgraph_node_ptr, set->nodes);
+  if (last_node != node)
+    {
+      dummy.node = last_node;
+      last_slot = htab_find_slot (set->hashtab, &dummy, NO_INSERT);
+      last_element = (cgraph_node_set_element) *last_slot;
+      gcc_assert (last_element);
+
+      /* Move the last element to the original spot of NODE. */
+      last_element->index = element->index;
+      VEC_replace (cgraph_node_ptr, set->nodes, last_element->index,
+		   last_node);
+    }
+
+  /* Remove element from hash table. */
+  htab_clear_slot (set->hashtab, slot);
+  ggc_free (element);
+}
+
+/* Find NODE in SET and return an iterator to it if found.  A null iterator
+   is returned if NODE is not in SET.  */
+
+cgraph_node_set_iterator
+cgraph_node_set_find (cgraph_node_set set, struct cgraph_node *node)
+{
+  void **slot;
+  struct cgraph_node_set_element_def dummy;
+  cgraph_node_set_element element;
+  cgraph_node_set_iterator csi;
+
+  dummy.node = node;
+  slot = htab_find_slot (set->hashtab, &dummy, NO_INSERT);
+  if (slot == NULL)
+    csi.index = (unsigned) ~0;
+  else
+    {
+      element = (cgraph_node_set_element) *slot;
+#ifdef ENABLE_CHECKING
+      gcc_assert (VEC_index (cgraph_node_ptr, set->nodes, element->index)
+		  == node);
+#endif
+      csi.index = element->index;
+    }
+  csi.set = set;
+
+  return csi;
+}
+
+/* Dump content of SET to file F. */
+
+void
+dump_cgraph_node_set (FILE *f, cgraph_node_set set)
+{
+  cgraph_node_set_iterator iter;
+
+  for (iter = csi_start (set); !csi_end_p (iter); csi_next (&iter))
+    {
+      struct cgraph_node *node = csi_node (iter);
+      dump_cgraph_node (f, node);
+    }
+}
+
+/* Dump content of SET to stderr. */
+
+void
+debug_cgraph_node_set (cgraph_node_set set)
+{
+  dump_cgraph_node_set (stderr, set);
+}
+
 #include "gt-cgraph.h"
Index: cgraph.h
===================================================================
--- cgraph.h	(revision 146200)
+++ cgraph.h	(working copy)
@@ -189,6 +189,12 @@ struct cgraph_node GTY((chain_next ("%h.
   tree inline_decl;
 };

+typedef struct cgraph_node *cgraph_node_ptr;
+
+DEF_VEC_P(cgraph_node_ptr);
+DEF_VEC_ALLOC_P(cgraph_node_ptr,heap);
+DEF_VEC_ALLOC_P(cgraph_node_ptr,gc);
+
 #define DEFCIFCODE(code, string)	CIF_ ## code,
 /* Reasons for inlining failures.  */
 typedef enum {
@@ -302,6 +308,40 @@ extern GTY(()) struct cgraph_node *cgrap
 extern GTY(()) struct cgraph_asm_node *cgraph_asm_nodes;
 extern GTY(()) int cgraph_order;

+/* A cgraph node set is a collection of cgraph nodes.  A cgraph node
+   can appear in multiple sets. */
+
+struct cgraph_node_set_def GTY(())
+{
+  htab_t GTY((param_is (struct cgraph_node_set_element_def))) hashtab;
+  VEC(cgraph_node_ptr, gc) *nodes;
+  PTR GTY ((skip)) aux;
+};
+
+typedef struct cgraph_node_set_def *cgraph_node_set;
+
+DEF_VEC_P(cgraph_node_set);
+DEF_VEC_ALLOC_P(cgraph_node_set,gc);
+DEF_VEC_ALLOC_P(cgraph_node_set,heap);
+
+/* A cgraph node set element contains an index in the vector of nodes in
+   the set. */
+
+struct cgraph_node_set_element_def GTY(())
+{
+  struct cgraph_node *node;
+  HOST_WIDE_INT index;
+};
+
+typedef struct cgraph_node_set_element_def *cgraph_node_set_element;
+typedef const struct cgraph_node_set_element_def
*const_cgraph_node_set_element;
+
+typedef struct
+{
+  cgraph_node_set set;
+  unsigned index;
+} cgraph_node_set_iterator;
+
 /* In cgraph.c  */
 void dump_cgraph (FILE *);
 void debug_cgraph (void);
@@ -341,6 +381,69 @@ enum availability cgraph_function_body_a
 void cgraph_add_new_function (tree, bool);
 const char* cgraph_inline_failed_string (cgraph_inline_failed_t);

+cgraph_node_set cgraph_node_set_new (void);
+cgraph_node_set_iterator cgraph_node_set_find (cgraph_node_set set,
+					       struct cgraph_node *node);
+void cgraph_node_set_add (cgraph_node_set, struct cgraph_node *);
+void cgraph_node_set_remove (cgraph_node_set, struct cgraph_node *);
+void dump_cgraph_node_set (FILE *f, cgraph_node_set);
+void debug_cgraph_node_set (cgraph_node_set);
+const char *cgraph_inline_failed_string (cgraph_inline_failed_t);
+
+/* Return true if iterator CSI points to nothing. */
+
+static inline bool
+csi_end_p (cgraph_node_set_iterator csi)
+{
+  return csi.index >= VEC_length (cgraph_node_ptr, csi.set->nodes);
+}
+
+/* Advance iterator CSI. */
+
+static inline void
+csi_next (cgraph_node_set_iterator *csi)
+{
+  csi->index++;
+}
+
+/* Return the node pointed to by CSI. */
+
+static inline struct cgraph_node *
+csi_node (cgraph_node_set_iterator csi)
+{
+  return VEC_index (cgraph_node_ptr, csi.set->nodes, csi.index);
+}
+
+/* Return an iterator to the first node in SET. */
+
+static inline cgraph_node_set_iterator
+csi_start (cgraph_node_set set)
+{
+  cgraph_node_set_iterator csi;
+
+  csi.set = set;
+  csi.index = 0;
+  return csi;
+}
+
+/* Return true if SET contains NODE. */
+
+static inline bool
+cgraph_node_in_set_p (struct cgraph_node *node, cgraph_node_set set)
+{
+  cgraph_node_set_iterator csi;
+  csi = cgraph_node_set_find (set, node);
+  return !csi_end_p (csi);
+}
+
+/* Return number of nodes in SET. */
+
+static inline size_t
+cgraph_node_set_size (cgraph_node_set set)
+{
+  return htab_elements (set->hashtab);
+}
+
 /* In cgraphunit.c  */
 void cgraph_finalize_function (tree, bool);
 void cgraph_mark_if_needed (tree);
Index: tree.h
===================================================================
--- tree.h	(revision 146200)
+++ tree.h	(working copy)
@@ -183,6 +183,22 @@ DEF_VEC_P(tree);
 DEF_VEC_ALLOC_P(tree,gc);
 DEF_VEC_ALLOC_P(tree,heap);

+/* We have to be able to tell cgraph about the needed-ness of the target
+   of an alias.  This requires that the decl have been defined.  Aliases
+   that precede their definition have to be queued for later processing.  */
+
+typedef struct alias_pair GTY(())
+{
+  tree decl;
+  tree target;
+} alias_pair;
+
+/* Define gc'd vector type.  */
+DEF_VEC_O(alias_pair);
+DEF_VEC_ALLOC_O(alias_pair,gc);
+
+extern GTY(()) VEC(alias_pair,gc) * alias_pairs;
+
 
 /* Classify which part of the compiler has defined a given builtin function.
    Note that we assume below that this is no more than two bits.  */
@@ -1272,7 +1288,7 @@ extern void omp_clause_range_check_faile
    This is interesting in an inline function, since it might not need
    to be compiled separately.
    Nonzero in a RECORD_TYPE, UNION_TYPE, QUAL_UNION_TYPE or ENUMERAL_TYPE
-   if the sdb debugging info for the type has been written.
+   if the debugging info for the type has been written.
    In a BLOCK node, nonzero if reorder_blocks has already seen this block.
    In an SSA_NAME node, nonzero if the SSA_NAME occurs in an abnormal
    PHI node.  */
@@ -2478,9 +2494,9 @@ struct function;

 /*  For FIELD_DECLs, this is the RECORD_TYPE, UNION_TYPE, or
     QUAL_UNION_TYPE node that the field is a member of.  For VAR_DECL,
-    PARM_DECL, FUNCTION_DECL, LABEL_DECL, and CONST_DECL nodes, this
-    points to either the FUNCTION_DECL for the containing function,
-    the RECORD_TYPE or UNION_TYPE for the containing type, or
+    PARM_DECL, FUNCTION_DECL, LABEL_DECL, RESULT_DECL, and CONST_DECL
+    nodes, this points to either the FUNCTION_DECL for the containing
+    function, the RECORD_TYPE or UNION_TYPE for the containing type, or
     NULL_TREE or a TRANSLATION_UNIT_DECL if the given decl has "file
     scope".  */
 #define DECL_CONTEXT(NODE) (DECL_MINIMAL_CHECK (NODE)->decl_minimal.context)
@@ -5027,6 +5043,7 @@ extern void process_pending_assemble_ext
 extern void finish_aliases_1 (void);
 extern void finish_aliases_2 (void);
 extern tree emutls_decl (tree);
+extern void remove_unreachable_alias_pairs (void);

 /* In stmt.c */
 extern void expand_computed_goto (tree);
Index: tree-pass.h
===================================================================
--- tree-pass.h	(revision 146200)
+++ tree-pass.h	(working copy)
@@ -154,6 +154,7 @@ struct rtl_opt_pass

 struct varpool_node;
 struct cgraph_node;
+struct cgraph_node_set_def;

 /* Description of IPA pass with generate summary, write, execute, read and
    transform stages.  */
@@ -166,7 +167,7 @@ struct ipa_opt_pass
   void (*generate_summary) (void);

   /* This hook is used to serialize IPA summaries on disk.  */
-  void (*write_summary) (void);
+  void (*write_summary) (struct cgraph_node_set_def *);

   /* For most ipa passes, the information can only be deserialized in
      one chunk.  However, function bodies are read function at a time
Index: diagnostic.h
===================================================================
--- diagnostic.h	(revision 146200)
+++ diagnostic.h	(working copy)
@@ -238,4 +238,8 @@ extern void print_gimple_stmt (FILE *, g
 extern void print_gimple_expr (FILE *, gimple, int, int);
 extern void dump_gimple_stmt (pretty_printer *, gimple, int, int);

+/* In toplev.c  */
+extern bool default_tree_printer (pretty_printer *, text_info *, const char *,
+				  int, bool, bool, bool);
+
 #endif /* ! GCC_DIAGNOSTIC_H */
Index: gcc.c
===================================================================
--- gcc.c	(revision 146200)
+++ gcc.c	(working copy)
@@ -4741,6 +4741,49 @@ spec_path (char *path, void *data)
   return NULL;
 }

+/* Create a temporary FILE with the contents of ARGV. Add @FILE to the
+   argument list. */
+
+static void
+create_at_file (char **argv)
+{
+  char *temp_file = make_temp_file ("");
+  char *at_argument = concat ("@", temp_file, NULL);
+  FILE *f = fopen (temp_file, "w");
+  int status;
+
+  if (f == NULL)
+    fatal ("could not open temporary response file %s",
+	   temp_file);
+
+  status = writeargv (argv, f);
+
+  if (status)
+    fatal ("could not write to temporary response file %s",
+	   temp_file);
+
+  status = fclose (f);
+
+  if (EOF == status)
+    fatal ("could not close temporary response file %s",
+	   temp_file);
+
+  store_arg (at_argument, 0, 0);
+
+  record_temp_file (temp_file, !save_temps_flag, !save_temps_flag);
+}
+
+/* True if we should compile INFILE. */
+
+static bool
+compile_input_file_p (struct infile *infile)
+{
+  if ((!infile->language) || (infile->language[0] != '*'))
+    if (infile->incompiler == input_file_compiler)
+      return true;
+  return false;
+}
+
 /* Process the sub-spec SPEC as a portion of a larger spec.
    This is like processing a whole spec except that we do
    not initialize at the beginning and we do not supply a
@@ -5107,9 +5150,37 @@ do_spec_1 (const char *spec, int inswitc
 	  case 'i':
 	    if (combine_inputs)
 	      {
-		for (i = 0; (int) i < n_infiles; i++)
-		  if ((!infiles[i].language) || (infiles[i].language[0] != '*'))
-		    if (infiles[i].incompiler == input_file_compiler)
+		if (at_file_supplied)
+		  {
+		    /* We are going to expand `%i' to `@FILE', where FILE
+		       is a newly-created temporary filename.  The filenames
+		       that would usually be expanded in place of %o will be
+		       written to the temporary file.  */
+		    char **argv;
+		    int n_files = 0;
+		    int j;
+
+		    for (i = 0; i < n_infiles; i++)
+		      if (compile_input_file_p (&infiles[i]))
+			n_files++;
+
+		    argv = (char **) alloca (sizeof (char *) * (n_files + 1));
+
+		    /* Copy the strings over.  */
+		    for (i = 0, j = 0; i < n_infiles; i++)
+		      if (compile_input_file_p (&infiles[i]))
+			{
+			  argv[j] = CONST_CAST (char *, infiles[i].name);
+			  infiles[i].compiled = true;
+			  j++;
+			}
+		    argv[j] = NULL;
+
+		    create_at_file (argv);
+		  }
+		else
+		  for (i = 0; (int) i < n_infiles; i++)
+		    if (compile_input_file_p (&infiles[i]))
 		      {
 			store_arg (infiles[i].name, 0, 0);
 			infiles[i].compiled = true;
@@ -5187,14 +5258,8 @@ do_spec_1 (const char *spec, int inswitc
                      that would usually be expanded in place of %o will be
                      written to the temporary file.  */

-                  char *temp_file = make_temp_file ("");
-                  char *at_argument;
                   char **argv;
-                  int n_files, j, status;
-                  FILE *f;
-
-                  at_argument = concat ("@", temp_file, NULL);
-                  store_arg (at_argument, 0, 0);
+                  int n_files, j;

                   /* Convert OUTFILES into a form suitable for writeargv.  */

@@ -5213,25 +5278,7 @@ do_spec_1 (const char *spec, int inswitc
                       }
                   argv[j] = NULL;

-                  f = fopen (temp_file, "w");
-
-                  if (f == NULL)
-                    fatal ("could not open temporary response file %s",
-                           temp_file);
-
-                  status = writeargv (argv, f);
-
-                  if (status)
-                    fatal ("could not write to temporary response file %s",
-                           temp_file);
-
-                  status = fclose (f);
-
-                  if (EOF == status)
-                    fatal ("could not close temporary response file %s",
-                           temp_file);
-
-                  record_temp_file (temp_file, !save_temps_flag,
!save_temps_flag);
+		  create_at_file (argv);
                 }
               else
                 for (i = 0; i < max; i++)
Index: omp-low.c
===================================================================
--- omp-low.c	(revision 146200)
+++ omp-low.c	(working copy)
@@ -1577,6 +1577,7 @@ create_omp_child_function (omp_context *
   t = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
   DECL_ARTIFICIAL (t) = 1;
   DECL_IGNORED_P (t) = 1;
+  DECL_CONTEXT (t) = decl;
   DECL_RESULT (decl) = t;

   t = build_decl (PARM_DECL, get_identifier (".omp_data_i"), ptr_type_node);
Index: toplev.c
===================================================================
--- toplev.c	(revision 146200)
+++ toplev.c	(working copy)
@@ -993,11 +993,6 @@ compile_file (void)
   varpool_assemble_pending_decls ();
   finish_aliases_2 ();

-  /* This must occur after the loop to output deferred functions.
-     Else the coverage initializer would not be emitted if all the
-     functions in this compilation unit were deferred.  */
-  coverage_finish ();
-
   /* Likewise for mudflap static object registrations.  */
   if (flag_mudflap)
     mudflap_finish_file ();
@@ -1496,8 +1491,8 @@ default_pch_valid_p (const void *data_p,
 }

 /* Default tree printer.   Handles declarations only.  */
-static bool
-default_tree_printer (pretty_printer * pp, text_info *text, const char *spec,
+bool
+default_tree_printer (pretty_printer *pp, text_info *text, const char *spec,
 		      int precision, bool wide, bool set_locus, bool hash)
 {
   tree t;
@@ -1508,6 +1503,15 @@ default_tree_printer (pretty_printer * p

   switch (*spec)
     {
+    case 'E':
+      t = va_arg (*text->args_ptr, tree);
+      if (TREE_CODE (t) == IDENTIFIER_NODE)
+	{
+	  pp_string (pp, IDENTIFIER_POINTER (t));
+	  return true;
+	}
+      break;
+
     case 'D':
       t = va_arg (*text->args_ptr, tree);
       if (DECL_DEBUG_EXPR_IS_FROM (t) && DECL_DEBUG_EXPR (t))
@@ -2261,16 +2265,18 @@ do_compile (void)
    It is not safe to call this function more than once.  */

 int
-toplev_main (unsigned int argc, const char **argv)
+toplev_main (int argc, char **argv)
 {
-  save_argv = argv;
+  expandargv (&argc, &argv);
+
+  save_argv = (const char **) argv;

   /* Initialization of GCC's environment, and diagnostics.  */
   general_init (argv[0]);

   /* Parse the options and do minimal processing; basically just
      enough to default flags appropriately.  */
-  decode_options (argc, argv);
+  decode_options (argc, (const char **) argv);

   init_local_tick ();

Index: toplev.h
===================================================================
--- toplev.h	(revision 146200)
+++ toplev.h	(working copy)
@@ -27,7 +27,7 @@ along with GCC; see the file COPYING3.
 #define skip_leading_substring(whole,  part) \
    (strncmp (whole, part, strlen (part)) ? NULL : whole + strlen (part))

-extern int toplev_main (unsigned int, const char **);
+extern int toplev_main (int, char **);
 extern int read_integral_parameter (const char *, const char *, const int);
 extern void strip_off_ending (char *, int);
 extern const char *trim_filename (const char *);
Index: cgraphunit.c
===================================================================
--- cgraphunit.c	(revision 146200)
+++ cgraphunit.c	(working copy)
@@ -1043,8 +1043,6 @@ cgraph_expand_function (struct cgraph_no
   gcc_assert (node->lowered);

   /* Generate RTL for the body of DECL.  */
-  if (lang_hooks.callgraph.emit_associated_thunks)
-    lang_hooks.callgraph.emit_associated_thunks (decl);
   tree_rest_of_compilation (decl);

   /* Make sure that BE didn't give up on compiling.  */
@@ -1237,10 +1235,45 @@ ipa_passes (void)
   current_function_decl = NULL;
   gimple_register_cfg_hooks ();
   bitmap_obstack_initialize (NULL);
+
+  /* Remove bodies of extern inline functions that we never inlined.  */
+  cgraph_remove_unreachable_nodes (false, dump_file);
+
+  /* Generate coverage variables and constructors.  */
+  coverage_finish ();
+
+  /* Process new functions added so far.  */
+  set_cfun (NULL);
+  current_function_decl = NULL;
+  cgraph_process_new_functions ();
+
   execute_ipa_pass_list (all_ipa_passes);
   bitmap_obstack_release (NULL);
 }

+
+/* Emit thunks for every node in the cgraph.  */
+
+static void
+cgraph_emit_thunks (void)
+{
+  struct cgraph_node *n;
+
+  for (n = cgraph_nodes; n; n = n->next)
+    {
+      /* Only emit thunks on functions defined in this TU.
+	 Note that this may emit more thunks than strictly necessary.
+	 During optimization some nodes may disappear.  It would be
+	 nice to only emit thunks only for the functions that will be
+	 emitted, but we cannot know that until the inliner and other
+	 IPA passes have run (see the sequencing of the call to
+	 cgraph_mark_functions_to_output in cgraph_optimize).  */
+      if (!DECL_EXTERNAL (n->decl))
+	lang_hooks.callgraph.emit_associated_thunks (n->decl);
+    }
+}
+
+
 /* Perform simple optimizations based on callgraph.  */

 void
@@ -1253,6 +1286,18 @@ cgraph_optimize (void)
   verify_cgraph ();
 #endif

+  /* Emit thunks, if needed.  */
+  if (lang_hooks.callgraph.emit_associated_thunks)
+    {
+      cgraph_emit_thunks ();
+
+      /* Thunk emission may produce errors for thunks that
+	 need varargs (since asm thunks have been disabled).  This
+	 shouldn't be needed after thunks are properly lowered.  */
+      if (errorcount || sorrycount)
+	return;
+    }
+
   /* Call functions declared with the "constructor" or "destructor"
      attribute.  */
   cgraph_build_cdtor_fns ();
@@ -1276,9 +1321,6 @@ cgraph_optimize (void)
   if (errorcount == 0 && sorrycount == 0)
     ipa_passes ();

-  /* This pass remove bodies of extern inline functions we never inlined.
-     Do this later so other IPA passes see what is really going on.  */
-  cgraph_remove_unreachable_nodes (false, dump_file);
   cgraph_global_info_ready = true;
   if (cgraph_dump_file)
     {
@@ -1369,6 +1411,7 @@ cgraph_build_static_cdtor (char which, t
   resdecl = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
   DECL_ARTIFICIAL (resdecl) = 1;
   DECL_RESULT (decl) = resdecl;
+  DECL_CONTEXT (resdecl) = decl;

   allocate_struct_function (decl, false);

Index: testsuite/gcc.c-torture/execute/builtins/strlen-3.c
===================================================================
--- testsuite/gcc.c-torture/execute/builtins/strlen-3.c	(revision 146200)
+++ testsuite/gcc.c-torture/execute/builtins/strlen-3.c	(working copy)
@@ -10,7 +10,7 @@ extern char *strcpy (char *, const char
 static const char bar[] = "Hello, World!";
 static const char baz[] = "hello, world?";
 static const char larger[20] = "short string";
-extern volatile int inside_main;
+extern int inside_main;

 int l1 = 1;
 int x = 6;
Index: ada/gcc-interface/misc.c
===================================================================
--- ada/gcc-interface/misc.c	(revision 146200)
+++ ada/gcc-interface/misc.c	(working copy)
@@ -91,8 +91,6 @@ static const char *gnat_dwarf_name	(tree
 static tree gnat_return_tree		(tree);
 static int gnat_eh_type_covers		(tree, tree);
 static void gnat_parse_file		(int);
-static rtx gnat_expand_expr		(tree, rtx, enum machine_mode, int,
-					 rtx *);
 static void internal_error_function	(const char *, va_list *);
 static tree gnat_type_max_size		(const_tree);

@@ -124,8 +122,6 @@ static tree gnat_type_max_size		(const_t
 #define LANG_HOOKS_FINISH_INCOMPLETE_DECL gnat_finish_incomplete_decl
 #undef  LANG_HOOKS_GET_ALIAS_SET
 #define LANG_HOOKS_GET_ALIAS_SET	gnat_get_alias_set
-#undef  LANG_HOOKS_EXPAND_EXPR
-#define LANG_HOOKS_EXPAND_EXPR		gnat_expand_expr
 #undef  LANG_HOOKS_MARK_ADDRESSABLE
 #define LANG_HOOKS_MARK_ADDRESSABLE	gnat_mark_addressable
 #undef  LANG_HOOKS_PRINT_DECL
@@ -612,45 +608,6 @@ gnat_printable_name (tree decl, int verb
     return ada_name;
 }

-/* Expands GNAT-specific GCC tree nodes.  The only ones we support
-   here are  and NULL_EXPR.  */
-
-static rtx
-gnat_expand_expr (tree exp, rtx target, enum machine_mode tmode,
-		  int modifier, rtx *alt_rtl)
-{
-  tree type = TREE_TYPE (exp);
-  tree new;
-
-  /* Update EXP to be the new expression to expand.  */
-  switch (TREE_CODE (exp))
-    {
-#if 0
-    case ALLOCATE_EXPR:
-      return
-	allocate_dynamic_stack_space
-	  (expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, TYPE_MODE (sizetype),
-			EXPAND_NORMAL),
-	   NULL_RTX, tree_low_cst (TREE_OPERAND (exp, 1), 1));
-#endif
-
-    case UNCONSTRAINED_ARRAY_REF:
-      /* If we are evaluating just for side-effects, just evaluate our
-	 operand.  Otherwise, abort since this code should never appear
-	 in a tree to be evaluated (objects aren't unconstrained).  */
-      if (target == const0_rtx || TREE_CODE (type) == VOID_TYPE)
-	return expand_expr (TREE_OPERAND (exp, 0), const0_rtx,
-			    VOIDmode, modifier);
-
-      /* ... fall through ... */
-
-    default:
-      gcc_unreachable ();
-    }
-
-  return expand_expr_real (new, target, tmode, modifier, alt_rtl);
-}
-
 /* Do nothing (return the tree node passed).  */

 static tree
Index: ipa.c
===================================================================
--- ipa.c	(revision 146200)
+++ ipa.c	(working copy)
@@ -198,6 +198,11 @@ cgraph_remove_unreachable_nodes (bool be
 #ifdef ENABLE_CHECKING
   verify_cgraph ();
 #endif
+
+  /* Reclaim alias pairs for functions that have disappeared from the
+     call graph.  */
+  remove_unreachable_alias_pairs ();
+
   return changed;
 }

Index: tree-ssa-coalesce.c
===================================================================
--- tree-ssa-coalesce.c	(revision 146200)
+++ tree-ssa-coalesce.c	(working copy)
@@ -1351,7 +1351,8 @@ coalesce_ssa_name (void)
 	{
 	  tree a = ssa_name (i);

-	  if (a && SSA_NAME_VAR (a) && !DECL_ARTIFICIAL (SSA_NAME_VAR (a)))
+	  if (a && SSA_NAME_VAR (a) && !DECL_ARTIFICIAL (SSA_NAME_VAR (a))
+	      && map->partition_to_var[i] != NULL)
 	    {
 	      tree *slot = (tree *) htab_find_slot (ssa_name_hash, a, INSERT);

Index: tree-dfa.c
===================================================================
--- tree-dfa.c	(revision 146200)
+++ tree-dfa.c	(working copy)
@@ -88,26 +88,10 @@ find_referenced_vars (void)
   FOR_EACH_BB (bb)
     {
       for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
-	{
-	  size_t i;
-	  gimple stmt = gsi_stmt (si);
-	  for (i = 0; i < gimple_num_ops (stmt); i++)
-	    walk_tree (gimple_op_ptr (stmt, i), find_vars_r, NULL, NULL);
-	}
+	find_referenced_vars_in (gsi_stmt (si));

       for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
-	{
-	  gimple phi = gsi_stmt (si);
-	  size_t i, len = gimple_phi_num_args (phi);
-
-	  walk_tree (gimple_phi_result_ptr (phi), find_vars_r, NULL, NULL);
-
-	  for (i = 0; i < len; i++)
-	    {
-	      tree arg = gimple_phi_arg_def (phi, i);
-	      walk_tree (&arg, find_vars_r, NULL, NULL);
-	    }
-	}
+	find_referenced_vars_in (gsi_stmt (si));
     }

   return 0;
@@ -498,6 +482,33 @@ find_vars_r (tree *tp, int *walk_subtree
   return NULL_TREE;
 }

+/* Find referenced variables in STMT.  In contrast with
+   find_new_referenced_vars, this function will not mark newly found
+   variables for renaming.  */
+
+void
+find_referenced_vars_in (gimple stmt)
+{
+  size_t i;
+
+  if (gimple_code (stmt) != GIMPLE_PHI)
+    {
+      for (i = 0; i < gimple_num_ops (stmt); i++)
+	walk_tree (gimple_op_ptr (stmt, i), find_vars_r, NULL, NULL);
+    }
+  else
+    {
+      walk_tree (gimple_phi_result_ptr (stmt), find_vars_r, NULL, NULL);
+
+      for (i = 0; i < gimple_phi_num_args (stmt); i++)
+	{
+	  tree arg = gimple_phi_arg_def (stmt, i);
+	  walk_tree (&arg, find_vars_r, NULL, NULL);
+	}
+    }
+}
+
+
 /* Lookup UID in the referenced_vars hashtable and return the associated
    variable.  */

Index: except.c
===================================================================
--- except.c	(revision 146200)
+++ except.c	(working copy)
@@ -114,119 +114,15 @@ static int sjlj_fc_personality_ofs;
 static int sjlj_fc_lsda_ofs;
 static int sjlj_fc_jbuf_ofs;
 
-/* Describes one exception region.  */
-struct eh_region GTY(())
-{
-  /* The immediately surrounding region.  */
-  struct eh_region *outer;
-
-  /* The list of immediately contained regions.  */
-  struct eh_region *inner;
-  struct eh_region *next_peer;
-
-  /* An identifier for this region.  */
-  int region_number;
-
-  /* When a region is deleted, its parents inherit the REG_EH_REGION
-     numbers already assigned.  */
-  bitmap aka;
-
-  /* Each region does exactly one thing.  */
-  enum eh_region_type
-  {
-    ERT_UNKNOWN = 0,
-    ERT_CLEANUP,
-    ERT_TRY,
-    ERT_CATCH,
-    ERT_ALLOWED_EXCEPTIONS,
-    ERT_MUST_NOT_THROW,
-    ERT_THROW
-  } type;
-
-  /* Holds the action to perform based on the preceding type.  */
-  union eh_region_u {
-    /* A list of catch blocks, a surrounding try block,
-       and the label for continuing after a catch.  */
-    struct eh_region_u_try {
-      struct eh_region *eh_catch;
-      struct eh_region *last_catch;
-    } GTY ((tag ("ERT_TRY"))) eh_try;
-
-    /* The list through the catch handlers, the list of type objects
-       matched, and the list of associated filters.  */
-    struct eh_region_u_catch {
-      struct eh_region *next_catch;
-      struct eh_region *prev_catch;
-      tree type_list;
-      tree filter_list;
-    } GTY ((tag ("ERT_CATCH"))) eh_catch;
-
-    /* A tree_list of allowed types.  */
-    struct eh_region_u_allowed {
-      tree type_list;
-      int filter;
-    } GTY ((tag ("ERT_ALLOWED_EXCEPTIONS"))) allowed;
-
-    /* The type given by a call to "throw foo();", or discovered
-       for a throw.  */
-    struct eh_region_u_throw {
-      tree type;
-    } GTY ((tag ("ERT_THROW"))) eh_throw;
-
-    /* Retain the cleanup expression even after expansion so that
-       we can match up fixup regions.  */
-    struct eh_region_u_cleanup {
-      struct eh_region *prev_try;
-    } GTY ((tag ("ERT_CLEANUP"))) cleanup;
-  } GTY ((desc ("%0.type"))) u;
-
-  /* Entry point for this region's handler before landing pads are built.  */
-  rtx label;
-  tree tree_label;
-
-  /* Entry point for this region's handler from the runtime eh library.  */
-  rtx landing_pad;
-
-  /* Entry point for this region's handler from an inner region.  */
-  rtx post_landing_pad;
-
-  /* The RESX insn for handing off control to the next outermost handler,
-     if appropriate.  */
-  rtx resume;
-
-  /* True if something in this region may throw.  */
-  unsigned may_contain_throw : 1;
-};
-
-typedef struct eh_region *eh_region;

 struct call_site_record GTY(())
 {
   rtx landing_pad;
   int action;
 };
-
-DEF_VEC_P(eh_region);
-DEF_VEC_ALLOC_P(eh_region, gc);
-DEF_VEC_ALLOC_P(eh_region, heap);
-
-/* Used to save exception status for each function.  */
-struct eh_status GTY(())
-{
-  /* The tree of all regions for this function.  */
-  struct eh_region *region_tree;
-
-  /* The same information as an indexable array.  */
-  VEC(eh_region,gc) *region_array;
-  int last_region_number;
-
-  htab_t GTY((param_is (struct throw_stmt_node))) throw_stmt_table;
-};
 
 static int t2r_eq (const void *, const void *);
 static hashval_t t2r_hash (const void *);
-static void add_type_for_runtime (tree);
-static tree lookup_type_for_runtime (tree);

 static int ttypes_filter_eq (const void *, const void *);
 static hashval_t ttypes_filter_hash (const void *);
@@ -1308,7 +1204,7 @@ t2r_hash (const void *pentry)
   return TREE_HASH (TREE_PURPOSE (entry));
 }

-static void
+void
 add_type_for_runtime (tree type)
 {
   tree *slot;
@@ -1322,7 +1218,7 @@ add_type_for_runtime (tree type)
     }
 }

-static tree
+tree
 lookup_type_for_runtime (tree type)
 {
   tree *slot;
@@ -2479,8 +2375,33 @@ check_handled (tree handled, tree type)
   if (! lang_eh_type_covers)
     {
       for (t = handled; t ; t = TREE_CHAIN (t))
-	if (TREE_VALUE (t) == type)
-	  return 1;
+	{
+	  tree t1 = TREE_VALUE (t);
+	  tree t2 = type;
+
+	  /* If the types have been converted to runtime types (i.e.,
+	     when the IL is being read from disk in an LTO
+	     compilation), then T1 and T2 will be pointers to the
+	     runtime type of the form '(void *) &<runtime_type>' (See
+	     cp/except.c:build_eh_type_type).  Strip the conversion
+	     and the address.  */
+	  if (CONVERT_EXPR_P (t1))
+	    {
+	      STRIP_NOPS (t1);
+	      gcc_assert (TREE_CODE (t1) == ADDR_EXPR);
+	      t1 = TREE_OPERAND (t1, 0);
+	    }
+
+	  if (CONVERT_EXPR_P (t2))
+	    {
+	      STRIP_NOPS (t2);
+	      gcc_assert (TREE_CODE (t2) == ADDR_EXPR);
+	      t2 = TREE_OPERAND (t2, 0);
+	    }
+
+	  if (t1 == t2)
+	    return 1;
+	}
     }
   else
     {
@@ -3737,7 +3658,14 @@ output_ttype (tree type, int tt_format,
     {
       struct varpool_node *node;

-      type = lookup_type_for_runtime (type);
+      /* FIXME lto.  During LTO compiles, pass_ipa_free_lang_data
+	 changes all types to runtime types so TYPE should already be
+	 a runtime type reference.  When pass_ipa_free_lang data is
+	 made a default pass, we can then remove the call to
+	 lookup_type_for_runtime below.  */
+      if (TYPE_P (type))
+	type = lookup_type_for_runtime (type);
+
       value = expand_expr (type, NULL_RTX, VOIDmode, EXPAND_INITIALIZER);

       /* Let cgraph know that the rtti decl is used.  Not all of the
@@ -4092,6 +4020,15 @@ dump_eh_tree (FILE * out, struct functio
     }
 }

+/* Dump the EH tree for FN on stderr.  */
+
+void
+debug_eh_tree (struct function *fn)
+{
+  dump_eh_tree (stderr, fn);
+}
+
+
 /* Verify EH region invariants.  */

 static bool
Index: except.h
===================================================================
--- except.h	(revision 146200)
+++ except.h	(working copy)
@@ -24,12 +24,109 @@ along with GCC; see the file COPYING3.

 struct function;

-/* Per-function EH data.  Used only in except.c, but GC and others
-   manipulate pointers to the opaque type.  */
-struct eh_status;
+/* Describes one exception region.  */
+struct eh_region GTY(())
+{
+  /* The immediately surrounding region.  */
+  struct eh_region *outer;
+
+  /* The list of immediately contained regions.  */
+  struct eh_region *inner;
+  struct eh_region *next_peer;
+
+  /* An identifier for this region.  */
+  int region_number;
+
+  /* When a region is deleted, its parents inherit the REG_EH_REGION
+     numbers already assigned.  */
+  bitmap aka;
+
+  /* Each region does exactly one thing.  */
+  enum eh_region_type
+  {
+    ERT_UNKNOWN = 0,
+    ERT_CLEANUP,
+    ERT_TRY,
+    ERT_CATCH,
+    ERT_ALLOWED_EXCEPTIONS,
+    ERT_MUST_NOT_THROW,
+    ERT_THROW
+  } type;
+
+  /* Holds the action to perform based on the preceding type.  */
+  union eh_region_u {
+    /* A list of catch blocks, a surrounding try block,
+       and the label for continuing after a catch.  */
+    struct eh_region_u_try {
+      struct eh_region *eh_catch;
+      struct eh_region *last_catch;
+    } GTY ((tag ("ERT_TRY"))) eh_try;
+
+    /* The list through the catch handlers, the list of type objects
+       matched, and the list of associated filters.  */
+    struct eh_region_u_catch {
+      struct eh_region *next_catch;
+      struct eh_region *prev_catch;
+      tree type_list;
+      tree filter_list;
+    } GTY ((tag ("ERT_CATCH"))) eh_catch;
+
+    /* A tree_list of allowed types.  */
+    struct eh_region_u_allowed {
+      tree type_list;
+      int filter;
+    } GTY ((tag ("ERT_ALLOWED_EXCEPTIONS"))) allowed;
+
+    /* The type given by a call to "throw foo();", or discovered
+       for a throw.  */
+    struct eh_region_u_throw {
+      tree type;
+    } GTY ((tag ("ERT_THROW"))) eh_throw;
+
+    /* Retain the cleanup expression even after expansion so that
+       we can match up fixup regions.  */
+    struct eh_region_u_cleanup {
+      struct eh_region *prev_try;
+    } GTY ((tag ("ERT_CLEANUP"))) cleanup;
+  } GTY ((desc ("%0.type"))) u;
+
+  /* Entry point for this region's handler before landing pads are built.  */
+  rtx label;
+  tree tree_label;
+
+  /* Entry point for this region's handler from the runtime eh library.  */
+  rtx landing_pad;
+
+  /* Entry point for this region's handler from an inner region.  */
+  rtx post_landing_pad;
+
+  /* The RESX insn for handing off control to the next outermost handler,
+     if appropriate.  */
+  rtx resume;
+
+  /* True if something in this region may throw.  */
+  unsigned may_contain_throw : 1;
+};
+
+typedef struct eh_region *eh_region;
+DEF_VEC_P(eh_region);
+DEF_VEC_ALLOC_P(eh_region, gc);
+DEF_VEC_ALLOC_P(eh_region, heap);
+
+/* Per-function EH data.  Used to save exception status for each
+   function.  */
+struct eh_status GTY(())
+{
+  /* The tree of all regions for this function.  */
+  struct eh_region *region_tree;
+
+  /* The same information as an indexable array.  */
+  VEC(eh_region,gc) *region_array;
+  int last_region_number;
+
+  htab_t GTY((param_is (struct throw_stmt_node))) throw_stmt_table;
+};

-/* Internal structure describing a region.  */
-struct eh_region;

 /* Test: is exception handling turned on?  */
 extern int doing_eh (int);
@@ -108,8 +205,11 @@ extern void collect_eh_region_array (voi
 extern void expand_resx_expr (tree);
 extern void verify_eh_tree (struct function *);
 extern void dump_eh_tree (FILE *, struct function *);
+void debug_eh_tree (struct function *);
 extern bool eh_region_outer_p (struct function *, int, int);
 extern int eh_region_outermost (struct function *, int, int);
+extern void add_type_for_runtime (tree);
+extern tree lookup_type_for_runtime (tree);

 /* If non-NULL, this is a function that returns an expression to be
    executed if an unhandled exception is propagated out of a cleanup
Index: tree-ssa-pre.c
===================================================================
--- tree-ssa-pre.c	(revision 146200)
+++ tree-ssa-pre.c	(working copy)
@@ -3003,6 +3003,7 @@ create_expression_by_pieces (basic_block
 	      add_to_value (VN_INFO (forcedname)->value_id, nameexpr);
 	      if (!in_fre)
 		bitmap_value_replace_in_set (NEW_SETS (block), nameexpr);
+	      gcc_assert (AVAIL_OUT (block));
 	      bitmap_value_replace_in_set (AVAIL_OUT (block), nameexpr);
 	    }
 	  mark_symbols_for_renaming (stmt);
Index: varasm.c
===================================================================
--- varasm.c	(revision 146200)
+++ varasm.c	(working copy)
@@ -5176,21 +5176,7 @@ globalize_decl (tree decl)
   targetm.asm_out.globalize_decl_name (asm_out_file, decl);
 }

-/* We have to be able to tell cgraph about the needed-ness of the target
-   of an alias.  This requires that the decl have been defined.  Aliases
-   that precede their definition have to be queued for later processing.  */
-
-typedef struct alias_pair GTY(())
-{
-  tree decl;
-  tree target;
-} alias_pair;
-
-/* Define gc'd vector type.  */
-DEF_VEC_O(alias_pair);
-DEF_VEC_ALLOC_O(alias_pair,gc);
-
-static GTY(()) VEC(alias_pair,gc) *alias_pairs;
+VEC(alias_pair,gc) *alias_pairs;

 /* Given an assembly name, find the decl it is associated with.  At the
    same time, mark it needed for cgraph.  */
@@ -5333,6 +5319,39 @@ do_assemble_alias (tree decl, tree targe
 #endif
 }

+
+/* Remove the alias pairing for functions that are no longer in the call
+   graph.  */
+
+void
+remove_unreachable_alias_pairs (void)
+{
+  unsigned i;
+  alias_pair *p;
+
+  if (alias_pairs == NULL)
+    return;
+
+  for (i = 0; VEC_iterate (alias_pair, alias_pairs, i, p); )
+    {
+      if (!DECL_EXTERNAL (p->decl))
+	{
+	  struct cgraph_node *fnode = NULL;
+	  struct varpool_node *vnode = NULL;
+	  fnode = cgraph_node_for_asm (p->target);
+	  vnode = (fnode == NULL) ? varpool_node_for_asm (p->target) : NULL;
+	  if (fnode == NULL && vnode == NULL)
+	    {
+	      VEC_unordered_remove (alias_pair, alias_pairs, i);
+	      continue;
+	    }
+	}
+
+      i++;
+    }
+}
+
+
 /* First pass of completing pending aliases.  Make sure that cgraph knows
    which symbols will be required.  */

Index: tree-flow.h
===================================================================
--- tree-flow.h	(revision 146200)
+++ tree-flow.h	(working copy)
@@ -616,6 +616,7 @@ extern tree gimple_default_def (struct f
 extern bool stmt_references_abnormal_ssa_name (gimple);
 extern tree get_ref_base_and_extent (tree, HOST_WIDE_INT *,
 				     HOST_WIDE_INT *, HOST_WIDE_INT *);
+extern void find_referenced_vars_in (gimple);

 /* In tree-phinodes.c  */
 extern void reserve_phi_args_for_new_edge (basic_block);
Index: main.c
===================================================================
--- main.c	(revision 146200)
+++ main.c	(working copy)
@@ -32,5 +32,5 @@ int main (int argc, char **argv);
 int
 main (int argc, char **argv)
 {
-  return toplev_main (argc, (const char **) argv);
+  return toplev_main (argc, argv);
 }
Index: Makefile.in
===================================================================
--- Makefile.in	(revision 146200)
+++ Makefile.in	(working copy)
@@ -829,7 +829,7 @@ CFGLOOP_H = cfgloop.h $(BASIC_BLOCK_H) $
 IPA_UTILS_H = ipa-utils.h $(TREE_H) $(CGRAPH_H)
 IPA_REFERENCE_H = ipa-reference.h $(BITMAP_H) $(TREE_H)
 IPA_TYPE_ESCAPE_H = ipa-type-escape.h $(TREE_H)
-CGRAPH_H = cgraph.h $(TREE_H) $(BASIC_BLOCK_H)
+CGRAPH_H = cgraph.h $(TREE_H) $(BASIC_BLOCK_H) cif-code.def
 DF_H = df.h $(BITMAP_H) $(BASIC_BLOCK_H) alloc-pool.h
 RESOURCE_H = resource.h hard-reg-set.h $(DF_H)
 DDG_H = ddg.h sbitmap.h $(DF_H)
@@ -2056,7 +2056,8 @@ tree.o : tree.c $(CONFIG_H) $(SYSTEM_H)
    all-tree.def $(FLAGS_H) $(FUNCTION_H) $(PARAMS_H) \
    $(TOPLEV_H) $(GGC_H) $(HASHTAB_H) $(TARGET_H) output.h $(TM_P_H)
langhooks.h \
    $(REAL_H) gt-tree.h tree-iterator.h $(BASIC_BLOCK_H) $(TREE_FLOW_H) \
-   $(OBSTACK_H) pointer-set.h fixed-value.h
+   $(OBSTACK_H) pointer-set.h fixed-value.h tree-pass.h langhooks-def.h \
+   $(DIAGNOSTIC_H) $(CGRAPH_H) $(TIMEVAR_H) except.h
 tree-dump.o: tree-dump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    $(TREE_H) langhooks.h $(TOPLEV_H) $(SPLAY_TREE_H) $(TREE_DUMP_H) \
    tree-iterator.h tree-pass.h $(DIAGNOSTIC_H) $(REAL_H) fixed-value.h
@@ -2391,11 +2392,11 @@ tree-loop-distribution.o: tree-loop-dist
    $(TM_H) $(GGC_H) $(OPTABS_H) $(TREE_H) $(RTL_H) $(BASIC_BLOCK_H) \
    $(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) \
    tree-pass.h $(TREE_DATA_REF_H) $(SCEV_H) $(EXPR_H) \
-   $(TARGET_H) tree-chrec.h langhooks.h tree-vectorizer.h
+   $(TARGET_H) tree-chrec.h langhooks.h $(TREE_VECTORIZER_H)
 tree-parloops.o: tree-parloops.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    $(TREE_FLOW_H) $(TREE_H) $(RTL_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) $(GGC_H) \
    $(DIAGNOSTIC_H) tree-pass.h $(SCEV_H) langhooks.h gt-tree-parloops.h \
-   tree-vectorizer.h
+   $(TREE_VECTORIZER_H)
 tree-stdarg.o: tree-stdarg.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    $(TREE_H) $(FUNCTION_H) $(DIAGNOSTIC_H) $(TREE_FLOW_H) tree-pass.h \
    tree-stdarg.h $(TARGET_H) langhooks.h
@@ -2404,7 +2405,7 @@ tree-object-size.o: tree-object-size.c $
    tree-ssa-propagate.h
 gimple.o : gimple.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \
    $(GGC_H) $(GIMPLE_H) $(GIMPLE_H) $(DIAGNOSTIC_H) gt-gimple.h \
-   $(TREE_FLOW_H) value-prof.h $(FLAGS_H)
+   $(TREE_FLOW_H) value-prof.h $(FLAGS_H) $(TARGET_H)
 gimple-pretty-print.o : gimple-pretty-print.c $(CONFIG_H) $(SYSTEM_H) \
    $(TREE_H) $(DIAGNOSTIC_H) $(REAL_H) $(HASHTAB_H) $(TREE_FLOW_H) \
    $(TM_H) coretypes.h tree-pass.h $(GIMPLE_H) value-prof.h
@@ -2594,22 +2595,23 @@ simplify-rtx.o : simplify-rtx.c $(CONFIG
 cgraph.o : cgraph.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
    langhooks.h $(TOPLEV_H) $(FLAGS_H) $(GGC_H) $(TARGET_H) $(CGRAPH_H) \
    gt-cgraph.h output.h intl.h $(BASIC_BLOCK_H) debug.h $(HASHTAB_H) \
-   $(TREE_INLINE_H) $(VARRAY_H) $(TREE_DUMP_H) $(TREE_FLOW_H) value-prof.h
+   $(TREE_INLINE_H) $(VARRAY_H) $(TREE_DUMP_H) $(TREE_FLOW_H) cif-code.def \
+   value-prof.h
 cgraphunit.o : cgraphunit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    $(TREE_H) langhooks.h $(TREE_INLINE_H) $(TOPLEV_H) $(FLAGS_H) $(GGC_H) \
    $(TARGET_H) $(CGRAPH_H) intl.h pointer-set.h $(FUNCTION_H) $(GIMPLE_H) \
    $(TREE_FLOW_H) tree-pass.h $(C_COMMON_H) debug.h $(DIAGNOSTIC_H) \
    $(FIBHEAP_H) output.h $(PARAMS_H) $(RTL_H) $(TIMEVAR_H) $(IPA_PROP_H) \
-   gt-cgraphunit.h tree-iterator.h
+   gt-cgraphunit.h tree-iterator.h $(COVERAGE_H)
 cgraphbuild.o : cgraphbuild.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    $(TREE_H) langhooks.h $(CGRAPH_H) intl.h pointer-set.h $(GIMPLE_H) \
    $(TREE_FLOW_H) tree-pass.h
 varpool.o : varpool.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    $(TREE_H) $(CGRAPH_H) langhooks.h $(DIAGNOSTIC_H) $(HASHTAB_H) \
    $(GGC_H) $(TIMEVAR_H) debug.h $(TARGET_H) output.h $(GIMPLE_H) \
-   $(TREE_FLOW_H) gt-varpool.h
+   $(TREE_FLOW_H) gt-varpool.h $(FLAGS_H)
 ipa.o : ipa.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(CGRAPH_H) \
-   tree-pass.h $(TIMEVAR_H)
+   tree-pass.h $(TIMEVAR_H) $(FLAGS_H)
 ipa-prop.o : ipa-prop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
    langhooks.h $(GGC_H) $(TARGET_H) $(CGRAPH_H) $(IPA_PROP_H) $(DIAGNOSTIC_H) \
    $(TREE_FLOW_H) $(TM_H) tree-pass.h $(FLAGS_H) $(TREE_H) $(TREE_INLINE_H) \
@@ -3290,9 +3292,9 @@ GTFILES = $(CPP_ID_DATA_H) $(srcdir)/inp
   $(srcdir)/dbxout.c $(srcdir)/ipa-struct-reorg.c
$(srcdir)/dwarf2out.c $(srcdir)/dwarf2asm.c \
   $(srcdir)/tree-vect-generic.c \
   $(srcdir)/dojump.c \
-  $(srcdir)/emit-rtl.c $(srcdir)/except.c $(srcdir)/explow.c $(srcdir)/expr.c \
+  $(srcdir)/emit-rtl.c $(srcdir)/except.h $(srcdir)/explow.c $(srcdir)/expr.c \
   $(srcdir)/expr.h \
-  $(srcdir)/function.c $(srcdir)/except.h \
+  $(srcdir)/function.c $(srcdir)/except.c \
   $(srcdir)/gcse.c $(srcdir)/integrate.c $(srcdir)/lists.c $(srcdir)/optabs.c \
   $(srcdir)/profile.c $(srcdir)/reginfo.c $(srcdir)/mcf.c \
   $(srcdir)/reg-stack.c $(srcdir)/cfglayout.c $(srcdir)/cfglayout.h \


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]