+2009-11-18 Martin Jambor <mjambor@suse.cz>
+
+ * ipa-prop.h (struct ipa_param_call_note): New field lto_stmt_uid.
+ (lto_ipa_fixup_call_notes): Declare.
+ * ipa-prop.c (ipa_note_param_call): Store gimple uid.
+ (update_call_notes_after_inlining): Copy call stmt uid to the new
+ edge.
+ (ipa_write_param_call_note): New function.
+ (ipa_read_param_call_note): New function
+ (ipa_write_node_info): Write also param call notes. Removed a bogus
+ comment, reformatted to fit 80 columns.
+ (ipa_read_node_info): Read also param call notes. Removed a bogus
+ comment. Remove ipa_edge_args_vector growth.
+ (lto_ipa_fixup_call_notes): New function.
+ * ipa-cp.c (pass_ipa_cp): Add stmt_fixup hook.
+ * ipa-inline.c (cgraph_mark_inline_edge): Perform indirect
+ inlining regardless of flag_wpa.
+ (cgraph_decide_inlining_of_small_functions): Likewise.
+ (cgraph_decide_inlining): Likewise.
+ (inline_read_summary): Likewise.
+
2009-11-18 Jan Hubicka <jh@suse.cz>
* predict.c (compute_function_frequency): Export.
overall_size -= orig_size;
ncalls_inlined++;
- if (flag_indirect_inlining && !flag_wpa)
+ if (flag_indirect_inlining)
return ipa_propagate_indirect_call_infos (curr, new_edges);
else
return false;
int min_size, max_size;
VEC (cgraph_edge_p, heap) *new_indirect_edges = NULL;
- if (flag_indirect_inlining && !flag_wpa)
+ if (flag_indirect_inlining)
new_indirect_edges = VEC_alloc (cgraph_edge_p, heap, 8);
if (dump_file)
if (where->global.inlined_to)
where = where->global.inlined_to;
if (!cgraph_decide_recursive_inlining (where,
- flag_indirect_inlining && !flag_wpa
+ flag_indirect_inlining
? &new_indirect_edges : NULL))
continue;
- if (flag_indirect_inlining && !flag_wpa)
+ if (flag_indirect_inlining)
add_new_edges_to_heap (heap, new_indirect_edges);
update_callee_keys (heap, where, updated_nodes);
}
}
callee = edge->callee;
cgraph_mark_inline_edge (edge, true, &new_indirect_edges);
- if (flag_indirect_inlining && !flag_wpa)
+ if (flag_indirect_inlining)
add_new_edges_to_heap (heap, new_indirect_edges);
update_callee_keys (heap, callee, updated_nodes);
int initial_size = 0;
cgraph_remove_function_insertion_hook (function_insertion_hook_holder);
- if (in_lto_p && flag_indirect_inlining && !flag_wpa)
+ if (in_lto_p && flag_indirect_inlining)
ipa_update_after_lto_read ();
max_count = 0;
}
/* Free ipa-prop structures if they are no longer needed. */
- if (flag_indirect_inlining && !flag_wpa)
+ if (flag_indirect_inlining)
free_all_ipa_structures_after_iinln ();
if (dump_file)
static void
inline_read_summary (void)
{
- if (flag_indirect_inlining && !flag_wpa)
+ if (flag_indirect_inlining)
{
ipa_register_cgraph_hooks ();
if (!flag_ipa_cp)
inline_write_summary, /* write_summary */
inline_read_summary, /* read_summary */
NULL, /* function_read_summary */
- NULL, /* stmt_fixup */
+ lto_ipa_fixup_call_notes, /* stmt_fixup */
0, /* TODOs */
inline_transform, /* function_transform */
NULL, /* variable_transform */
note = XCNEW (struct ipa_param_call_note);
note->formal_id = formal_id;
note->stmt = stmt;
+ note->lto_stmt_uid = gimple_uid (stmt);
note->count = bb->count;
note->frequency = compute_call_stmt_bb_frequency (current_function_decl, bb);
new_indirect_edge = cgraph_create_edge (node, callee, nt->stmt,
nt->count, nt->frequency,
nt->loop_nest);
+ new_indirect_edge->lto_stmt_uid = nt->lto_stmt_uid;
new_indirect_edge->indirect_call = 1;
ipa_check_create_edge_args ();
if (new_edges)
}
}
+/* Stream out a parameter call note. */
+
+static void
+ipa_write_param_call_note (struct output_block *ob,
+ struct ipa_param_call_note *note)
+{
+ gcc_assert (!note->processed);
+ lto_output_uleb128_stream (ob->main_stream, gimple_uid (note->stmt));
+ lto_output_sleb128_stream (ob->main_stream, note->formal_id);
+ lto_output_sleb128_stream (ob->main_stream, note->count);
+ lto_output_sleb128_stream (ob->main_stream, note->frequency);
+ lto_output_sleb128_stream (ob->main_stream, note->loop_nest);
+}
+
+/* Read in a parameter call note. */
+
+static void
+ipa_read_param_call_note (struct lto_input_block *ib,
+ struct ipa_node_params *info)
+
+{
+ struct ipa_param_call_note *note = XCNEW (struct ipa_param_call_note);
+
+ note->lto_stmt_uid = (unsigned int) lto_input_uleb128 (ib);
+ note->formal_id = (int) lto_input_sleb128 (ib);
+ note->count = (gcov_type) lto_input_sleb128 (ib);
+ note->frequency = (int) lto_input_sleb128 (ib);
+ note->loop_nest = (int) lto_input_sleb128 (ib);
+
+ note->next = info->param_calls;
+ info->param_calls = note;
+}
+
+
/* Stream out NODE info to OB. */
static void
int j;
struct cgraph_edge *e;
struct bitpack_d *bp;
+ int note_count;
+ struct ipa_param_call_note *note;
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->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);
{
struct ipa_edge_args *args = IPA_EDGE_REF (e);
- lto_output_uleb128_stream (ob->main_stream, ipa_get_cs_argument_count (args));
+ 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));
}
+
+ for (note = info->param_calls; note; note = note->next)
+ note_count++;
+ lto_output_uleb128_stream (ob->main_stream, note_count);
+ for (note = info->param_calls; note; note = note->next)
+ ipa_write_param_call_note (ob, note);
}
/* Srtream in NODE info from IB. */
int k;
struct cgraph_edge *e;
struct bitpack_d *bp;
+ int i, note_count;
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)
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;
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);
}
+
+ note_count = lto_input_uleb128 (ib);
+ for (i = 0; i < note_count; i++)
+ ipa_read_param_call_note (ib, info);
}
/* Write jump functions for nodes in SET. */
}
}
}
+
+/* Walk param call notes of NODE and set their call statements given the uid
+ stored in each note and STMTS which is an array of statements indexed by the
+ uid. */
+
+void
+lto_ipa_fixup_call_notes (struct cgraph_node *node, gimple *stmts)
+{
+ struct ipa_node_params *info;
+ struct ipa_param_call_note *note;
+
+ ipa_check_create_node_params ();
+ info = IPA_NODE_REF (node);
+ note = info->param_calls;
+ /* If there are no notes or they have already been fixed up (the same fixup
+ is called for both inlining and ipa-cp), there's nothing to do. */
+ if (!note || note->stmt)
+ return;
+
+ do
+ {
+ note->stmt = stmts[note->lto_stmt_uid];
+ note = note->next;
+ }
+ while (note);
+}