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]

[LTO] patch committed to get SSA properly started and other bugs.


This patch gets the compiler on the receiving end mostly started up
properly.  A lot of work has been done to get ssa form properly
started.  The current code may be overkill, but that is not important now. 

The current code exposes one known bug, that dannyb is looking into:
================
extern int foo (int);

int foo (int a)
{
  return a * 6;
}
=================

This program seems to serialize fine, but blows up in the expander
trying to expand the parm_decl.  It is possible that this is caused by
me failing to serialize something, or i could be just not initializing
something properly.

I have run a couple of other small examples thru.
================
extern int foo (void);

int foo (void)
{
  int a,b = 2;
  for (a = 0; a < 10; a++)
    b = 6 * a;
  return b * 6;
}
=================
now works fine.  I am starting to work on larger programs.

Mark claims that everything on his end should work except for static
initializers so we may be ready for some larger scale testing as soon as
the above bug is tracked down.

Committed as revision 127125.

Kenny

2007-07-31  Kenneth Zadeck <zadeck@naturalbridge.com>

    * tree-into-ssa.c (rebuild_ssa_for_lto): New function.
    (pass_rebuild_ssa_for_lto): New pass.
    * cgraph_build.c (tree_opt_pass pass_rebuild_cgraph): Added some
dumping.
    * lto-tree-flags.def (tcc_declaration): Added used_flag to
serialized list.
    (SSA_NAME): Added nothrow_flag and volatile_flag to serialized list.
    * tree-pass.h (pass_early_lto_passes, pass_rebuild_ssa_for_lto): New
passes.
    * lto-function-out.c (output_tree_flags): Added code to properly
    control writing of flags. Also added new parameter to pass in the
    tree code.
    (output_record_start, output_local_vars): Added param to
    output_tree_flags.
    (output_tree_list, output_eh_cleanup, output_eh_try,
    output_eh_catch, output_eh_allowed, output_eh_must_not_throw,
    output_eh_regions): Added missing debugging undent.
    (output_expr_operand): Added assert that there was no rtl and code
    to properly handle COND_EXPR.  Fixed the outputing of types and
    flags for many tree codes.
    (output_phi): Fixed the outputing of types and flags.  Generalized
    to handle parameters to phi that are not SSA_NAMES.
    (output_bb, LTO_SET_DEBUGGING_STREAM): Added assert to check for
    proper debug stream usage.
    (lto_static_init): Changed the outputting of flags and types for
    various tree codes.
    (pass_ipa_lto_out): Added dumping.
    * ipa-inline.c (pass_inline_parameters): Added dumping.
    * lto-tree-tags.def (COND_EXPR): Changed processing options.
    * lto-tags.h: Changed define into enum.
    * ipa.c (gate_ipa_fun_and_var_visibility): Always execute this
    pass.
    * tree.def (COND_EXEC): Properly documented this code.
    * tree-dfa.c (find_referenced_vars): Added code to walk phi
    functions.
    (pass_referenced_vars): Added name and dump flag.
    (find_vars_r): Now handles SSA_NAMES.
    * tree-optimize.c (gate_early_lto_passes): New function.
    (pass_early_lto_passes): New pass.
    * passes.c (pass_early_lto_passes): New pass.
    (dump_properties, debug_properties): New debugging function.
    * tree-ssanames.c (pass_release_ssa_names): Added dumping.


2007-07-31  Kenneth Zadeck <zadeck@naturalbridge.com>

    * lto-read.c (input_expr_operand): Fixed code for COND_EXEC,
    RETURN_EXPR, MODIFY_EXPR and processing of flags.
    (input_phi): Made work with operands other than SSA_NAMES and
    fixed processing of flags.
    (input_ssa_names): Initialize SSA_NAME_DEF_STMT to empty stmt.
    (input_flags): New function.
    * lto-lang.c (lto_init): Changed state of in_lto_p.
   

Index: tree-into-ssa.c
===================================================================
--- tree-into-ssa.c	(revision 127112)
+++ tree-into-ssa.c	(working copy)
@@ -3362,3 +3362,51 @@ done:
 
   timevar_pop (TV_TREE_SSA_INCREMENTAL);
 }
+
+
+static unsigned int
+rebuild_ssa_for_lto (void)
+{
+  block_stmt_iterator bsi;
+  basic_block bb;
+  referenced_var_iterator rvi;
+  tree var;
+
+  init_ssa_operands ();
+  FOR_EACH_BB (bb)
+    for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+      update_stmt_if_modified (bsi_stmt (bsi));
+
+  FOR_EACH_REFERENCED_VAR (var, rvi)
+    {
+      if (dump_file)
+	print_node (dump_file, "\nmarking symbol for renaming ", var, 0);
+      mark_sym_for_renaming (var);
+    }
+
+  update_ssa (TODO_update_ssa);
+  return 1;
+
+}
+
+
+struct tree_opt_pass pass_rebuild_ssa_for_lto = 
+{
+  "rebuild_ssa",			/* name */
+  NULL,					/* gate */
+  rebuild_ssa_for_lto,			/* execute */
+  NULL,					/* sub */
+  NULL,					/* next */
+  0,					/* static_pass_number */
+  0,					/* tv_id */
+  PROP_cfg | PROP_referenced_vars,	/* properties_required */
+  PROP_ssa,				/* properties_provided */
+  0,					/* properties_destroyed */
+  0,					/* todo_flags_start */
+  TODO_dump_func
+    | TODO_verify_ssa
+    | TODO_remove_unused_locals,	/* todo_flags_finish */
+  0					/* letter */
+};
+
+
Index: cgraphbuild.c
===================================================================
--- cgraphbuild.c	(revision 127112)
+++ cgraphbuild.c	(working copy)
@@ -252,6 +252,6 @@ struct tree_opt_pass pass_rebuild_cgraph
   0,					/* properties_provided */
   0,					/* properties_destroyed */
   0,					/* todo_flags_start */
-  0,					/* todo_flags_finish */
+  TODO_dump_func,			/* todo_flags_finish */
   0					/* letter */
 };
Index: lto-tree-flags.def
===================================================================
--- lto-tree-flags.def	(revision 127112)
+++ lto-tree-flags.def	(working copy)
@@ -66,6 +66,7 @@
       ADD_CLASS_FLAG (constant_flag)
       ADD_CLASS_FLAG (unsigned_flag)
       ADD_CLASS_FLAG (deprecated_flag)
+      ADD_CLASS_FLAG (used_flag)
     END_CLASS_CASE (tcc_declaration)
 
     START_CLASS_CASE (tcc_exceptional)
@@ -608,6 +609,8 @@
       
     START_EXPR_CASE (SSA_NAME)
       ADD_EXPR_FLAG (asm_written_flag)
+      ADD_EXPR_FLAG (nothrow_flag)
+      ADD_EXPR_FLAG (volatile_flag)
     END_EXPR_CASE (SSA_NAME)
       
     START_EXPR_CASE (STATEMENT_LIST)
Index: tree-pass.h
===================================================================
--- tree-pass.h	(revision 127112)
+++ tree-pass.h	(working copy)
@@ -342,6 +342,9 @@ extern struct tree_opt_pass pass_free_da
 extern struct tree_opt_pass pass_init_datastructures;
 extern struct tree_opt_pass pass_fixup_cfg;
 
+extern struct tree_opt_pass pass_early_lto_passes;
+extern struct tree_opt_pass pass_rebuild_ssa_for_lto;
+
 extern struct tree_opt_pass pass_init_function;
 extern struct tree_opt_pass pass_jump;
 extern struct tree_opt_pass pass_rtl_eh;
Index: lto-function-out.c
===================================================================
--- lto-function-out.c	(revision 127112)
+++ lto-function-out.c	(working copy)
@@ -594,14 +594,16 @@ output_decl_index (struct output_stream 
 
 
 static void
-output_tree_flags (struct output_block *ob, tree expr)
+output_tree_flags (struct output_block *ob, enum tree_code code, tree expr)
 {
   int flags = 0;
   const char *file_to_write = NULL;
   int line_to_write = -1;
   const char *current_file;
 
-  LTO_DEBUG_TOKEN ("flags")
+  if (code == 0 || TEST_BIT (lto_flags_needed_for, code))
+    {
+      LTO_DEBUG_TOKEN ("flags")
 
 #define START_CLASS_SWITCH()              \
   {                                       \
@@ -650,43 +652,44 @@ output_tree_flags (struct output_block *
 #undef END_EXPR_CASE
 #undef END_EXPR_SWITCH
 
-  /* Add two more bits onto the flag if this is a tree node that can
-     have a line number.  The first bit is true if this node changes
-     files and the second is set if this node changes lines.  */
-  if (expr && EXPR_P (expr))
-    {
-      flags <<= 2;
-      if (EXPR_HAS_LOCATION (expr))
-	{
-	  LOC current_loc = EXPR_LOC (expr);
-	  const int current_line = LOC_LINE (current_loc);
-	  current_file = LOC_FILE (current_loc);
-	  if (ob->last_file != current_file)
+      /* Add two more bits onto the flag if this is a tree node that can
+	 have a line number.  The first bit is true if this node changes
+	 files and the second is set if this node changes lines.  */
+      if (expr && EXPR_P (expr))
+        {
+	  flags <<= 2;
+	  if (EXPR_HAS_LOCATION (expr))
 	    {
-	      file_to_write = current_file;
-	      ob->last_file = current_file;
-	      flags |= 0x2;
-	    }
-	  if (ob->last_line != current_line)
-	    {
-	      line_to_write = current_line;
-	      ob->last_line = current_line;
-	      flags |= 0x1;
+	      LOC current_loc = EXPR_LOC (expr);
+	      const int current_line = LOC_LINE (current_loc);
+	      current_file = LOC_FILE (current_loc);
+	      if (ob->last_file != current_file)
+		{
+		  file_to_write = current_file;
+		  ob->last_file = current_file;
+		  flags |= 0x2;
+		}
+	      if (ob->last_line != current_line)
+		{
+		  line_to_write = current_line;
+		  ob->last_line = current_line;
+		  flags |= 0x1;
+		}
 	    }
 	}
-    }
 
-  output_uleb128 (ob, flags);
-  if (file_to_write)
-    {
-      LTO_DEBUG_TOKEN ("file")
-      output_string (ob, ob->main_stream, 
-		     file_to_write, strlen (file_to_write));
-    }
-  if (line_to_write != -1)
-    {
-      LTO_DEBUG_TOKEN ("line")
-      output_uleb128 (ob, line_to_write);
+      output_uleb128 (ob, flags);
+      if (file_to_write)
+	{
+	  LTO_DEBUG_TOKEN ("file")
+	    output_string (ob, ob->main_stream, 
+			   file_to_write, strlen (file_to_write));
+	}
+      if (line_to_write != -1)
+	{
+	  LTO_DEBUG_TOKEN ("line")
+	    output_uleb128 (ob, line_to_write);
+	}
     }
 }
 
@@ -773,7 +776,7 @@ output_record_start (struct output_block
       enum tree_code code = TREE_CODE (expr);
       if (value && TEST_BIT (lto_types_needed_for, code))
 	output_type_ref (ob, TREE_TYPE (value));
-      output_tree_flags (ob, expr);
+      output_tree_flags (ob, code, expr);
     }
 }
 
@@ -821,6 +824,7 @@ output_tree_list (struct output_block *o
       for (tl = list; tl; tl = TREE_CHAIN (tl))
 	if (TREE_VALUE (tl) != NULL_TREE)
 	  output_expr_operand (ob, TREE_VALUE (tl));
+      LTO_DEBUG_UNDENT ()
     }
   else
     output_zero (ob);
@@ -846,6 +850,7 @@ output_eh_cleanup (void *obv,
   output_sleb128 (ob, prev_try);
   if (!has_peer)
     output_zero (ob);
+  LTO_DEBUG_UNDENT ()
 }
 
 
@@ -870,6 +875,7 @@ output_eh_try (void *obv,
   output_sleb128 (ob, last_catch);
   if (!has_peer)
     output_zero (ob);
+  LTO_DEBUG_UNDENT ()
 }
 
 
@@ -895,6 +901,7 @@ output_eh_catch (void *obv,
   output_type_list (ob, type_list);
   if (!has_peer)
     output_zero (ob);
+  LTO_DEBUG_UNDENT ()
 }
 
 /* Output an eh_allowed_exceptions region with REGION_NUMBER.
@@ -916,6 +923,7 @@ output_eh_allowed (void *obv,
   output_type_list (ob, type_list);
   if (!has_peer)
     output_zero (ob);
+  LTO_DEBUG_UNDENT ()
 }
 
 
@@ -937,6 +945,7 @@ output_eh_must_not_throw (void *obv,
   output_sleb128 (ob, region_number);
   if (!has_peer)
     output_zero (ob);
+  LTO_DEBUG_UNDENT ()
 }
 
 
@@ -954,6 +963,7 @@ output_eh_regions (struct output_block *
 			 output_eh_catch,
 			 output_eh_allowed,
 			 output_eh_must_not_throw);
+      LTO_DEBUG_UNDENT ()
     }
   /* The 0 either terminates the record or indicates that there are no
      eh_records at all.  */
@@ -1164,6 +1174,7 @@ output_expr_operand (struct output_block
       break;
 
     case PARM_DECL:
+      gcc_assert (!DECL_RTL_SET_P (expr));
       output_record_start (ob, NULL, NULL, tag);
       output_local_decl_ref (ob, expr);
       break;
@@ -1178,8 +1189,23 @@ output_expr_operand (struct output_block
       output_label_ref (ob, TREE_OPERAND (expr, 0));
       break;
 
+    case COND_EXPR:
+      if (TREE_OPERAND (expr, 1))
+	{
+	  output_record_start (ob, expr, expr, LTO_cond_expr0);
+	  output_expr_operand (ob, TREE_OPERAND (expr, 0));
+	  output_expr_operand (ob, TREE_OPERAND (expr, 1));
+	  output_expr_operand (ob, TREE_OPERAND (expr, 2));
+	}
+      else 
+	{
+	  output_record_start (ob, expr, expr, LTO_cond_expr1);
+	  output_expr_operand (ob, TREE_OPERAND (expr, 0));
+	}
+      break;
+
     case RESULT_DECL:
-      output_record_start (ob, expr, NULL, tag);
+      output_record_start (ob, expr, expr, tag);
       break;
 
     case COMPONENT_REF:
@@ -1300,13 +1326,13 @@ output_expr_operand (struct output_block
 	if (t == NULL)
 	  {
 	    /* Form return.  */
-	    output_record_start (ob, expr, NULL,
+	    output_record_start (ob, expr, expr,
 				 LTO_return_expr0);
 	  }
 	else if (TREE_CODE (t) == MODIFY_EXPR)
 	  {
 	    /* Form return a = b;  */
-	    output_record_start (ob, expr, NULL,
+	    output_record_start (ob, expr, expr,
 				 LTO_return_expr2);
 	    output_expr_operand (ob, TREE_OPERAND (t, 0));
 	    output_expr_operand (ob, TREE_OPERAND (t, 1));
@@ -1314,7 +1340,7 @@ output_expr_operand (struct output_block
 	else
 	  {
 	    /* Form return a; */
-	    output_record_start (ob, expr, NULL,
+	    output_record_start (ob, expr, expr,
 				 LTO_return_expr1);
 	    output_expr_operand (ob, t);
 	  }
@@ -1355,7 +1381,7 @@ output_expr_operand (struct output_block
 #undef TREE_SINGLE_MECHANICAL_TRUE
 #undef SET_NAME
 	output_record_start (ob, expr, expr, tag);
-	for (i = 0; i< TREE_CODE_LENGTH (TREE_CODE (expr)); i++)
+	for (i = 0; i < TREE_CODE_LENGTH (TREE_CODE (expr)); i++)
 	  output_expr_operand (ob, TREE_OPERAND (expr, i));
 	break;
       }
@@ -1454,7 +1480,7 @@ output_local_vars (struct output_block *
       if (!is_var)
 	output_type_ref (ob, DECL_ARG_TYPE (decl));
       
-      output_tree_flags (ob, decl);
+      output_tree_flags (ob, 0, decl);
       LTO_DEBUG_TOKEN ("align")
       output_uleb128 (ob, DECL_ALIGN (decl));
 
@@ -1523,6 +1549,8 @@ output_ssa_names (struct output_block *o
 
       output_uleb128 (ob, i);
       output_expr_operand (ob, SSA_NAME_VAR (ptr));
+      /* Lie about the type of object to get the flags out.  */
+      output_tree_flags (ob, 0, ptr);
     }
 
   output_uleb128 (ob, 0);
@@ -1578,14 +1606,15 @@ output_phi (struct output_block *ob, tre
   int len = PHI_NUM_ARGS (expr);
   int i;
   
-  output_record_start (ob, expr, NULL, LTO_phi_node);
+  output_record_start (ob, expr, expr, LTO_phi_node);
   output_uleb128 (ob, SSA_NAME_VERSION (PHI_RESULT (expr)));
   
   for (i = 0; i < len; i++)
     {
-      output_uleb128 (ob, SSA_NAME_VERSION (PHI_ARG_DEF (expr, i)));
+      output_expr_operand (ob, PHI_ARG_DEF (expr, i));
       output_uleb128 (ob, PHI_ARG_EDGE (expr, i)->src->index);
     }
+  LTO_DEBUG_UNDENT ()
 }
 
 
@@ -1649,6 +1678,10 @@ output_bb (struct output_block *ob, basi
     }
 
   LTO_DEBUG_UNDENT()
+
+#ifdef LTO_STREAM_DEBUGGING
+  gcc_assert (lto_debug_context.indent == 1);
+#endif
 }
 
 
@@ -1788,10 +1821,11 @@ lto_static_init (void)
   lto_flags_needed_for = sbitmap_alloc (NUM_TREE_CODES);
   sbitmap_ones (lto_flags_needed_for);
   RESET_BIT (lto_flags_needed_for, FIELD_DECL);
+  RESET_BIT (lto_flags_needed_for, FIELD_DECL);
   RESET_BIT (lto_flags_needed_for, FUNCTION_DECL);
-  RESET_BIT (lto_flags_needed_for, VAR_DECL);
   RESET_BIT (lto_flags_needed_for, PARM_DECL);
-  RESET_BIT (lto_flags_needed_for, FIELD_DECL);
+  RESET_BIT (lto_flags_needed_for, SSA_NAME);
+  RESET_BIT (lto_flags_needed_for, VAR_DECL);
 
   lto_types_needed_for = sbitmap_alloc (NUM_TREE_CODES);
 
@@ -1805,9 +1839,9 @@ lto_static_init (void)
   RESET_BIT (lto_types_needed_for, LABEL_EXPR);
   RESET_BIT (lto_types_needed_for, MODIFY_EXPR);
   RESET_BIT (lto_types_needed_for, PARM_DECL);
-  RESET_BIT (lto_types_needed_for, RESULT_DECL);
+  RESET_BIT (lto_types_needed_for, PHI_NODE);
   RESET_BIT (lto_types_needed_for, RESX_EXPR);
-  RESET_BIT (lto_types_needed_for, RETURN_EXPR);
+  RESET_BIT (lto_types_needed_for, SSA_NAME);
   RESET_BIT (lto_types_needed_for, STRING_CST);
   RESET_BIT (lto_types_needed_for, SWITCH_EXPR);
   RESET_BIT (lto_types_needed_for, VAR_DECL);
@@ -1868,6 +1902,7 @@ static int function_num;
   ob-> STREAM = xcalloc (1, sizeof (struct output_stream)); \
   lto_debug_context. CONTEXT = ob-> STREAM; \
   lto_debug_context.current_data = ob-> STREAM; \
+  gcc_assert (lto_debug_context.indent == 0);  \
 }
 #else
 #define LTO_SET_DEBUGGING_STREAM(STREAM,CONTEXT)
@@ -2015,7 +2050,7 @@ struct tree_opt_pass pass_ipa_lto_out =
   0,	                                /* properties_required */
   0,					/* properties_provided */
   0,					/* properties_destroyed */
-  0,					/* todo_flags_start */
+  TODO_dump_func,			/* todo_flags_start */
   0,                                    /* todo_flags_finish */
   0					/* letter */
 };
Index: cgraphunit.c
===================================================================
--- cgraphunit.c	(revision 127112)
+++ cgraphunit.c	(working copy)
@@ -529,7 +529,7 @@ cgraph_finalize_function (tree decl, boo
   if (node->lowered)
     {
       DECL_STRUCT_FUNCTION (decl)->curr_properties
-	|= (PROP_gimple_leh | PROP_cfg | PROP_referenced_vars
+	|= (PROP_gimple_leh | PROP_cfg | PROP_referenced_vars 
 	    | PROP_gimple_lomp | PROP_gimple_any | PROP_gimple_lcf);
     }
   record_cdtor_fn (node->decl);
Index: ipa-inline.c
===================================================================
--- ipa-inline.c	(revision 127112)
+++ ipa-inline.c	(working copy)
@@ -1558,7 +1558,7 @@ struct tree_opt_pass pass_inline_paramet
   PROP_cfg,				/* properties_provided */
   0,					/* properties_destroyed */
   0,					/* todo_flags_start */
-  0,					/* todo_flags_finish */
+  TODO_dump_func,		        /* todo_flags_finish */
   0					/* letter */
 };
 
Index: lto-tree-tags.def
===================================================================
--- lto-tree-tags.def	(revision 127112)
+++ lto-tree-tags.def	(working copy)
@@ -55,6 +55,7 @@
   MAP_EXPR_TAGS(BIT_FIELD_REF, LTO_bit_field_ref0, 2)
   MAP_EXPR_TAGS(CALL_EXPR, LTO_call_expr0, 2)
   MAP_EXPR_TAGS(CASE_LABEL_EXPR, LTO_case_label_expr0, 4)
+  MAP_EXPR_TAGS(COND_EXPR, LTO_cond_expr0, 2)
   MAP_EXPR_TAGS(COMPLEX_CST, LTO_complex_cst0, 2)
   MAP_EXPR_TAGS(RETURN_EXPR, LTO_return_expr0, 3)
   MAP_EXPR_TAGS(VAR_DECL, LTO_var_decl0, 2)
@@ -98,7 +99,6 @@
   MAP_EXPR_TAG(CEIL_MOD_EXPR, LTO_ceil_mod_expr)
   MAP_EXPR_TAG(COMPLEX_EXPR, LTO_complex_expr)
   MAP_EXPR_TAG(COMPOUND_EXPR, LTO_compound_expr)
-  MAP_EXPR_TAG(COND_EXPR, LTO_cond_expr)
   MAP_EXPR_TAG(CONJ_EXPR, LTO_conj_expr)
   MAP_EXPR_TAG(CONVERT_EXPR, LTO_convert_expr)
   MAP_EXPR_TAG(DOT_PROD_EXPR, LTO_dot_prod_expr)
@@ -196,7 +196,8 @@
   SET_NAME (LTO_complex_expr, "complex_expr")
   SET_NAME (LTO_component_ref, "component_ref")
   SET_NAME (LTO_compound_expr, "compound_expr")
-  SET_NAME (LTO_cond_expr, "cond_expr")
+  SET_NAME (LTO_cond_expr0, "cond_expr0")
+  SET_NAME (LTO_cond_expr1, "cond_expr1")
   SET_NAME (LTO_conj_expr, "conj_expr")
   SET_NAME (LTO_const_decl, "const_decl")
   SET_NAME (LTO_constructor, "constructor")
Index: lto-tags.h
===================================================================
--- lto-tags.h	(revision 127112)
+++ lto-tags.h	(working copy)
@@ -253,182 +253,197 @@ struct lto_function_header
    type codes.  */
 #define REDUNDANT_TYPE_SYSTEM 1
 
+enum LTO_tags {
+
 /* The 1 variant indicates that the basic block is not empty.  */
-#define LTO_bb0                         0x001
-#define LTO_bb1                         0x002
+  LTO_bb0 = 1,
+  LTO_bb1,
 /* Variant 1 is used to set region to no zero value.  */
-#define LTO_set_eh0                     0x003
-#define LTO_set_eh1                     0x004
+  LTO_set_eh0,
+  LTO_set_eh1,
 
 /* All of the expression types that we can see.  */
-#define LTO_abs_expr                    0x005
-#define LTO_addr_expr                   0x006
-#define LTO_align_indirect_ref          0x007
-#define LTO_array_range_ref             0x008
-#define LTO_array_ref                   0x009
-#define LTO_asm_expr                    0x00A
-#define LTO_assert_expr                 0x00B
-#define LTO_bit_and_expr                0x00C
-#define LTO_bit_ior_expr                0x00D
+  LTO_abs_expr,
+  LTO_addr_expr,
+  LTO_align_indirect_ref,
+  LTO_array_range_ref,
+  LTO_array_ref,
+  LTO_asm_expr,
+  LTO_assert_expr,
+  LTO_bit_and_expr,
+  LTO_bit_ior_expr,
+
 /* Variant 1 is used if both operands 1 and 2 are constant ints.  */
-#define LTO_bit_field_ref0              0x00E
-#define LTO_bit_field_ref1              0x00F
-#define LTO_bit_not_expr                0x010
-#define LTO_bit_xor_expr                0x011
+  LTO_bit_field_ref0,
+  LTO_bit_field_ref1,
+  LTO_bit_not_expr,
+  LTO_bit_xor_expr,
+
 /* Call_exprs are terminated by a 0 to indicate the end of the
    parameter list.  Variant 1 indicates the presence of a call
    chain.  */
-#define LTO_call_expr0                  0x012
-#define LTO_call_expr1                  0x013
+  LTO_call_expr0,
+  LTO_call_expr1,
+
 /* Variant 1 and 3 are if CASE_LOW exists and variant 2 and 3 are if
    CASE_HIGH exists.  */
-#define LTO_case_label_expr0            0x014
-#define LTO_case_label_expr1            0x015
-#define LTO_case_label_expr2            0x016
-#define LTO_case_label_expr3            0x017
-#define LTO_ceil_div_expr               0x018
-#define LTO_ceil_mod_expr               0x019
-#define LTO_change_dynamic_type_expr    0x01A
-/* 1 if the elements are reals and 0 if the elements are ints.  */
-#define LTO_complex_cst0                0x01B
-#define LTO_complex_cst1                0x01C
-#define LTO_complex_expr                0x01D
-#define LTO_component_ref               0x01E
-#define LTO_compound_expr               0x01F
-#define LTO_cond_expr                   0x020
-#define LTO_conj_expr                   0x021
-#define LTO_const_decl                  0x022
+  LTO_case_label_expr0,
+  LTO_case_label_expr1,
+  LTO_case_label_expr2,
+  LTO_case_label_expr3,
+  LTO_ceil_div_expr,
+  LTO_ceil_mod_expr,
+  LTO_change_dynamic_type_expr,
+
+/* Variant 1 if the elements are reals and 0 if the elements are ints.  */
+  LTO_complex_cst0,
+  LTO_complex_cst1,
+  LTO_complex_expr,
+  LTO_component_ref,
+  LTO_compound_expr,
+
+/* Variant 1 if operands 1 and 2 are NULL.  */
+  LTO_cond_expr0,
+  LTO_cond_expr1,
+  LTO_conj_expr,
+  LTO_const_decl,
+
 /* This form is terminated by a zero.  */
-#define LTO_constructor                 0x023
-#define LTO_constructor_range           0x024
-#define LTO_convert_expr                0x025
-#define LTO_dot_prod_expr               0x026
-#define LTO_eq_expr                     0x027
-#define LTO_exact_div_expr              0x028
-#define LTO_exc_ptr_expr                0x029
-#define LTO_field_decl                  0x02A
-#define LTO_filter_expr                 0x02B
-#define LTO_fix_ceil_expr               0x02C
-#define LTO_fix_floor_expr              0x02D
-#define LTO_fix_round_expr              0x02E
-#define LTO_fix_trunc_expr              0x02F
-#define LTO_float_expr                  0x030
-#define LTO_floor_div_expr              0x031
-#define LTO_floor_mod_expr              0x032
-#define LTO_function_decl               0x033
-#define LTO_ge_expr                     0x034
-#define LTO_gimple_modify_stmt          0x035
-#define LTO_goto_expr                   0x036
-#define LTO_gt_expr                     0x037
-#define LTO_imagpart_expr               0x038
-#define LTO_indirect_ref                0x039
-#define LTO_integer_cst                 0x03A
-#define LTO_label_decl                  0x03B
-#define LTO_label_expr                  0x03C
-#define LTO_le_expr                     0x03D
-#define LTO_lrotate_expr                0x03E
-#define LTO_lshift_expr                 0x03F
-#define LTO_lt_expr                     0x040
-#define LTO_ltgt_expr                   0x041
-#define LTO_max_expr                    0x042
-#define LTO_min_expr                    0x043
-#define LTO_minus_expr                  0x044
-#define LTO_misaligned_indirect_ref     0x045
-#define LTO_modify_expr                 0x046
-#define LTO_mult_expr                   0x047
-#define LTO_ne_expr                     0x048
-#define LTO_negate_expr                 0x049
-#define LTO_non_lvalue_expr             0x04A
-#define LTO_nop_expr                    0x04B
-#define LTO_obj_type_ref                0x04C
-#define LTO_ordered_expr                0x04D
-#define LTO_parm_decl                   0x04E
-#define LTO_phi_node                    0x04F
-#define LTO_pointer_plus_expr           0x050
-#define LTO_plus_expr                   0x051
-#define LTO_range_expr                  0x052
-#define LTO_rdiv_expr                   0x053
-#define LTO_real_cst                    0x054
-#define LTO_realign_load_expr           0x055
-#define LTO_realpart_expr               0x056
-#define LTO_reduc_max_expr              0x057
-#define LTO_reduc_min_expr              0x058
-#define LTO_reduc_plus_expr             0x059
-#define LTO_result_decl                 0x05A
+  LTO_constructor,
+  LTO_constructor_range,
+  LTO_convert_expr,
+  LTO_dot_prod_expr,
+  LTO_eq_expr,
+  LTO_exact_div_expr,
+  LTO_exc_ptr_expr,
+  LTO_field_decl,
+  LTO_filter_expr,
+  LTO_fix_ceil_expr,
+  LTO_fix_floor_expr,
+  LTO_fix_round_expr,
+  LTO_fix_trunc_expr,
+  LTO_float_expr,
+  LTO_floor_div_expr,
+  LTO_floor_mod_expr,
+  LTO_function_decl,
+  LTO_ge_expr,
+  LTO_gimple_modify_stmt,
+  LTO_goto_expr,
+  LTO_gt_expr,
+  LTO_imagpart_expr,
+  LTO_indirect_ref,
+  LTO_integer_cst,
+  LTO_label_decl,
+  LTO_label_expr,
+  LTO_le_expr,
+  LTO_lrotate_expr,
+  LTO_lshift_expr,
+  LTO_lt_expr,
+  LTO_ltgt_expr,
+  LTO_max_expr,
+  LTO_min_expr,
+  LTO_minus_expr,
+  LTO_misaligned_indirect_ref,
+  LTO_modify_expr,
+  LTO_mult_expr,
+  LTO_ne_expr,
+  LTO_negate_expr,
+  LTO_non_lvalue_expr,
+  LTO_nop_expr,
+  LTO_obj_type_ref,
+  LTO_ordered_expr,
+  LTO_parm_decl,
+  LTO_phi_node,
+  LTO_pointer_plus_expr,
+  LTO_plus_expr,
+  LTO_range_expr,
+  LTO_rdiv_expr,
+  LTO_real_cst,
+  LTO_realign_load_expr,
+  LTO_realpart_expr,
+  LTO_reduc_max_expr,
+  LTO_reduc_min_expr,
+  LTO_reduc_plus_expr,
+  LTO_result_decl,
+
 /* Form "return;"  */
-#define LTO_return_expr0                0x05B
+  LTO_return_expr0,
+
 /* Form "return x;"  */
-#define LTO_return_expr1                0x05C
+  LTO_return_expr1,
+
 /* Form "return x=y;"  */
-#define LTO_return_expr2                0x05D
-#define LTO_resx_expr                   0x05E
-#define LTO_round_div_expr              0x05F
-#define LTO_round_mod_expr              0x060
-#define LTO_rrotate_expr                0x061
-#define LTO_rshift_expr                 0x062
-#define LTO_ssa_name                    0x063
-#define LTO_string_cst                  0x064
+  LTO_return_expr2,
+  LTO_resx_expr,
+  LTO_round_div_expr,
+  LTO_round_mod_expr,
+  LTO_rrotate_expr,
+  LTO_rshift_expr,
+  LTO_ssa_name,
+  LTO_string_cst,
+
 /* Cases are terminated a zero.  */
-#define LTO_switch_expr                 0x065
-#define LTO_trunc_div_expr              0x066
-#define LTO_trunc_mod_expr              0x067
-#define LTO_truth_and_expr              0x068
-#define LTO_truth_not_expr              0x069
-#define LTO_truth_or_expr               0x06A
-#define LTO_truth_xor_expr              0x06B
-#define LTO_uneq_expr                   0x06C
-#define LTO_unge_expr                   0x070
-#define LTO_ungt_expr                   0x071
-#define LTO_unle_expr                   0x072
-#define LTO_unlt_expr                   0x073
-#define LTO_unordered_expr              0x074
+  LTO_switch_expr,
+  LTO_trunc_div_expr,
+  LTO_trunc_mod_expr,
+  LTO_truth_and_expr,
+  LTO_truth_not_expr,
+  LTO_truth_or_expr,
+  LTO_truth_xor_expr,
+  LTO_uneq_expr,
+  LTO_unge_expr,
+  LTO_ungt_expr,
+  LTO_unle_expr,
+  LTO_unlt_expr,
+  LTO_unordered_expr,
+
 /* 1 for static or extern and 0 for local.  */
-#define LTO_var_decl0                   0x075
-#define LTO_var_decl1                   0x076
-#define LTO_vec_cond_expr               0x077
-#define LTO_vec_lshift_expr             0x078
-#define LTO_vec_rshift_expr             0x079
-/* 1 if the elements are reals and 0 if the elements are ints.  */
-#define LTO_vector_cst0                 0x07A
-#define LTO_vector_cst1                 0x07B
-#define LTO_view_convert_expr           0x07C
-#define LTO_widen_mult_expr             0x07D
-#define LTO_widen_sum_expr              0x07E
-#define LTO_with_size_expr              0x080
+  LTO_var_decl0,
+  LTO_var_decl1,
+  LTO_vec_cond_expr,
+  LTO_vec_lshift_expr,
+  LTO_vec_rshift_expr,
 
+/* 1 if the elements are reals and 0 if the elements are ints.  */
+  LTO_vector_cst0,
+  LTO_vector_cst1,
+  LTO_view_convert_expr,
+  LTO_widen_mult_expr,
+  LTO_widen_sum_expr,
+  LTO_with_size_expr,
 
 /* All of the statement types that do not also appear as
    expressions.  */
-#define LTO_asm_inputs                  0x090
-#define LTO_asm_outputs                 0x091
-#define LTO_asm_clobbers                0x092
-
-#define LTO_function                    0x093
-#define LTO_attribute_list              0x094
-#define LTO_eh_table                    0x095
+  LTO_asm_inputs,
+  LTO_asm_outputs,
+  LTO_asm_clobbers,
+
+  LTO_function,
+  LTO_attribute_list,
+  LTO_eh_table,
 
 /* Each of these requires 4 variants.  1 and 3 are have_inner and 2
    and 3 are may_contain_throw.  */
-#define LTO_eh_table_cleanup0           0x0A0
-#define LTO_eh_table_cleanup1           0x0A1
-#define LTO_eh_table_cleanup2           0x0A2
-#define LTO_eh_table_cleanup3           0x0A3
-#define LTO_eh_table_try0               0x0A4
-#define LTO_eh_table_try1               0x0A5
-#define LTO_eh_table_try2               0x0A6
-#define LTO_eh_table_try3               0x0A7
-#define LTO_eh_table_catch0             0x0A8
-#define LTO_eh_table_catch1             0x0A9
-#define LTO_eh_table_catch2             0x0AA
-#define LTO_eh_table_catch3             0x0AB
-#define LTO_eh_table_allowed0           0x0AC
-#define LTO_eh_table_allowed1           0x0AD
-#define LTO_eh_table_allowed2           0x0AE
-#define LTO_eh_table_allowed3           0x0AF
-#define LTO_eh_table_must_not_throw0    0x0B0
-#define LTO_eh_table_must_not_throw1    0x0B1
-#define LTO_eh_table_must_not_throw2    0x0B2
-#define LTO_eh_table_must_not_throw3    0x0B3
+  LTO_eh_table_cleanup0,
+  LTO_eh_table_cleanup1,
+  LTO_eh_table_cleanup2,
+  LTO_eh_table_cleanup3,
+  LTO_eh_table_try0,
+  LTO_eh_table_try1,
+  LTO_eh_table_try2,
+  LTO_eh_table_try3,
+  LTO_eh_table_catch0,
+  LTO_eh_table_catch1,
+  LTO_eh_table_catch2,
+  LTO_eh_table_catch3,
+  LTO_eh_table_allowed0,
+  LTO_eh_table_allowed1,
+  LTO_eh_table_allowed2,
+  LTO_eh_table_allowed3,
+  LTO_eh_table_must_not_throw0,
+  LTO_eh_table_must_not_throw1,
+  LTO_eh_table_must_not_throw2,
+  LTO_eh_table_must_not_throw3,
 
 /* There are 16 variants of the following decl bodies depending on the
    subtrees that may or may not be there in the decl_common part of
@@ -441,9 +456,11 @@ struct lto_function_header
    These next two tags must have their last hex digit be 0. 
 */
 
-#define LTO_local_var_decl_body0        0x0C0
-#define LTO_parm_decl_body0             0x0D0
-#define LTO_last_tag                    0x0E0
+  LTO_local_var_decl_body0 = 0x0C0,
+  LTO_parm_decl_body0      = 0x0D0,
+  LTO_last_tag             = 0x0E0
+};
+
 /* The string that is prepended on the DECL_ASSEMBLER_NAME to make the 
    section name for the function.  */
 #define LTO_SECTION_NAME_PREFIX         ".gnu.lto_"
Index: ipa.c
===================================================================
--- ipa.c	(revision 127112)
+++ ipa.c	(working copy)
@@ -281,7 +281,7 @@ function_and_variable_visibility (void)
 static bool
 gate_ipa_fun_and_var_visibility (void)
 {
-  return !in_lto_p;
+  return true;
 }
 
 
Index: tree.def
===================================================================
--- tree.def	(revision 127112)
+++ tree.def	(working copy)
@@ -485,7 +485,10 @@ DEFTREECODE (TARGET_EXPR, "target_expr",
    Operand 1 must have the same type as the entire expression, unless
    it unconditionally throws an exception, in which case it should
    have VOID_TYPE.  The same constraints apply to operand 2.  The
-   condition in operand 0 must be of integral type.  */
+   condition in operand 0 must be of integral type. 
+
+   In cfg gimple, if you do not have a selection expression, operands
+   1 and 2 are NULL.  The operands are then taken from the cfg edges. */
 DEFTREECODE (COND_EXPR, "cond_expr", tcc_expression, 3)
 
 /* Vector conditional expression. It is like COND_EXPR, but with
Index: tree-dfa.c
===================================================================
--- tree-dfa.c	(revision 127112)
+++ tree-dfa.c	(working copy)
@@ -85,20 +85,26 @@ find_referenced_vars (void)
 {
   basic_block bb;
   block_stmt_iterator si;
+  tree phi;
 
   FOR_EACH_BB (bb)
-    for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
-      {
-	tree *stmt_p = bsi_stmt_ptr (si);
-	walk_tree (stmt_p, find_vars_r, NULL, NULL);
-      }
+    {
+      for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
+	{
+	  tree *stmt_p = bsi_stmt_ptr (si);
+	  walk_tree (stmt_p, find_vars_r, NULL, NULL);
+	}
+
+      for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+	walk_tree (&phi, find_vars_r, NULL, NULL);
+    }
 
   return 0;
 }
 
 struct tree_opt_pass pass_referenced_vars =
 {
-  NULL,					/* name */
+  "referenced-vars",			/* name */
   NULL,					/* gate */
   find_referenced_vars,			/* execute */
   NULL,					/* sub */
@@ -109,7 +115,7 @@ struct tree_opt_pass pass_referenced_var
   PROP_referenced_vars,			/* properties_provided */
   0,					/* properties_destroyed */
   0,					/* todo_flags_start */
-  0,                                    /* todo_flags_finish */
+  TODO_dump_func,                       /* todo_flags_finish */
   0				        /* letter */
 };
 
@@ -616,9 +622,14 @@ collect_dfa_stats_r (tree *tp, int *walk
 static tree
 find_vars_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
 {
+  /* If we are reading the lto info back in, we need to rescan the
+     referenced vars.  */
+  if (TREE_CODE (*tp) == SSA_NAME)
+    add_referenced_var (SSA_NAME_VAR (*tp));
+
   /* If T is a regular variable that the optimizers are interested
      in, add it to the list of variables.  */
-  if (SSA_VAR_P (*tp))
+  else if (SSA_VAR_P (*tp))
     add_referenced_var (*tp);
 
   /* Type, _DECL and constant nodes have no interesting children.
Index: lto/lto-read.c
===================================================================
--- lto/lto-read.c	(revision 127112)
+++ lto/lto-read.c	(working copy)
@@ -384,6 +384,24 @@ process_flags (tree expr, unsigned HOST_
 }
 
 
+/* Read the flags for CODE from IB.  */
+
+static unsigned int 
+input_flags (struct input_block *ib, enum tree_code code)
+{
+  unsigned int flags;
+
+  if (TEST_BIT (lto_flags_needed_for, code))
+    {
+      LTO_DEBUG_TOKEN ("flags")
+      flags = input_uleb128 (ib);
+    }
+  else
+    flags = 0;
+  return flags;
+}
+
+
 /* Read a node in the gimple tree from IB.  The TAG has already been
    read.  */
 
@@ -402,13 +420,7 @@ input_expr_operand (struct input_block *
   if (TEST_BIT (lto_types_needed_for, code))
     type = get_type_ref (fun_in, ib);
 
-  if (TEST_BIT (lto_flags_needed_for, code))
-    {
-      LTO_DEBUG_TOKEN ("flags")
-      flags = input_uleb128 (ib);
-    }
-  else
-    flags = 0;
+  flags = input_flags (ib, code);
 
   /* FIXME! need to figure out how to set the file and line number.  */
   if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code)))
@@ -606,8 +618,32 @@ input_expr_operand (struct input_block *
       result = build1 (code, void_type_node, get_label_decl (fun_in, ib));
       break;
 
+    case COND_EXPR:
+      if (tag == LTO_cond_expr0)
+	{
+	  tree op0;
+	  tree op1;
+	  tree op2;
+	  op0 = input_expr_operand (ib, fun_in, fn, 
+				    input_record_start (ib));
+	  op1 = input_expr_operand (ib, fun_in, fn, 
+				    input_record_start (ib));
+	  op2 = input_expr_operand (ib, fun_in, fn, 
+				    input_record_start (ib));
+	  result = build3 (code, type, op0, op1, op2);
+	}
+      else
+	{
+	  tree op0;
+	  op0 = input_expr_operand (ib, fun_in, fn, 
+				    input_record_start (ib));
+	  result = build3 (code, type, op0, NULL, NULL);
+	}
+      break;
+      
+
     case RESULT_DECL:
-      result = build0 (code, NULL_TREE);
+      result = build0 (code, type);
       break;
 
     case COMPONENT_REF:
@@ -711,11 +747,11 @@ input_expr_operand (struct input_block *
       switch (tag) 
 	{
 	case LTO_return_expr0:
-	  result = build1 (code, NULL_TREE, NULL_TREE);
+	  result = build1 (code, type, NULL_TREE);
 	  break;
 	  
 	case LTO_return_expr1:
-	  result = build1 (code, NULL_TREE, 
+	  result = build1 (code, type, 
 			   input_expr_operand (ib, fun_in, fn, 
 					       input_record_start (ib)));
 	  break;
@@ -726,7 +762,7 @@ input_expr_operand (struct input_block *
 					   input_record_start (ib));
 	    tree op1 = input_expr_operand (ib, fun_in, fn,
 					   input_record_start (ib));
-	    result = build1 (code, NULL_TREE, 
+	    result = build1 (code, type, 
 			     build2 (MODIFY_EXPR, NULL_TREE, op0, op1));
 	  }
 	  break;
@@ -838,7 +874,8 @@ input_expr_operand (struct input_block *
     }
 
   LTO_DEBUG_UNDENT()
-  process_flags (result, flags);
+  if (flags)
+    process_flags (result, flags);
   return result;
 }
 
@@ -1136,8 +1173,11 @@ input_cfg (struct input_block *ib, struc
 /* Input the next phi function for BB.  */
 
 static tree
-input_phi (struct input_block *ib, basic_block bb, struct function *fn)
+input_phi (struct input_block *ib, basic_block bb, 
+	   struct fun_in *fun_in, struct function *fn)
 {
+  unsigned int flags = input_flags (ib, PHI_NODE);
+
   tree phi_result = VEC_index (tree, SSANAMES (fn), input_uleb128 (ib));
   int len = EDGE_COUNT (bb->preds);
   int i;
@@ -1147,7 +1187,7 @@ input_phi (struct input_block *ib, basic
 
   for (i = 0; i < len; i++)
     {
-      tree def = VEC_index (tree, SSANAMES (fn), input_uleb128 (ib));
+      tree def = input_expr_operand (ib, fun_in, fn, input_record_start (ib));
       int src_index = input_uleb128 (ib);
       basic_block sbb = BASIC_BLOCK_FOR_FUNCTION (fn, src_index);
       
@@ -1163,6 +1203,12 @@ input_phi (struct input_block *ib, basic
 
       add_phi_arg (result, def, e); 
     }
+
+  if (flags)
+    process_flags (result, flags);
+
+  LTO_DEBUG_UNDENT()
+
   return result;
 }
 
@@ -1181,11 +1227,20 @@ input_ssa_names (struct fun_in *fun_in, 
   
   while (i)
     {
+      tree ssa_name;
+      tree name;
+      unsigned int flags;
+
       /* Skip over the elements that had been freed.  */
       while (VEC_length (tree, SSANAMES (fn)) < i)
 	VEC_quick_push (tree, SSANAMES (fn), NULL_TREE);
 
-      make_ssa_name (input_expr_operand (ib, fun_in, fn, input_record_start (ib)), NULL);
+      name = input_expr_operand (ib, fun_in, fn, input_record_start (ib));
+      ssa_name = make_ssa_name (name, build_empty_stmt ());
+
+      LTO_DEBUG_TOKEN ("flags")
+      flags = input_uleb128 (ib);
+      process_flags (ssa_name, flags);
 
       i = input_uleb128 (ib);
     } 
@@ -1196,7 +1251,7 @@ input_ssa_names (struct fun_in *fun_in, 
 
 static void
 input_bb (struct input_block *ib, unsigned int tag, 
-	  struct function *fn, struct fun_in *fun_in)
+	  struct fun_in *fun_in, struct function *fn)
 {
   unsigned int index;
   basic_block bb;
@@ -1229,7 +1284,7 @@ input_bb (struct input_block *ib, unsign
   tag = input_record_start (ib);
   while (tag)
     {
-      input_phi (ib, bb, fn);
+      input_phi (ib, bb, fun_in, fn);
       LTO_DEBUG_INDENT_TOKEN ("phi")
       tag = input_record_start (ib);
     }
@@ -1255,7 +1310,7 @@ input_function (tree fn_decl, struct fun
   tag = input_record_start (ib);
   while (tag)
     {
-      input_bb (ib, tag, fn, fun_in);
+      input_bb (ib, tag, fun_in, fn);
       tag = input_record_start (ib);
     }
 
Index: lto/lto-lang.c
===================================================================
--- lto/lto-lang.c	(revision 127112)
+++ lto/lto-lang.c	(working copy)
@@ -136,7 +136,6 @@ lto_init (void)
   /* Always operate in unit-at-time mode so that we can defer
      decisions about what to output.  */
   flag_unit_at_a_time = 1;
-  in_lto_p = false;
 
   /* Create the basic integer types.  */
   build_common_tree_nodes (flag_signed_char, 
@@ -153,6 +152,7 @@ lto_init (void)
 
   /* Initialize LTO-specific data structures.  */
   lto_global_var_decls = VEC_alloc (tree, gc, 256);
+  in_lto_p = true;
 
   return true;
 }
Index: tree-optimize.c
===================================================================
--- tree-optimize.c	(revision 127112)
+++ tree-optimize.c	(working copy)
@@ -139,6 +139,35 @@ struct tree_opt_pass pass_all_early_opti
   0					/* letter */
 };
 
+
+/* Control the early passes that are run if this is the lto front end.
+   This cannot be in the lto front end because that must be linked
+   separately.  */
+
+static bool
+gate_early_lto_passes (void)
+{
+	  /* Don't bother doing anything if the program has errors.  */
+  return (!errorcount && !sorrycount && in_lto_p);
+}
+
+struct tree_opt_pass pass_early_lto_passes =
+{
+  "early_lto_passes",    		/* name */
+  gate_early_lto_passes,		/* gate */
+  NULL,					/* execute */
+  NULL,					/* sub */
+  NULL,					/* next */
+  0,					/* static_pass_number */
+  0,					/* tv_id */
+  0,					/* properties_required */
+  0,					/* properties_provided */
+  0,					/* properties_destroyed */
+  0,					/* todo_flags_start */
+  0,		                        /* todo_flags_finish */
+  0					/* letter */
+};
+
 /* Pass: cleanup the CFG just before expanding trees to RTL.
    This is just a round of label cleanups and case node grouping
    because after the tree optimizers have run such cleanups may
Index: passes.c
===================================================================
--- passes.c	(revision 127112)
+++ passes.c	(working copy)
@@ -533,6 +533,12 @@ init_optimization_passes (void)
       NEXT_PASS (pass_rebuild_cgraph_edges);
       NEXT_PASS (pass_inline_parameters);
     }
+  NEXT_PASS (pass_early_lto_passes);
+    {
+      struct tree_opt_pass **p = &pass_early_lto_passes.sub;
+      NEXT_PASS (pass_referenced_vars);
+      NEXT_PASS (pass_rebuild_ssa_for_lto);
+    }
   NEXT_PASS (pass_ipa_lto_out);
   NEXT_PASS (pass_ipa_increase_alignment);
   NEXT_PASS (pass_ipa_matrix_reorg);
@@ -1200,4 +1206,39 @@ execute_ipa_pass_list (struct tree_opt_p
     }
   while (pass);
 }
+
+extern void debug_properties (unsigned int);
+extern void dump_properties (FILE *, unsigned int);
+void
+dump_properties (FILE *dump, unsigned int props)
+{
+  fprintf (dump, "Properties:\n");
+  if (props & PROP_gimple_any)
+    fprintf (dump, "PROP_gimple_any\n");
+  if (props & PROP_gimple_lcf)
+    fprintf (dump, "PROP_gimple_lcf\n");
+  if (props & PROP_gimple_leh)
+    fprintf (dump, "PROP_gimple_leh\n");
+  if (props & PROP_cfg)
+    fprintf (dump, "PROP_cfg\n");
+  if (props & PROP_referenced_vars)
+    fprintf (dump, "PROP_referenced_vars\n");
+  if (props & PROP_pta)
+    fprintf (dump, "PROP_pta\n");
+  if (props & PROP_ssa)
+    fprintf (dump, "PROP_ssa\n");
+  if (props & PROP_no_crit_edges)
+    fprintf (dump, "PROP_no_crit_edges\n");
+  if (props & PROP_rtl)
+    fprintf (dump, "PROP_rtl\n");
+  if (props & PROP_alias)
+    fprintf (dump, "PROP_alias\n");
+  if (props & PROP_gimple_lomp)
+    fprintf (dump, "PROP_gimple_lomp\n");
+}
+  void
+debug_properties (unsigned int props)
+{
+    dump_properties (stderr, props);
+}
 #include "gt-passes.h"
Index: tree-ssanames.c
===================================================================
--- tree-ssanames.c	(revision 127112)
+++ tree-ssanames.c	(working copy)
@@ -359,6 +359,6 @@ struct tree_opt_pass pass_release_ssa_na
   0,					/* properties_provided */
   0,					/* properties_destroyed */
   0,					/* todo_flags_start */
-  0,					/* todo_flags_finish */
+  TODO_dump_func,			/* todo_flags_finish */
   0					/* letter */
 };

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