Hi, this patch makes lto-cgraph to use the new output_enum/var_len functions in some obvious places where it fits. It also fixes a problem where resolution was streamed in wrong order that is maked by our current bitpack implementation.
One problem is streaming resolution enums. I am not sure I want to add the last argument into ld-plugin-api header, so instead I just keep constant about last code known to GCC. As plugin API will envolve we will have more resoltion types, but GCC should always get only those it knows about. Bootstrapped/regtested x86_64-linux, OK? Honza * cgraph.h (cgraph_inline_failed_t): Give enum a name * lto-cgraph.c (LDPR_NUM_KNOWN): New macro. (LTO_cgraph_tags): Add LTO_cgraph_last_tag. (lto_output_edge): Use output_enum and var_len_unsigned. (lto_output_varpool_node): Likewise. (input_overwrite_node): Do not take resolution parameter; extract it from a bitpack. (input_node): Do not read resolution; use input_enum and var_len_unsigned. (input_varpool_node): Likewise. (input_edge): Likewise. (input_cgraph_1): Likewise. Index: cgraph.h =================================================================== *** cgraph.h (revision 174393) --- cgraph.h (working copy) *************** typedef struct *** 304,310 **** #define DEFCIFCODE(code, string) CIF_ ## code, /* Reasons for inlining failures. */ ! typedef enum { #include "cif-code.def" CIF_N_REASONS } cgraph_inline_failed_t; --- 304,310 ---- #define DEFCIFCODE(code, string) CIF_ ## code, /* Reasons for inlining failures. */ ! typedef enum cgraph_inline_failed_enum { #include "cif-code.def" CIF_N_REASONS } cgraph_inline_failed_t; Index: lto-cgraph.c =================================================================== *** lto-cgraph.c (revision 174393) --- lto-cgraph.c (working copy) *************** static void output_varpool (cgraph_node_ *** 49,54 **** --- 49,56 ---- static void output_cgraph_opt_summary (cgraph_node_set set); static void input_cgraph_opt_summary (VEC (cgraph_node_ptr, heap) * nodes); + /* Number of LDPR values known to GCC. */ + #define LDPR_NUM_KNOWN (LDPR_RESOLVED_DYN + 1) /* Cgraph streaming is organized as set of record whose type is indicated by a tag. */ *************** enum LTO_cgraph_tags *** 62,68 **** LTO_cgraph_analyzed_node, /* Cgraph edges. */ LTO_cgraph_edge, ! LTO_cgraph_indirect_edge }; /* Create a new cgraph encoder. */ --- 63,70 ---- LTO_cgraph_analyzed_node, /* Cgraph edges. */ LTO_cgraph_edge, ! LTO_cgraph_indirect_edge, ! LTO_cgraph_last_tag }; /* Create a new cgraph encoder. */ *************** lto_output_edge (struct lto_simple_outpu *** 262,270 **** struct bitpack_d bp; if (edge->indirect_unknown_callee) ! lto_output_uleb128_stream (ob->main_stream, LTO_cgraph_indirect_edge); else ! lto_output_uleb128_stream (ob->main_stream, LTO_cgraph_edge); ref = lto_cgraph_encoder_lookup (encoder, edge->caller); gcc_assert (ref != LCC_NOT_FOUND); --- 264,274 ---- struct bitpack_d bp; if (edge->indirect_unknown_callee) ! lto_output_enum (ob->main_stream, LTO_cgraph_tags, LTO_cgraph_last_tag, ! LTO_cgraph_indirect_edge); else ! lto_output_enum (ob->main_stream, LTO_cgraph_tags, LTO_cgraph_last_tag, ! LTO_cgraph_edge); ref = lto_cgraph_encoder_lookup (encoder, edge->caller); gcc_assert (ref != LCC_NOT_FOUND); *************** lto_output_edge (struct lto_simple_outpu *** 282,290 **** bp = bitpack_create (ob->main_stream); uid = (!gimple_has_body_p (edge->caller->decl) ? edge->lto_stmt_uid : gimple_uid (edge->call_stmt)); ! bp_pack_value (&bp, uid, HOST_BITS_PER_INT); ! bp_pack_value (&bp, edge->inline_failed, HOST_BITS_PER_INT); ! bp_pack_value (&bp, edge->frequency, HOST_BITS_PER_INT); bp_pack_value (&bp, edge->indirect_inlining_edge, 1); bp_pack_value (&bp, edge->call_stmt_cannot_inline_p, 1); bp_pack_value (&bp, edge->can_throw_external, 1); --- 286,295 ---- bp = bitpack_create (ob->main_stream); uid = (!gimple_has_body_p (edge->caller->decl) ? edge->lto_stmt_uid : gimple_uid (edge->call_stmt)); ! bp_pack_enum (&bp, cgraph_inline_failed_enum, ! CIF_N_REASONS, edge->inline_failed); ! bp_pack_var_len_unsigned (&bp, uid); ! bp_pack_var_len_unsigned (&bp, edge->frequency); bp_pack_value (&bp, edge->indirect_inlining_edge, 1); bp_pack_value (&bp, edge->call_stmt_cannot_inline_p, 1); bp_pack_value (&bp, edge->can_throw_external, 1); *************** lto_output_node (struct lto_simple_outpu *** 415,421 **** else tag = LTO_cgraph_unavail_node; ! lto_output_uleb128_stream (ob->main_stream, tag); /* In WPA mode, we only output part of the call-graph. Also, we fake cgraph node attributes. There are two cases that we care. --- 420,426 ---- else tag = LTO_cgraph_unavail_node; ! lto_output_enum (ob->main_stream, LTO_cgraph_tags, LTO_cgraph_last_tag, tag); /* In WPA mode, we only output part of the call-graph. Also, we fake cgraph node attributes. There are two cases that we care. *************** lto_output_node (struct lto_simple_outpu *** 503,510 **** bp_pack_value (&bp, node->only_called_at_startup, 1); bp_pack_value (&bp, node->only_called_at_exit, 1); bp_pack_value (&bp, node->thunk.thunk_p && !boundary_p, 1); lto_output_bitpack (&bp); - lto_output_uleb128_stream (ob->main_stream, node->resolution); if (node->thunk.thunk_p && !boundary_p) { --- 508,516 ---- bp_pack_value (&bp, node->only_called_at_startup, 1); bp_pack_value (&bp, node->only_called_at_exit, 1); bp_pack_value (&bp, node->thunk.thunk_p && !boundary_p, 1); + bp_pack_enum (&bp, ld_plugin_symbol_resolution, + LDPR_NUM_KNOWN, node->resolution); lto_output_bitpack (&bp); if (node->thunk.thunk_p && !boundary_p) { *************** lto_output_node (struct lto_simple_outpu *** 534,540 **** lto_output_fn_decl_index (ob->decl_state, ob->main_stream, alias->thunk.alias); gcc_assert (cgraph_get_node (alias->thunk.alias) == node); ! lto_output_uleb128_stream (ob->main_stream, alias->resolution); alias = alias->previous; } while (alias); --- 540,547 ---- lto_output_fn_decl_index (ob->decl_state, ob->main_stream, alias->thunk.alias); gcc_assert (cgraph_get_node (alias->thunk.alias) == node); ! lto_output_enum (ob->main_stream, ld_plugin_symbol_resolution, ! LDPR_NUM_KNOWN, alias->resolution); alias = alias->previous; } while (alias); *************** lto_output_varpool_node (struct lto_simp *** 595,601 **** else ref = LCC_NOT_FOUND; lto_output_sleb128_stream (ob->main_stream, ref); ! lto_output_uleb128_stream (ob->main_stream, node->resolution); if (count) { --- 602,609 ---- else ref = LCC_NOT_FOUND; lto_output_sleb128_stream (ob->main_stream, ref); ! lto_output_enum (ob->main_stream, ld_plugin_symbol_resolution, ! LDPR_NUM_KNOWN, node->resolution); if (count) { *************** lto_output_varpool_node (struct lto_simp *** 603,609 **** for (alias = node->extra_name; alias; alias = alias->next) { lto_output_var_decl_index (ob->decl_state, ob->main_stream, alias->decl); ! lto_output_uleb128_stream (ob->main_stream, alias->resolution); } } } --- 611,618 ---- for (alias = node->extra_name; alias; alias = alias->next) { lto_output_var_decl_index (ob->decl_state, ob->main_stream, alias->decl); ! lto_output_enum (ob->main_stream, ld_plugin_symbol_resolution, ! LDPR_NUM_KNOWN, alias->resolution); } } } *************** static void *** 909,916 **** input_overwrite_node (struct lto_file_decl_data *file_data, struct cgraph_node *node, enum LTO_cgraph_tags tag, ! struct bitpack_d *bp, ! enum ld_plugin_symbol_resolution resolution) { node->aux = (void *) tag; node->local.lto_file_data = file_data; --- 918,924 ---- input_overwrite_node (struct lto_file_decl_data *file_data, struct cgraph_node *node, enum LTO_cgraph_tags tag, ! struct bitpack_d *bp) { node->aux = (void *) tag; node->local.lto_file_data = file_data; *************** input_overwrite_node (struct lto_file_de *** 946,952 **** node->only_called_at_startup = bp_unpack_value (bp, 1); node->only_called_at_exit = bp_unpack_value (bp, 1); node->thunk.thunk_p = bp_unpack_value (bp, 1); ! node->resolution = resolution; } /* Output the part of the cgraph in SET. */ --- 954,961 ---- node->only_called_at_startup = bp_unpack_value (bp, 1); node->only_called_at_exit = bp_unpack_value (bp, 1); node->thunk.thunk_p = bp_unpack_value (bp, 1); ! node->resolution = bp_unpack_enum (bp, ld_plugin_symbol_resolution, ! LDPR_NUM_KNOWN); } /* Output the part of the cgraph in SET. */ *************** input_node (struct lto_file_decl_data *f *** 989,995 **** int ref = LCC_NOT_FOUND, ref2 = LCC_NOT_FOUND; unsigned long same_body_count = 0; int clone_ref; - enum ld_plugin_symbol_resolution resolution; clone_ref = lto_input_sleb128 (ib); --- 998,1003 ---- *************** input_node (struct lto_file_decl_data *f *** 1021,1028 **** "node %d", node->uid); bp = lto_input_bitpack (ib); ! resolution = (enum ld_plugin_symbol_resolution)lto_input_uleb128 (ib); ! input_overwrite_node (file_data, node, tag, &bp, resolution); /* Store a reference for now, and fix up later to be a pointer. */ node->global.inlined_to = (cgraph_node_ptr) (intptr_t) ref; --- 1029,1035 ---- "node %d", node->uid); bp = lto_input_bitpack (ib); ! input_overwrite_node (file_data, node, tag, &bp); /* Store a reference for now, and fix up later to be a pointer. */ node->global.inlined_to = (cgraph_node_ptr) (intptr_t) ref; *************** input_node (struct lto_file_decl_data *f *** 1058,1064 **** real_alias = lto_file_decl_data_get_fn_decl (file_data, decl_index); alias = cgraph_same_body_alias (node, alias_decl, real_alias); gcc_assert (alias); ! alias->resolution = (enum ld_plugin_symbol_resolution)lto_input_uleb128 (ib); } return node; } --- 1065,1072 ---- real_alias = lto_file_decl_data_get_fn_decl (file_data, decl_index); alias = cgraph_same_body_alias (node, alias_decl, real_alias); gcc_assert (alias); ! alias->resolution = lto_input_enum (ib, ld_plugin_symbol_resolution, ! LDPR_NUM_KNOWN); } return node; } *************** input_varpool_node (struct lto_file_decl *** 1102,1108 **** ref = lto_input_sleb128 (ib); /* Store a reference for now, and fix up later to be a pointer. */ node->same_comdat_group = (struct varpool_node *) (intptr_t) ref; ! node->resolution = (enum ld_plugin_symbol_resolution)lto_input_uleb128 (ib); if (aliases_p) { count = lto_input_uleb128 (ib); --- 1110,1117 ---- ref = lto_input_sleb128 (ib); /* Store a reference for now, and fix up later to be a pointer. */ node->same_comdat_group = (struct varpool_node *) (intptr_t) ref; ! node->resolution = lto_input_enum (ib, ld_plugin_symbol_resolution, ! LDPR_NUM_KNOWN); if (aliases_p) { count = lto_input_uleb128 (ib); *************** input_varpool_node (struct lto_file_decl *** 1112,1118 **** lto_input_uleb128 (ib)); struct varpool_node *alias; alias = varpool_extra_name_alias (decl, var_decl); ! alias->resolution = (enum ld_plugin_symbol_resolution)lto_input_uleb128 (ib); } } return node; --- 1121,1128 ---- lto_input_uleb128 (ib)); struct varpool_node *alias; alias = varpool_extra_name_alias (decl, var_decl); ! alias->resolution = lto_input_enum (ib, ld_plugin_symbol_resolution, ! LDPR_NUM_KNOWN); } } return node; *************** input_edge (struct lto_input_block *ib, *** 1179,1188 **** count = (gcov_type) lto_input_sleb128 (ib); bp = lto_input_bitpack (ib); ! stmt_id = (unsigned int) bp_unpack_value (&bp, HOST_BITS_PER_INT); ! inline_failed = (cgraph_inline_failed_t) bp_unpack_value (&bp, ! HOST_BITS_PER_INT); ! freq = (int) bp_unpack_value (&bp, HOST_BITS_PER_INT); if (indirect) edge = cgraph_create_indirect_edge (caller, NULL, 0, count, freq); --- 1189,1197 ---- count = (gcov_type) lto_input_sleb128 (ib); bp = lto_input_bitpack (ib); ! inline_failed = bp_unpack_enum (&bp, cgraph_inline_failed_enum, CIF_N_REASONS); ! stmt_id = bp_unpack_var_len_unsigned (&bp); ! freq = (int) bp_unpack_var_len_unsigned (&bp); if (indirect) edge = cgraph_create_indirect_edge (caller, NULL, 0, count, freq); *************** input_cgraph_1 (struct lto_file_decl_dat *** 1225,1231 **** unsigned i; unsigned HOST_WIDE_INT len; ! tag = (enum LTO_cgraph_tags) lto_input_uleb128 (ib); while (tag) { if (tag == LTO_cgraph_edge) --- 1234,1240 ---- unsigned i; unsigned HOST_WIDE_INT len; ! tag = lto_input_enum (ib, LTO_cgraph_tags, LTO_cgraph_last_tag); while (tag) { if (tag == LTO_cgraph_edge) *************** input_cgraph_1 (struct lto_file_decl_dat *** 1241,1247 **** lto_cgraph_encoder_encode (file_data->cgraph_node_encoder, node); } ! tag = (enum LTO_cgraph_tags) lto_input_uleb128 (ib); } /* Input toplevel asms. */ --- 1250,1256 ---- lto_cgraph_encoder_encode (file_data->cgraph_node_encoder, node); } ! tag = lto_input_enum (ib, LTO_cgraph_tags, LTO_cgraph_last_tag); } /* Input toplevel asms. */