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]

Re: LTO/WHOPR summary streaming fixes


On Thu, 22 Oct 2009, Jan Hubicka wrote:

> Hi,
> this should be final version of patch.  Tested on x86_64-linux and also
> Richard kindly tested it works with Spec2006.
> The patch fixes ICE in ipa-cp seen on libquantum. OK?

Ok.  I'll think about the fixup problem.  I think we can easily delay
cgraph node merging until after fixup, then read in the summaries and
then apply the node merging.

Thanks,
Richard.

> Honza
> 
> 
> 	* ipa-cp.c (ipcp_write_summary, ipcp_read_summary): New functions.
> 	(pass_ipa_cp): Register them.
> 	(ipcp_init_stage): Analyze all functions for whopr/lto.
> 	(ipcp_propagate_stage): Skip external calls.
> 	(ipcp_iterate_stage): Call ipa_update_after_lto_read if needed.
> 	* ipa-reference.c (write_node_summary_p): Fix thinko about availability.
> 	* cgraphunit.c (ipa_passes): When in lto, ne er produce new summaries;
> 	when in ltrans, skip executing of ipa passes since everything should've
> 	been done.
> 	* ipa-inline.c (cgraph_decide_inlining): Remove FIXMEs.
> 	(inline_generate_summary): Likewise.
> 	(inline_read_summary): New function.
> 	(inline_write_summary): New function.
> 	(pass_ipa_inline): Register new hooks.
> 	* ipa-prop.c: Inlcude lto-streamer.h
> 	(ipa_edge_args_vector): Update declaration.
> 	(ipa_count_arguments, ipa_compute_jump_functions,
> 	ipa_free_edge_args_substructures): Move ipa_edge_args_vector into ggc.
> 	(ipa_write_jump_function, ipa_read_jump_function, ipa_write_node_info,
> 	ipa_read_node_info): New static functions.
> 	(ipa_prop_write_jump_functions, ipa_prop_read_jump_functions): Update.
> 	(duplicate_array): Use xmalloc.
> 	(duplicate_ggc_array): New.
> 	(ipa_edge_duplication_hook): Use it.
> 	(ipa_update_after_lto_read): New function.
> 	* ipa-prop.h (ipa_prop_write_jump_functions,
> 	ipa_prop_read_jump_functions): Declare.
> 	(ipa_pass_through_data, ipa_ancestor_jf_data, ipa_member_ptr_cst,
> 	jump_func_value, ipa_member_ptr_cst, ipa_edge_args): Add GTY markers.
> 	(ipa_edge_args_vector): Move into GGC.
> 	(ipa_check_create_edge_args): Update.
> 	(ipa_update_after_lto_read): New.
> 	* passes.c (ipa_write_summaries_1): When in wpa, do not write summaries.
> 	(ipa_read_summaries): When in ltrans, so not read summaries.
> 	* lto-streamer.c (lto_get_section_name): Add LTO_section_jump_functions.
> 	* lto-streamer.h (LTO_section_jump_functions): New section.
> 	(produce_asm): Declare.
> 	* lto-cgraph.c (output_cgraph): Output edges in reverse order.
> 	* lto-streamer-out.c (produce_asm): Export.
> 	* lto-streamer-in.c: Include tree-pass.h
> 	(input_function): Free dominance info when done.
> 	(lto_read_body): Push ipa_inline in ltrans stage.
> 	* gengtype.c (open_base_files): Add ipa-prop.h into includes.
> 	* Makefile.in (GTFILES): Add ipa-prop.h
> 
> 	* lto.c (lto_fixup_jump_functions): New function.
> 	(lto_fixup_decls): Use it.
> Index: gengtype.c
> ===================================================================
> *** gengtype.c	(revision 152974)
> --- gengtype.c	(working copy)
> *************** open_base_files (void)
> *** 1571,1577 ****
>         "optabs.h", "libfuncs.h", "debug.h", "ggc.h", "cgraph.h",
>         "tree-flow.h", "reload.h", "cpp-id-data.h", "tree-chrec.h",
>         "cfglayout.h", "except.h", "output.h", "gimple.h", "cfgloop.h",
> !       "target.h", NULL
>       };
>       const char *const *ifp;
>       outf_p gtype_desc_c;
> --- 1571,1577 ----
>         "optabs.h", "libfuncs.h", "debug.h", "ggc.h", "cgraph.h",
>         "tree-flow.h", "reload.h", "cpp-id-data.h", "tree-chrec.h",
>         "cfglayout.h", "except.h", "output.h", "gimple.h", "cfgloop.h",
> !       "target.h", "ipa-prop.h", NULL
>       };
>       const char *const *ifp;
>       outf_p gtype_desc_c;
> Index: ipa-cp.c
> ===================================================================
> *** ipa-cp.c	(revision 152974)
> --- ipa-cp.c	(working copy)
> *************** ipcp_init_stage (void)
> *** 614,620 ****
>         /* building jump functions  */
>         for (cs = node->callees; cs; cs = cs->next_callee)
>   	{
> ! 	  if (!cs->callee->analyzed)
>   	    continue;
>   	  ipa_count_arguments (cs);
>   	  if (ipa_get_cs_argument_count (IPA_EDGE_REF (cs))
> --- 614,622 ----
>         /* building jump functions  */
>         for (cs = node->callees; cs; cs = cs->next_callee)
>   	{
> ! 	  /* We do not need to bother analyzing calls to unknown
> ! 	     functions unless they may become known during lto/whopr.  */
> ! 	  if (!cs->callee->analyzed && !flag_lto && !flag_whopr)
>   	    continue;
>   	  ipa_count_arguments (cs);
>   	  if (ipa_get_cs_argument_count (IPA_EDGE_REF (cs))
> *************** ipcp_propagate_stage (void)
> *** 696,702 ****
>   	  struct ipa_node_params *callee_info = IPA_NODE_REF (cs->callee);
>   	  struct ipa_edge_args *args = IPA_EDGE_REF (cs);
>   
> ! 	  if (ipa_is_called_with_var_arguments (callee_info))
>   	    continue;
>   
>   	  count = ipa_get_cs_argument_count (args);
> --- 698,706 ----
>   	  struct ipa_node_params *callee_info = IPA_NODE_REF (cs->callee);
>   	  struct ipa_edge_args *args = IPA_EDGE_REF (cs);
>   
> ! 	  if (ipa_is_called_with_var_arguments (callee_info)
> ! 	      || !cs->callee->analyzed
> ! 	      || ipa_is_called_with_var_arguments (callee_info))
>   	    continue;
>   
>   	  count = ipa_get_cs_argument_count (args);
> *************** ipcp_iterate_stage (void)
> *** 727,732 ****
> --- 731,740 ----
>   
>     if (dump_file)
>       fprintf (dump_file, "\nIPA iterate stage:\n\n");
> + 
> +   if (in_lto_p)
> +     ipa_update_after_lto_read ();
> + 
>     for (node = cgraph_nodes; node; node = node->next)
>       {
>         ipcp_initialize_node_lattices (node);
> *************** ipcp_generate_summary (void)
> *** 1276,1281 ****
> --- 1284,1303 ----
>     ipcp_init_stage ();
>   }
>   
> + /* Write ipcp summary for nodes in SET.  */
> + static void
> + ipcp_write_summary (cgraph_node_set set)
> + {
> +   ipa_prop_write_jump_functions (set);
> + }
> + 
> + /* Read ipcp summary.  */
> + static void
> + ipcp_read_summary (void)
> + {
> +   ipa_prop_read_jump_functions ();
> + }
> + 
>   /* Gate for IPCP optimization.  */
>   static bool
>   cgraph_gate_cp (void)
> *************** struct ipa_opt_pass_d pass_ipa_cp =
> *** 1308,1315 ****
>     TODO_remove_functions /* todo_flags_finish */
>    },
>    ipcp_generate_summary,			/* generate_summary */
> !  NULL,					/* write_summary */
> !  NULL,					/* read_summary */
>    NULL,					/* function_read_summary */
>    0,					/* TODOs */
>    NULL,					/* function_transform */
> --- 1330,1337 ----
>     TODO_remove_functions /* todo_flags_finish */
>    },
>    ipcp_generate_summary,			/* generate_summary */
> !  ipcp_write_summary,			/* write_summary */
> !  ipcp_read_summary,			/* read_summary */
>    NULL,					/* function_read_summary */
>    0,					/* TODOs */
>    NULL,					/* function_transform */
> Index: ipa-reference.c
> ===================================================================
> *** ipa-reference.c	(revision 152974)
> --- ipa-reference.c	(working copy)
> *************** write_node_summary_p (struct cgraph_node
> *** 1014,1020 ****
>   {
>     return (node->analyzed 
>   	  && node->global.inlined_to == NULL
> ! 	  && cgraph_function_body_availability (node) == AVAIL_OVERWRITABLE
>   	  && get_reference_vars_info (node) != NULL);
>   }
>   
> --- 1014,1020 ----
>   {
>     return (node->analyzed 
>   	  && node->global.inlined_to == NULL
> ! 	  && cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE
>   	  && get_reference_vars_info (node) != NULL);
>   }
>   
> Index: cgraphunit.c
> ===================================================================
> *** cgraphunit.c	(revision 152974)
> --- cgraphunit.c	(working copy)
> *************** ipa_passes (void)
> *** 1375,1389 ****
>         set_cfun (NULL);
>         current_function_decl = NULL;
>         cgraph_process_new_functions ();
> -     }
>   
> !   execute_ipa_summary_passes ((struct ipa_opt_pass_d *) all_regular_ipa_passes);
>     execute_ipa_summary_passes ((struct ipa_opt_pass_d *) all_lto_gen_passes);
>   
>     if (!in_lto_p)
>       ipa_write_summaries ();
>   
> !   execute_ipa_pass_list (all_regular_ipa_passes);
>   
>     bitmap_obstack_release (NULL);
>   }
> --- 1375,1390 ----
>         set_cfun (NULL);
>         current_function_decl = NULL;
>         cgraph_process_new_functions ();
>   
> !       execute_ipa_summary_passes ((struct ipa_opt_pass_d *) all_regular_ipa_passes);
> !     }
>     execute_ipa_summary_passes ((struct ipa_opt_pass_d *) all_lto_gen_passes);
>   
>     if (!in_lto_p)
>       ipa_write_summaries ();
>   
> !   if (!flag_ltrans)
> !     execute_ipa_pass_list (all_regular_ipa_passes);
>   
>     bitmap_obstack_release (NULL);
>   }
> Index: lto-cgraph.c
> ===================================================================
> *** lto-cgraph.c	(revision 152974)
> --- lto-cgraph.c	(working copy)
> *************** output_cgraph (cgraph_node_set set)
> *** 372,379 ****
>     for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi))
>       {
>         node = csi_node (csi);
> !       for (edge = node->callees; edge; edge = edge->next_callee)
> ! 	lto_output_edge (ob, edge, encoder);
>       }
>   
>     lto_output_uleb128_stream (ob->main_stream, 0);
> --- 372,387 ----
>     for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi))
>       {
>         node = csi_node (csi);
> !       if (node->callees)
> !         {
> ! 	  /* Output edges in backward direction, so the reconstructed callgraph
> ! 	     match and it is easy to associate call sites in the IPA pass summaries.  */
> ! 	  edge = node->callees;
> ! 	  while (edge->next_callee)
> ! 	    edge = edge->next_callee;
> ! 	  for (; edge; edge = edge->prev_callee)
> ! 	    lto_output_edge (ob, edge, encoder);
> ! 	}
>       }
>   
>     lto_output_uleb128_stream (ob->main_stream, 0);
> Index: lto-streamer-out.c
> ===================================================================
> *** lto-streamer-out.c	(revision 152974)
> --- lto-streamer-out.c	(working copy)
> *************** output_bb (struct output_block *ob, basi
> *** 1762,1768 ****
>   /* Create the header in the file using OB.  If the section type is for
>      a function, set FN to the decl for that function.  */
>   
> ! static void
>   produce_asm (struct output_block *ob, tree fn)
>   {
>     enum lto_section_type section_type = ob->section_type;
> --- 1762,1768 ----
>   /* Create the header in the file using OB.  If the section type is for
>      a function, set FN to the decl for that function.  */
>   
> ! void
>   produce_asm (struct output_block *ob, tree fn)
>   {
>     enum lto_section_type section_type = ob->section_type;
> Index: ipa-inline.c
> ===================================================================
> *** ipa-inline.c	(revision 152974)
> --- ipa-inline.c	(working copy)
> *************** cgraph_decide_inlining (void)
> *** 1113,1125 ****
>     bool redo_always_inline = true;
>     int initial_size = 0;
>   
> !   /* FIXME lto.  We need to rethink how to coordinate different passes. */
> !   if (flag_ltrans)
> !     return 0;
> ! 
> !   /* FIXME lto.  We need to re-think about how the passes get invoked. */
> !   if (!flag_wpa)
> !     cgraph_remove_function_insertion_hook (function_insertion_hook_holder);
>   
>     max_count = 0;
>     max_benefit = 0;
> --- 1113,1121 ----
>     bool redo_always_inline = true;
>     int initial_size = 0;
>   
> !   cgraph_remove_function_insertion_hook (function_insertion_hook_holder);
> !   if (in_lto_p && flag_indirect_inlining)
> !     ipa_update_after_lto_read ();
>   
>     max_count = 0;
>     max_benefit = 0;
> *************** inline_generate_summary (void)
> *** 1928,1937 ****
>   {
>     struct cgraph_node *node;
>   
> -   /* FIXME lto.  We should not run any IPA-summary pass in LTRANS mode.  */
> -   if (flag_ltrans)
> -     return;
> - 
>     function_insertion_hook_holder =
>         cgraph_add_function_insertion_hook (&add_new_function, NULL);
>   
> --- 1924,1929 ----
> *************** inline_transform (struct cgraph_node *no
> *** 1976,1981 ****
> --- 1968,2001 ----
>     return todo | execute_fixup_cfg ();
>   }
>   
> + /* Read inline summary.  Jump functions are shared among ipa-cp
> +    and inliner, so when ipa-cp is active, we don't need to write them
> +    twice.  */
> + 
> + static void 
> + inline_read_summary (void)
> + {
> +   if (flag_indirect_inlining)
> +     {
> +       ipa_register_cgraph_hooks ();
> +       if (!flag_ipa_cp)
> +         ipa_prop_read_jump_functions ();
> +     }
> +   function_insertion_hook_holder =
> +       cgraph_add_function_insertion_hook (&add_new_function, NULL);
> + }
> + 
> + /* Write inline summary for node in SET.
> +    Jump functions are shared among ipa-cp and inliner, so when ipa-cp is
> +    active, we don't need to write them twice.  */
> + 
> + static void 
> + inline_write_summary (cgraph_node_set set)
> + {
> +   if (flag_indirect_inlining && !flag_ipa_cp)
> +     ipa_prop_write_jump_functions (set);
> + }
> + 
>   struct ipa_opt_pass_d pass_ipa_inline =
>   {
>    {
> *************** struct ipa_opt_pass_d pass_ipa_inline =
> *** 1995,2002 ****
>     | TODO_remove_functions		/* todo_flags_finish */
>    },
>    inline_generate_summary,		/* generate_summary */
> !  NULL,					/* write_summary */
> !  NULL,					/* read_summary */
>    NULL,					/* function_read_summary */
>    0,					/* TODOs */
>    inline_transform,			/* function_transform */
> --- 2015,2022 ----
>     | TODO_remove_functions		/* todo_flags_finish */
>    },
>    inline_generate_summary,		/* generate_summary */
> !  inline_write_summary,			/* write_summary */
> !  inline_read_summary,			/* read_summary */
>    NULL,					/* function_read_summary */
>    0,					/* TODOs */
>    inline_transform,			/* function_transform */
> Index: lto-streamer-in.c
> ===================================================================
> *** lto-streamer-in.c	(revision 152974)
> --- lto-streamer-in.c	(working copy)
> *************** along with GCC; see the file COPYING3.  
> *** 47,52 ****
> --- 47,53 ----
>   #include "output.h"
>   #include "ipa-utils.h"
>   #include "lto-streamer.h"
> + #include "tree-pass.h"
>   
>   /* Data structure used to hash file names in the source_location field.  */
>   struct string_slot
> *************** input_function (tree fn_decl, struct dat
> *** 1341,1346 ****
> --- 1342,1349 ----
>     fixup_call_stmt_edges (cgraph_node (fn_decl), stmts);
>   
>     update_ssa (TODO_update_ssa_only_virtuals); 
> +   free_dominance_info (CDI_DOMINATORS);
> +   free_dominance_info (CDI_POST_DOMINATORS);
>     free (stmts);
>   }
>   
> *************** lto_read_body (struct lto_file_decl_data
> *** 1455,1460 ****
> --- 1458,1472 ----
>         /* Restore decl state */
>         file_data->current_decl_state = file_data->global_decl_state;
>   
> +       /* FIXME: ipa_transforms_to_apply holds list of passes that have optimization
> +          summaries computed and needs to apply changes.  At the moment WHOPR only
> +          supports inlining, so we can push it here by hand.  In future we need to stream
> +          this field into ltrans compilation.  This will also need to move the field
> + 	 from struct function into cgraph node where it belongs.  */
> +       if (flag_ltrans && !cgraph_node (fn_decl)->global.inlined_to)
> + 	 VEC_safe_push (ipa_opt_pass, heap,
> + 			cfun->ipa_transforms_to_apply,
> + 			(ipa_opt_pass)&pass_ipa_inline);
>         pop_cfun ();
>       }
>     else 
> Index: lto/lto.c
> ===================================================================
> *** lto/lto.c	(revision 152974)
> --- lto/lto.c	(working copy)
> *************** free_decl (const void *p, void *data ATT
> *** 1652,1657 ****
> --- 1652,1704 ----
>     return true;
>   }
>   
> + /* Fixup pointers in jump functions.
> +    TODO: We need some generic solution that will allow tree pointers in
> +    function summaries.  */
> + static void
> + lto_fixup_jump_functions (lto_fixup_data_t * data)
> + {
> +   struct cgraph_node *node;
> +   struct cgraph_edge *cs;
> + 
> +   for (node = cgraph_nodes; node; node = node->next)
> +     {
> +       if (!node->analyzed)
> + 	continue;
> +       for (cs = node->callees; cs; cs = cs->next_callee)
> + 	{
> + 	  int i;
> + 	  struct ipa_edge_args *args = IPA_EDGE_REF (cs);
> + 	  for (i = 0; i < ipa_get_cs_argument_count (args); i++)
> + 	    {
> + 	      struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
> + 	      switch (jf->type)
> + 		{
> + 		case IPA_JF_UNKNOWN:
> + 		  break;
> + 		case IPA_JF_CONST:
> + 		  walk_tree (&jf->value.constant, lto_fixup_tree, data, NULL);
> + 		  break;
> + 		case IPA_JF_PASS_THROUGH:
> + 		  walk_tree (&jf->value.pass_through.operand, lto_fixup_tree,
> + 			     data, NULL);
> + 		  break;
> + 		case IPA_JF_ANCESTOR:
> + 		  walk_tree (&jf->value.ancestor.type, lto_fixup_tree, data,
> + 			     NULL);
> + 		  break;
> + 		case IPA_JF_CONST_MEMBER_PTR:
> + 		  walk_tree (&jf->value.member_cst.pfn, lto_fixup_tree, data,
> + 			     NULL);
> + 		  walk_tree (&jf->value.member_cst.delta, lto_fixup_tree,
> + 			     data, NULL);
> + 		  break;
> + 		}
> + 	    }
> + 	}
> +     }
> + }
> + 
>   /* Fix the decls from all FILES. Replaces each decl with the corresponding
>      prevailing one.  */
>   
> *************** lto_fixup_decls (struct lto_file_decl_da
> *** 1682,1687 ****
> --- 1729,1736 ----
>         if (decl != saved_decl)
>   	VEC_replace (tree, lto_global_var_decls, i, decl);
>       }
> +   if (ipa_edge_args_vector)
> +     lto_fixup_jump_functions (&data);
>   
>     pointer_set_traverse (free_list, free_decl, NULL);
>     pointer_set_destroy (free_list);
> Index: ipa-prop.c
> ===================================================================
> *** ipa-prop.c	(revision 152974)
> --- ipa-prop.c	(working copy)
> *************** along with GCC; see the file COPYING3.  
> *** 33,43 ****
>   #include "timevar.h"
>   #include "flags.h"
>   #include "diagnostic.h"
>   
>   /* Vector where the parameter infos are actually stored. */
>   VEC (ipa_node_params_t, heap) *ipa_node_params_vector;
>   /* Vector where the parameter infos are actually stored. */
> ! VEC (ipa_edge_args_t, heap) *ipa_edge_args_vector;
>   
>   /* Holders of ipa cgraph hooks: */
>   static struct cgraph_edge_hook_list *edge_removal_hook_holder;
> --- 33,44 ----
>   #include "timevar.h"
>   #include "flags.h"
>   #include "diagnostic.h"
> + #include "lto-streamer.h"
>   
>   /* Vector where the parameter infos are actually stored. */
>   VEC (ipa_node_params_t, heap) *ipa_node_params_vector;
>   /* Vector where the parameter infos are actually stored. */
> ! VEC (ipa_edge_args_t, gc) *ipa_edge_args_vector;
>   
>   /* Holders of ipa cgraph hooks: */
>   static struct cgraph_edge_hook_list *edge_removal_hook_holder;
> *************** ipa_count_arguments (struct cgraph_edge 
> *** 248,254 ****
>     arg_num = gimple_call_num_args (stmt);
>     if (VEC_length (ipa_edge_args_t, ipa_edge_args_vector)
>         <= (unsigned) cgraph_edge_max_uid)
> !     VEC_safe_grow_cleared (ipa_edge_args_t, heap,
>   			   ipa_edge_args_vector, cgraph_edge_max_uid + 1);
>     ipa_set_cs_argument_count (IPA_EDGE_REF (cs), arg_num);
>   }
> --- 249,255 ----
>     arg_num = gimple_call_num_args (stmt);
>     if (VEC_length (ipa_edge_args_t, ipa_edge_args_vector)
>         <= (unsigned) cgraph_edge_max_uid)
> !     VEC_safe_grow_cleared (ipa_edge_args_t, gc,
>   			   ipa_edge_args_vector, cgraph_edge_max_uid + 1);
>     ipa_set_cs_argument_count (IPA_EDGE_REF (cs), arg_num);
>   }
> *************** ipa_compute_jump_functions (struct cgrap
> *** 661,668 ****
>   
>     if (ipa_get_cs_argument_count (arguments) == 0 || arguments->jump_functions)
>       return;
> !   arguments->jump_functions = XCNEWVEC (struct ipa_jump_func,
> ! 					ipa_get_cs_argument_count (arguments));
>   
>     call = cs->call_stmt;
>     gcc_assert (is_gimple_call (call));
> --- 662,669 ----
>   
>     if (ipa_get_cs_argument_count (arguments) == 0 || arguments->jump_functions)
>       return;
> !   arguments->jump_functions = GGC_CNEWVEC (struct ipa_jump_func,
> ! 					   ipa_get_cs_argument_count (arguments));
>   
>     call = cs->call_stmt;
>     gcc_assert (is_gimple_call (call));
> *************** void
> *** 1173,1179 ****
>   ipa_free_edge_args_substructures (struct ipa_edge_args *args)
>   {
>     if (args->jump_functions)
> !     free (args->jump_functions);
>   
>     memset (args, 0, sizeof (*args));
>   }
> --- 1174,1180 ----
>   ipa_free_edge_args_substructures (struct ipa_edge_args *args)
>   {
>     if (args->jump_functions)
> !     ggc_free (args->jump_functions);
>   
>     memset (args, 0, sizeof (*args));
>   }
> *************** ipa_free_all_edge_args (void)
> *** 1191,1197 ****
>          i++)
>       ipa_free_edge_args_substructures (args);
>   
> !   VEC_free (ipa_edge_args_t, heap, ipa_edge_args_vector);
>     ipa_edge_args_vector = NULL;
>   }
>   
> --- 1192,1198 ----
>          i++)
>       ipa_free_edge_args_substructures (args);
>   
> !   VEC_free (ipa_edge_args_t, gc, ipa_edge_args_vector);
>     ipa_edge_args_vector = NULL;
>   }
>   
> *************** duplicate_array (void *src, size_t n)
> *** 1262,1268 ****
>     if (!src)
>       return NULL;
>   
> !   p = xcalloc (1, n);
>     memcpy (p, src, n);
>     return p;
>   }
> --- 1263,1284 ----
>     if (!src)
>       return NULL;
>   
> !   p = xmalloc (n);
> !   memcpy (p, src, n);
> !   return p;
> ! }
> ! 
> ! /* Like duplicate_array byt in GGC memory.  */
> ! 
> ! static void *
> ! duplicate_ggc_array (void *src, size_t n)
> ! {
> !   void *p;
> ! 
> !   if (!src)
> !     return NULL;
> ! 
> !   p = ggc_alloc (n);
>     memcpy (p, src, n);
>     return p;
>   }
> *************** ipa_edge_duplication_hook (struct cgraph
> *** 1284,1291 ****
>     arg_count = ipa_get_cs_argument_count (old_args);
>     ipa_set_cs_argument_count (new_args, arg_count);
>     new_args->jump_functions = (struct ipa_jump_func *)
> !     duplicate_array (old_args->jump_functions,
> ! 		     sizeof (struct ipa_jump_func) * arg_count);
>   }
>   
>   /* Hook that is called by cgraph.c when a node is duplicated.  */
> --- 1300,1307 ----
>     arg_count = ipa_get_cs_argument_count (old_args);
>     ipa_set_cs_argument_count (new_args, arg_count);
>     new_args->jump_functions = (struct ipa_jump_func *)
> !     duplicate_ggc_array (old_args->jump_functions,
> ! 		         sizeof (struct ipa_jump_func) * arg_count);
>   }
>   
>   /* Hook that is called by cgraph.c when a node is duplicated.  */
> *************** ipa_dump_param_adjustments (FILE *file, 
> *** 1875,1877 ****
> --- 1891,2173 ----
>     VEC_free (tree, heap, parms);
>   }
>   
> + /* Stream out jump function JUMP_FUNC to OB.  */
> + 
> + static void
> + ipa_write_jump_function (struct output_block *ob,
> + 			 struct ipa_jump_func *jump_func)
> + {
> +   lto_output_uleb128_stream (ob->main_stream,
> + 			     jump_func->type);
> + 
> +   switch (jump_func->type)
> +     {
> +     case IPA_JF_UNKNOWN:
> +       break;
> +     case IPA_JF_CONST:
> +       lto_output_tree (ob, jump_func->value.constant, true);
> +       break;
> +     case IPA_JF_PASS_THROUGH:
> +       lto_output_tree (ob, jump_func->value.pass_through.operand, true);
> +       lto_output_uleb128_stream (ob->main_stream,
> + 				 jump_func->value.pass_through.formal_id);
> +       lto_output_uleb128_stream (ob->main_stream,
> + 				 jump_func->value.pass_through.operation);
> +       break;
> +     case IPA_JF_ANCESTOR:
> +       lto_output_uleb128_stream (ob->main_stream,
> + 				 jump_func->value.ancestor.offset);
> +       lto_output_tree (ob, jump_func->value.ancestor.type, true);
> +       lto_output_uleb128_stream (ob->main_stream,
> + 				 jump_func->value.ancestor.formal_id);
> +       break;
> +     case IPA_JF_CONST_MEMBER_PTR:
> +       lto_output_tree (ob, jump_func->value.member_cst.pfn, true);
> +       lto_output_tree (ob, jump_func->value.member_cst.delta, false);
> +       break;
> +     }
> + }
> + 
> + /* Read in jump function JUMP_FUNC from IB.  */
> + 
> + static void
> + ipa_read_jump_function (struct lto_input_block *ib,
> + 			struct ipa_jump_func *jump_func,
> + 			struct data_in *data_in)
> + {
> +   jump_func->type = (enum jump_func_type) lto_input_uleb128 (ib);
> + 
> +   switch (jump_func->type)
> +     {
> +     case IPA_JF_UNKNOWN:
> +       break;
> +     case IPA_JF_CONST:
> +       jump_func->value.constant = lto_input_tree (ib, data_in);
> +       break;
> +     case IPA_JF_PASS_THROUGH:
> +       jump_func->value.pass_through.operand = lto_input_tree (ib, data_in);
> +       jump_func->value.pass_through.formal_id = lto_input_uleb128 (ib);
> +       jump_func->value.pass_through.operation = (enum tree_code) lto_input_uleb128 (ib);
> +       break;
> +     case IPA_JF_ANCESTOR:
> +       jump_func->value.ancestor.offset = lto_input_uleb128 (ib);
> +       jump_func->value.ancestor.type = lto_input_tree (ib, data_in);
> +       jump_func->value.ancestor.formal_id = lto_input_uleb128 (ib);
> +       break;
> +     case IPA_JF_CONST_MEMBER_PTR:
> +       jump_func->value.member_cst.pfn = lto_input_tree (ib, data_in);
> +       jump_func->value.member_cst.delta = lto_input_tree (ib, data_in);
> +       break;
> +     }
> + }
> + 
> + /* Stream out NODE info to OB.  */
> + 
> + static void
> + ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
> + {
> +   int node_ref;
> +   lto_cgraph_encoder_t encoder;
> +   struct ipa_node_params *info = IPA_NODE_REF (node);
> +   int j;
> +   struct cgraph_edge *e;
> +   struct bitpack_d *bp;
> + 
> +   encoder = ob->decl_state->cgraph_node_encoder;
> +   node_ref = lto_cgraph_encoder_encode (encoder, node);
> +   lto_output_uleb128_stream (ob->main_stream, node_ref);
> + 
> +   /* Note that flags will need to be read in the opposite
> +      order as we are pushing the bitflags into FLAGS.  */
> +   bp = bitpack_create ();
> +   bp_pack_value (bp, info->called_with_var_arguments, 1);
> +   gcc_assert (info->modification_analysis_done || ipa_get_param_count (info) == 0);
> +   gcc_assert (info->uses_analysis_done || ipa_get_param_count (info) == 0);
> +   gcc_assert (!info->node_enqueued);
> +   gcc_assert (!info->ipcp_orig_node);
> +   for (j = 0; j < ipa_get_param_count (info); j++)
> +     {
> +       bp_pack_value (bp, info->params[j].modified, 1);
> +       bp_pack_value (bp, info->params[j].called, 1);
> +     }
> +   lto_output_bitpack (ob->main_stream, bp);
> +   bitpack_delete (bp);
> +   for (e = node->callees; e; e = e->next_callee)
> +     {
> +       struct ipa_edge_args *args = IPA_EDGE_REF (e);
> + 
> +       lto_output_uleb128_stream (ob->main_stream, ipa_get_cs_argument_count (args));
> +       for (j = 0; j < ipa_get_cs_argument_count (args); j++)
> + 	ipa_write_jump_function (ob, ipa_get_ith_jump_func (args, j));
> +     }
> + }
> + 
> + /* Srtream in NODE info from IB.  */
> + 
> + static void
> + ipa_read_node_info (struct lto_input_block *ib, struct cgraph_node *node,
> + 		    struct data_in *data_in)
> + {
> +   struct ipa_node_params *info = IPA_NODE_REF (node);
> +   int k;
> +   struct cgraph_edge *e;
> +   struct bitpack_d *bp;
> + 
> +   ipa_initialize_node_params (node);
> + 
> +   /* Note that the flags must be read in the opposite
> +      order in which they were written (the bitflags were
> +      pushed into FLAGS).  */
> +   bp = lto_input_bitpack (ib);
> +   info->called_with_var_arguments = bp_unpack_value (bp, 1);
> +   if (ipa_get_param_count (info) != 0)
> +     {
> +       info->modification_analysis_done = true;
> +       info->uses_analysis_done = true;
> +     }
> +   info->node_enqueued = false;
> +   for (k = 0; k < ipa_get_param_count (info); k++)
> +     {
> +       info->params[k].modified = bp_unpack_value (bp, 1);
> +       info->params[k].called = bp_unpack_value (bp, 1);
> +     }
> +   bitpack_delete (bp);
> +   for (e = node->callees; e; e = e->next_callee)
> +     {
> +       struct ipa_edge_args *args = IPA_EDGE_REF (e);
> +       int count = lto_input_uleb128 (ib);
> + 
> +       if (VEC_length (ipa_edge_args_t, ipa_edge_args_vector)
> + 	  <= (unsigned) cgraph_edge_max_uid)
> + 	VEC_safe_grow_cleared (ipa_edge_args_t, gc,
> + 			       ipa_edge_args_vector, cgraph_edge_max_uid + 1);
> +       ipa_set_cs_argument_count (args, count);
> +       if (!count)
> + 	continue;
> + 
> +       args->jump_functions = GGC_CNEWVEC (struct ipa_jump_func,
> + 				          ipa_get_cs_argument_count (args));
> +       for (k = 0; k < ipa_get_cs_argument_count (args); k++)
> + 	ipa_read_jump_function (ib, ipa_get_ith_jump_func (args, k), data_in);
> +     }
> + }
> + 
> + /* Write jump functions for nodes in SET.  */
> + 
> + void
> + ipa_prop_write_jump_functions (cgraph_node_set set)
> + {
> +   struct cgraph_node *node;
> +   struct output_block *ob = create_output_block (LTO_section_jump_functions);
> +   unsigned int count = 0;
> +   cgraph_node_set_iterator csi;
> + 
> +   ob->cgraph_node = NULL;
> + 
> +   for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi))
> +     {
> +       node = csi_node (csi);
> +       if (node->analyzed && IPA_NODE_REF (node) != NULL)
> + 	count++;
> +     }
> + 
> +   lto_output_uleb128_stream (ob->main_stream, count);
> + 
> +   /* Process all of the functions.  */
> +   for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi))
> +     {
> +       node = csi_node (csi);
> +       if (node->analyzed && IPA_NODE_REF (node) != NULL)
> +         ipa_write_node_info (ob, node);
> +     }
> +   lto_output_1_stream (ob->main_stream, 0);
> +   produce_asm (ob, NULL);
> +   destroy_output_block (ob);
> + }
> + 
> + /* Read section in file FILE_DATA of length LEN with data DATA.  */
> + 
> + static void
> + ipa_prop_read_section (struct lto_file_decl_data *file_data, const char *data,
> + 		       size_t len)
> + {
> +   const struct lto_function_header *header =
> +     (const struct lto_function_header *) data;
> +   const int32_t cfg_offset = sizeof (struct lto_function_header);
> +   const int32_t main_offset = cfg_offset + header->cfg_size;
> +   const int32_t string_offset = main_offset + header->main_size;
> +   struct data_in *data_in;
> +   struct lto_input_block ib_main;
> +   unsigned int i;
> +   unsigned int count;
> + 
> +   LTO_INIT_INPUT_BLOCK (ib_main, (const char *) data + main_offset, 0,
> + 			header->main_size);
> + 
> +   data_in =
> +     lto_data_in_create (file_data, (const char *) data + string_offset,
> + 			header->string_size, NULL);
> +   count = lto_input_uleb128 (&ib_main);
> + 
> +   for (i = 0; i < count; i++)
> +     {
> +       unsigned int index;
> +       struct cgraph_node *node;
> +       lto_cgraph_encoder_t encoder;
> + 
> +       index = lto_input_uleb128 (&ib_main);
> +       encoder = file_data->cgraph_node_encoder;
> +       node = lto_cgraph_encoder_deref (encoder, index);
> +       ipa_read_node_info (&ib_main, node, data_in);
> +     }
> +   lto_free_section_data (file_data, LTO_section_jump_functions, NULL, data,
> + 			 len);
> +   lto_data_in_delete (data_in);
> + }
> + 
> + /* Read ipcp jump functions.  */
> + 
> + void
> + ipa_prop_read_jump_functions (void)
> + {
> +   struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
> +   struct lto_file_decl_data *file_data;
> +   unsigned int j = 0;
> + 
> +   ipa_check_create_node_params ();
> +   ipa_check_create_edge_args ();
> +   ipa_register_cgraph_hooks ();
> + 
> +   while ((file_data = file_data_vec[j++]))
> +     {
> +       size_t len;
> +       const char *data = lto_get_section_data (file_data, LTO_section_jump_functions, NULL, &len);
> + 
> +       if (data)
> +         ipa_prop_read_section (file_data, data, len);
> +     }
> + }
> + 
> + /* After merging units, we can get mismatch in argument counts. 
> +    Also decl merging might've rendered parameter lists obsolette.
> +    Also compute called_with_variable_arg info.  */
> + 
> + void
> + ipa_update_after_lto_read (void)
> + {
> +   struct cgraph_node *node;
> +   struct cgraph_edge *cs;
> + 
> +   for (node = cgraph_nodes; node; node = node->next)
> +     {
> +       if (!node->analyzed)
> + 	continue;
> +       ipa_populate_param_decls (node, IPA_NODE_REF (node));
> +       for (cs = node->callees; cs; cs = cs->next_callee)
> + 	{
> + 	  if (ipa_get_cs_argument_count (IPA_EDGE_REF (cs))
> + 	      != ipa_get_param_count (IPA_NODE_REF (cs->callee)))
> + 	    ipa_set_called_with_variable_arg (IPA_NODE_REF (cs->callee));
> + 	}
> +     }
> + }
> Index: ipa-prop.h
> ===================================================================
> *** ipa-prop.h	(revision 152974)
> --- ipa-prop.h	(working copy)
> *************** enum ipa_lattice_type
> *** 72,78 ****
>   
>   /* Structure holding data required to describe a pass-through jump function.  */
>   
> ! struct ipa_pass_through_data
>   {
>     /* If an operation is to be performed on the original parameter, this is the
>        second (constant) operand.  */
> --- 72,78 ----
>   
>   /* Structure holding data required to describe a pass-through jump function.  */
>   
> ! struct GTY(()) ipa_pass_through_data
>   {
>     /* If an operation is to be performed on the original parameter, this is the
>        second (constant) operand.  */
> *************** struct ipa_pass_through_data
> *** 89,95 ****
>   /* Structure holding data required to describe and ancestor pass throu
>      funkci.  */
>   
> ! struct ipa_ancestor_jf_data
>   {
>     /* Offset of the field representing the ancestor.  */
>     HOST_WIDE_INT offset;
> --- 89,95 ----
>   /* Structure holding data required to describe and ancestor pass throu
>      funkci.  */
>   
> ! struct GTY(()) ipa_ancestor_jf_data
>   {
>     /* Offset of the field representing the ancestor.  */
>     HOST_WIDE_INT offset;
> *************** struct ipa_ancestor_jf_data
> *** 101,130 ****
>   
>   /* Structure holding a C++ member pointer constant.  Holds a pointer to the
>      method and delta offset.  */
> ! struct ipa_member_ptr_cst
>   {
>     tree pfn;
>     tree delta;
>   };
>   
> - /* Represents a value of a jump function.  pass_through is used only in jump
> -    function context.  constant represents the actual constant in constant jump
> -    functions and member_cst holds constant c++ member functions.  */
> - union jump_func_value
> - {
> -   tree constant;
> -   struct ipa_pass_through_data pass_through;
> -   struct ipa_ancestor_jf_data ancestor;
> -   struct ipa_member_ptr_cst member_cst;
> - };
> - 
>   /* A jump function for a callsite represents the values passed as actual
>      arguments of the callsite. See enum jump_func_type for the various
>      types of jump functions supported.  */
> ! struct ipa_jump_func
>   {
>     enum jump_func_type type;
> !   union jump_func_value value;
>   };
>   
>   /* All formal parameters in the program have a cval computed by
> --- 101,128 ----
>   
>   /* Structure holding a C++ member pointer constant.  Holds a pointer to the
>      method and delta offset.  */
> ! struct GTY(()) ipa_member_ptr_cst
>   {
>     tree pfn;
>     tree delta;
>   };
>   
>   /* A jump function for a callsite represents the values passed as actual
>      arguments of the callsite. See enum jump_func_type for the various
>      types of jump functions supported.  */
> ! struct GTY (()) ipa_jump_func
>   {
>     enum jump_func_type type;
> !   /* Represents a value of a jump function.  pass_through is used only in jump
> !      function context.  constant represents the actual constant in constant jump
> !      functions and member_cst holds constant c++ member functions.  */
> !   union jump_func_value
> !   {
> !     tree GTY ((tag ("IPA_JF_CONST"))) constant;
> !     struct ipa_pass_through_data GTY ((tag ("IPA_JF_PASS_THROUGH"))) pass_through;
> !     struct ipa_ancestor_jf_data GTY ((tag ("IPA_JF_ANCESTOR"))) ancestor;
> !     struct ipa_member_ptr_cst GTY ((tag ("IPA_JF_CONST_MEMBER_PTR"))) member_cst;
> !   } GTY ((desc ("%1.type"))) value;
>   };
>   
>   /* All formal parameters in the program have a cval computed by
> *************** ipa_is_called_with_var_arguments (struct
> *** 280,294 ****
>   /* ipa_edge_args stores information related to a callsite and particularly
>      its arguments. It is pointed to by a field in the
>      callsite's corresponding cgraph_edge.  */
> ! struct ipa_edge_args
>   {
>     /* Number of actual arguments in this callsite.  When set to 0,
>        this callsite's parameters would not be analyzed by the different
>        stages of IPA CP.  */
>     int argument_count;
>     /* Array of the callsite's jump function of each parameter.  */
> !   struct ipa_jump_func *jump_functions;
> ! };
>   
>   /* ipa_edge_args access functions.  Please use these to access fields that
>      are or will be shared among various passes.  */
> --- 278,292 ----
>   /* ipa_edge_args stores information related to a callsite and particularly
>      its arguments. It is pointed to by a field in the
>      callsite's corresponding cgraph_edge.  */
> ! typedef struct GTY(()) ipa_edge_args
>   {
>     /* Number of actual arguments in this callsite.  When set to 0,
>        this callsite's parameters would not be analyzed by the different
>        stages of IPA CP.  */
>     int argument_count;
>     /* Array of the callsite's jump function of each parameter.  */
> !   struct ipa_jump_func GTY ((length ("%h.argument_count"))) *jump_functions;
> ! } ipa_edge_args_t;
>   
>   /* ipa_edge_args access functions.  Please use these to access fields that
>      are or will be shared among various passes.  */
> *************** ipa_get_ith_jump_func (struct ipa_edge_a
> *** 321,338 ****
>   
>   /* Vectors need to have typedefs of structures.  */
>   typedef struct ipa_node_params ipa_node_params_t;
> - typedef struct ipa_edge_args ipa_edge_args_t;
>   
>   /* Types of vectors holding the infos.  */
>   DEF_VEC_O (ipa_node_params_t);
>   DEF_VEC_ALLOC_O (ipa_node_params_t, heap);
>   DEF_VEC_O (ipa_edge_args_t);
> ! DEF_VEC_ALLOC_O (ipa_edge_args_t, heap);
>   
>   /* Vector where the parameter infos are actually stored. */
>   extern VEC (ipa_node_params_t, heap) *ipa_node_params_vector;
>   /* Vector where the parameter infos are actually stored. */
> ! extern VEC (ipa_edge_args_t, heap) *ipa_edge_args_vector;
>   
>   /* Return the associated parameter/argument info corresponding to the given
>      node/edge.  */
> --- 319,335 ----
>   
>   /* Vectors need to have typedefs of structures.  */
>   typedef struct ipa_node_params ipa_node_params_t;
>   
>   /* Types of vectors holding the infos.  */
>   DEF_VEC_O (ipa_node_params_t);
>   DEF_VEC_ALLOC_O (ipa_node_params_t, heap);
>   DEF_VEC_O (ipa_edge_args_t);
> ! DEF_VEC_ALLOC_O (ipa_edge_args_t, gc);
>   
>   /* Vector where the parameter infos are actually stored. */
>   extern VEC (ipa_node_params_t, heap) *ipa_node_params_vector;
>   /* Vector where the parameter infos are actually stored. */
> ! extern GTY(()) VEC (ipa_edge_args_t, gc) *ipa_edge_args_vector;
>   
>   /* Return the associated parameter/argument info corresponding to the given
>      node/edge.  */
> *************** static inline void
> *** 378,389 ****
>   ipa_check_create_edge_args (void)
>   {
>     if (!ipa_edge_args_vector)
> !     ipa_edge_args_vector = VEC_alloc (ipa_edge_args_t, heap,
>   				      cgraph_edge_max_uid);
>   
>     if (VEC_length (ipa_edge_args_t, ipa_edge_args_vector)
>         <=  (unsigned) cgraph_edge_max_uid)
> !     VEC_safe_grow_cleared (ipa_edge_args_t, heap, ipa_edge_args_vector,
>   			   cgraph_edge_max_uid + 1);
>   }
>   
> --- 375,386 ----
>   ipa_check_create_edge_args (void)
>   {
>     if (!ipa_edge_args_vector)
> !     ipa_edge_args_vector = VEC_alloc (ipa_edge_args_t, gc,
>   				      cgraph_edge_max_uid);
>   
>     if (VEC_length (ipa_edge_args_t, ipa_edge_args_vector)
>         <=  (unsigned) cgraph_edge_max_uid)
> !     VEC_safe_grow_cleared (ipa_edge_args_t, gc, ipa_edge_args_vector,
>   			   cgraph_edge_max_uid + 1);
>   }
>   
> *************** ipa_parm_adjustment_vec ipa_combine_adju
> *** 508,513 ****
> --- 505,514 ----
>   						 ipa_parm_adjustment_vec);
>   void ipa_dump_param_adjustments (FILE *, ipa_parm_adjustment_vec, tree);
>   
> + void ipa_prop_write_jump_functions (cgraph_node_set set);
> + void ipa_prop_read_jump_functions (void);
> + void ipa_update_after_lto_read (void);
> + 
>   /* From tree-sra.c:  */
>   bool build_ref_for_offset (tree *, tree, HOST_WIDE_INT, tree, bool);
>   
> Index: Makefile.in
> ===================================================================
> *** Makefile.in	(revision 152974)
> --- Makefile.in	(working copy)
> *************** GTFILES = $(CPP_ID_DATA_H) $(srcdir)/inp
> *** 3585,3590 ****
> --- 3585,3591 ----
>     $(srcdir)/tree-ssa-structalias.c \
>     $(srcdir)/lto-symtab.c \
>     $(srcdir)/tree-ssa-alias.h \
> +   $(srcdir)/ipa-prop.h \
>     @all_gtfiles@
>   
>   # Compute the list of GT header files from the corresponding C sources,
> Index: passes.c
> ===================================================================
> *** passes.c	(revision 152974)
> --- passes.c	(working copy)
> *************** ipa_write_summaries_1 (cgraph_node_set s
> *** 1618,1624 ****
>     struct lto_out_decl_state *state = lto_new_out_decl_state ();
>     lto_push_out_decl_state (state);
>   
> !   ipa_write_summaries_2 (all_regular_ipa_passes, set, state);
>     ipa_write_summaries_2 (all_lto_gen_passes, set, state);
>   
>     gcc_assert (lto_get_out_decl_state () == state);
> --- 1618,1625 ----
>     struct lto_out_decl_state *state = lto_new_out_decl_state ();
>     lto_push_out_decl_state (state);
>   
> !   if (!flag_wpa)
> !     ipa_write_summaries_2 (all_regular_ipa_passes, set, state);
>     ipa_write_summaries_2 (all_lto_gen_passes, set, state);
>   
>     gcc_assert (lto_get_out_decl_state () == state);
> *************** ipa_read_summaries_1 (struct opt_pass *p
> *** 1712,1718 ****
>   void
>   ipa_read_summaries (void)
>   {
> !   ipa_read_summaries_1 (all_regular_ipa_passes);
>     ipa_read_summaries_1 (all_lto_gen_passes);
>   }
>   
> --- 1713,1720 ----
>   void
>   ipa_read_summaries (void)
>   {
> !   if (!flag_ltrans)
> !     ipa_read_summaries_1 (all_regular_ipa_passes);
>     ipa_read_summaries_1 (all_lto_gen_passes);
>   }
>   
> Index: lto-streamer.c
> ===================================================================
> *** lto-streamer.c	(revision 152974)
> --- lto-streamer.c	(working copy)
> *************** lto_get_section_name (int section_type, 
> *** 157,162 ****
> --- 157,165 ----
>       case LTO_section_cgraph:
>         return concat (LTO_SECTION_NAME_PREFIX, ".cgraph", NULL);
>   
> +     case LTO_section_jump_functions:
> +       return concat (LTO_SECTION_NAME_PREFIX, ".jmpfuncs", NULL);
> + 
>       case LTO_section_ipa_pure_const:
>         return concat (LTO_SECTION_NAME_PREFIX, ".pureconst", NULL);
>   
> Index: lto-streamer.h
> ===================================================================
> *** lto-streamer.h	(revision 152974)
> --- lto-streamer.h	(working copy)
> *************** enum lto_section_type
> *** 256,261 ****
> --- 256,262 ----
>     LTO_section_function_body,
>     LTO_section_static_initializer,
>     LTO_section_cgraph,
> +   LTO_section_jump_functions,
>     LTO_section_ipa_pure_const,
>     LTO_section_ipa_reference,
>     LTO_section_symtab,
> *************** extern struct output_block *create_outpu
> *** 827,832 ****
> --- 828,834 ----
>   extern void destroy_output_block (struct output_block *);
>   extern void lto_output_tree (struct output_block *, tree, bool);
>   extern void lto_output_bitpack (struct lto_output_stream *, struct bitpack_d *);
> + extern void produce_asm (struct output_block *ob, tree fn);
>   
>   
>   /* In lto-cgraph.c  */
> 
> 

-- 
Richard Guenther <rguenther@suse.de>
Novell / SUSE Labs
SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746 - GF: Markus Rex


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