mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-23 01:00:53 +08:00
gengtype.c (open_base_files): Add ipa-inline.h include.
* gengtype.c (open_base_files): Add ipa-inline.h include. * ipa-cp.c (ipcp_get_lattice, ipcp_lattice_from_jfunc): Move to ipa-prop.c update all uses. * ipa-prop.c: (ipa_get_lattice, ipa_lattice_from_jfunc): ... here. * ipa-inline-transform.c (inline_call): Use inline_merge_summary to merge summary of inlined function into former caller. * ipa-inline.c (max_benefit): Remove. (edge_badness): Compensate for removal of benefits. (update_caller_keys): Use reset_node_growth_cache/reset_edge_growth_cache. (update_callee_keys): Likewise. (update_all_callee_keys): Likewise. (inline_small_functions): Do not collect max_benefit; do not reset stimated_growth; call free_growth_caches and initialize_growth_caches. * ipa-inline.h (struct condition, type clause_t, struct predicate, struct size_time_entry): New structures. (INLINE_SIZE_SCALE, INLINE_TIME_SCALE, MAX_CLAUSES): New constants. (inline_summary): Remove size_inlining_benefit, time_inlining_benefit and estimated_growth. (edge_growth_cache_entry): New structure. (node_growth_cache, edge_growth_cache): New global vars. (estimate_growth): Turn into inline. (inline_merge_summary, do_estimate_edge_growth, do_estimate_edge_time, initialize_growth_caches, free_growth_caches): Declare. (estimate_edge_growth): Rewrite. (estimate_edge_time): Implement as inline cache lookup. (reset_node_growth_cache, reset_edge_growth_cache): New inline functions. (MAX_TIME): Reduce to allow multiplicatoin by INLINE_SIZE_SCALE. (NUM_CONDITIONS): New constant. (predicate_conditions): New enum. (IS_NOT_CONSTANT): New constant. (edge_removal_hook_holder): New var. (node_growth_cache, edge_growth_cache): New global vars. (true_predicate, single_cond_predicate, false_predicate, not_inlined_predicate, add_condition, add_clause, and_predicates, or_predicates, predicates_equal_p, evaulate_predicate, dump_condition, dump_clause, dump_predicate, account_size_time, evaulate_conditions_for_edge): New functions. (inline_summary_alloc): Move to heap. (inline_node_removal_hook): Clear condition and entry vectors. (inline_edge_removal_hook): New function. (initialize_growth_caches, free_growth_caches): New function. (dump_inline_summary): Update. (edge_execution_predicate): New function. (will_be_nonconstant_predicate): New function. (estimate_function_body_sizes): Compute BB and constantness predicates. (compute_inline_parameters): Do not clear estimated_growth. (estimate_edge_size_and_time): New function. (estimate_calls_size_and_time): New function. (estimate_callee_size_and_time): New function. (remap_predicate): New function. (inline_merge_summary): New function. (do_estimate_edge_time): New function based on... (estimate_edge_time): ... this one. (do_estimate_edge_growth): New function. (do_estimate_growth): New function based on.... (estimate_growth): ... this one. (inline_analyze_function): Analyze after deciding on jump functions. (inline_read_section): New function. (inline_read_summary): Use it. (inline_write_summary): Write all the new data. * ipa-prop.c (ipa_get_param_decl_index): Export. (ipa_lattice_from_jfunc): Move here from ipa-cp.c * ipa-prop.h (ipa_get_param_decl_index, ipa_lattice_from_jfunc): Declare. (ipa_get_lattice): Move hre from ipa-cp.c * Makefile.in (GTFILES): Add ipa-inline.h and ipa-inline-analysis.c * params.def (PARAM_EARLY_INLINING_INSNS): Set to 11. * cgraph.h (cgraph_clone_inlined_nodes, compute_inline_parameters, cgraph_edge_inlinable_p): Remove. * cgraphunit.c: Include ipainline.h (cgraph_process_new_functions): Update call of compute_inline_parameters. * gcc.dg/tree-ssa/pr38699.c: Fix testcase. From-SVN: r172873
This commit is contained in:
parent
0cfbd28838
commit
632b4f8e8b
@ -1,3 +1,75 @@
|
||||
2011-04-22 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* gengtype.c (open_base_files): Add ipa-inline.h include.
|
||||
* ipa-cp.c (ipcp_get_lattice, ipcp_lattice_from_jfunc): Move to ipa-prop.c
|
||||
update all uses.
|
||||
* ipa-prop.c: (ipa_get_lattice, ipa_lattice_from_jfunc): ... here.
|
||||
* ipa-inline-transform.c (inline_call): Use inline_merge_summary to merge
|
||||
summary of inlined function into former caller.
|
||||
* ipa-inline.c (max_benefit): Remove.
|
||||
(edge_badness): Compensate for removal of benefits.
|
||||
(update_caller_keys): Use reset_node_growth_cache/reset_edge_growth_cache.
|
||||
(update_callee_keys): Likewise.
|
||||
(update_all_callee_keys): Likewise.
|
||||
(inline_small_functions): Do not collect max_benefit; do not
|
||||
reset stimated_growth; call free_growth_caches and initialize_growth_caches.
|
||||
* ipa-inline.h (struct condition, type clause_t, struct predicate, struct
|
||||
size_time_entry): New structures.
|
||||
(INLINE_SIZE_SCALE, INLINE_TIME_SCALE, MAX_CLAUSES): New constants.
|
||||
(inline_summary): Remove size_inlining_benefit, time_inlining_benefit and
|
||||
estimated_growth.
|
||||
(edge_growth_cache_entry): New structure.
|
||||
(node_growth_cache, edge_growth_cache): New global vars.
|
||||
(estimate_growth): Turn into inline.
|
||||
(inline_merge_summary, do_estimate_edge_growth, do_estimate_edge_time,
|
||||
initialize_growth_caches, free_growth_caches): Declare.
|
||||
(estimate_edge_growth): Rewrite.
|
||||
(estimate_edge_time): Implement as inline cache lookup.
|
||||
(reset_node_growth_cache, reset_edge_growth_cache): New inline functions.
|
||||
(MAX_TIME): Reduce to allow multiplicatoin by INLINE_SIZE_SCALE.
|
||||
(NUM_CONDITIONS): New constant.
|
||||
(predicate_conditions): New enum.
|
||||
(IS_NOT_CONSTANT): New constant.
|
||||
(edge_removal_hook_holder): New var.
|
||||
(node_growth_cache, edge_growth_cache): New global vars.
|
||||
(true_predicate, single_cond_predicate, false_predicate, not_inlined_predicate,
|
||||
add_condition, add_clause, and_predicates, or_predicates, predicates_equal_p,
|
||||
evaulate_predicate, dump_condition, dump_clause, dump_predicate, account_size_time,
|
||||
evaulate_conditions_for_edge): New functions.
|
||||
(inline_summary_alloc): Move to heap.
|
||||
(inline_node_removal_hook): Clear condition and entry vectors.
|
||||
(inline_edge_removal_hook): New function.
|
||||
(initialize_growth_caches, free_growth_caches): New function.
|
||||
(dump_inline_summary): Update.
|
||||
(edge_execution_predicate): New function.
|
||||
(will_be_nonconstant_predicate): New function.
|
||||
(estimate_function_body_sizes): Compute BB and constantness predicates.
|
||||
(compute_inline_parameters): Do not clear estimated_growth.
|
||||
(estimate_edge_size_and_time): New function.
|
||||
(estimate_calls_size_and_time): New function.
|
||||
(estimate_callee_size_and_time): New function.
|
||||
(remap_predicate): New function.
|
||||
(inline_merge_summary): New function.
|
||||
(do_estimate_edge_time): New function based on...
|
||||
(estimate_edge_time): ... this one.
|
||||
(do_estimate_edge_growth): New function.
|
||||
(do_estimate_growth): New function based on....
|
||||
(estimate_growth): ... this one.
|
||||
(inline_analyze_function): Analyze after deciding on jump functions.
|
||||
(inline_read_section): New function.
|
||||
(inline_read_summary): Use it.
|
||||
(inline_write_summary): Write all the new data.
|
||||
* ipa-prop.c (ipa_get_param_decl_index): Export.
|
||||
(ipa_lattice_from_jfunc): Move here from ipa-cp.c
|
||||
* ipa-prop.h (ipa_get_param_decl_index, ipa_lattice_from_jfunc): Declare.
|
||||
(ipa_get_lattice): Move hre from ipa-cp.c
|
||||
* Makefile.in (GTFILES): Add ipa-inline.h and ipa-inline-analysis.c
|
||||
* params.def (PARAM_EARLY_INLINING_INSNS): Set to 11.
|
||||
* cgraph.h (cgraph_clone_inlined_nodes, compute_inline_parameters,
|
||||
cgraph_edge_inlinable_p): Remove.
|
||||
* cgraphunit.c: Include ipainline.h
|
||||
(cgraph_process_new_functions): Update call of compute_inline_parameters.
|
||||
|
||||
2011-04-22 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
* tree.c (build_int_cst): Properly create canonicalized integer
|
||||
|
@ -2997,7 +2997,7 @@ cgraphunit.o : cgraphunit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
||||
$(TREE_FLOW_H) $(TREE_PASS_H) debug.h $(DIAGNOSTIC_H) \
|
||||
$(FIBHEAP_H) output.h $(PARAMS_H) $(RTL_H) $(TIMEVAR_H) $(IPA_PROP_H) \
|
||||
gt-cgraphunit.h tree-iterator.h $(COVERAGE_H) $(TREE_DUMP_H) \
|
||||
tree-pretty-print.h gimple-pretty-print.h
|
||||
tree-pretty-print.h gimple-pretty-print.h ipa-inline.h
|
||||
cgraphbuild.o : cgraphbuild.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
||||
$(TREE_H) langhooks.h $(CGRAPH_H) intl.h pointer-set.h $(GIMPLE_H) \
|
||||
$(TREE_FLOW_H) $(TREE_PASS_H) $(IPA_UTILS_H) $(EXCEPT_H) \
|
||||
@ -3782,6 +3782,7 @@ GTFILES = $(CPP_ID_DATA_H) $(srcdir)/input.h $(srcdir)/coretypes.h \
|
||||
$(srcdir)/ipa-prop.h \
|
||||
$(srcdir)/lto-streamer.h \
|
||||
$(srcdir)/target-globals.h \
|
||||
$(srcdir)/ipa-inline.h \
|
||||
@all_gtfiles@
|
||||
|
||||
# Compute the list of GT header files from the corresponding C sources,
|
||||
|
@ -721,11 +721,6 @@ varpool_next_static_initializer (struct varpool_node *node)
|
||||
for ((node) = varpool_first_static_initializer (); (node); \
|
||||
(node) = varpool_next_static_initializer (node))
|
||||
|
||||
/* In ipa-inline.c */
|
||||
void cgraph_clone_inlined_nodes (struct cgraph_edge *, bool, bool);
|
||||
void compute_inline_parameters (struct cgraph_node *);
|
||||
cgraph_inline_failed_t cgraph_edge_inlinable_p (struct cgraph_edge *);
|
||||
|
||||
/* Create a new static variable of type TYPE. */
|
||||
tree add_new_static_var (tree type);
|
||||
|
||||
|
@ -138,6 +138,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
#include "output.h"
|
||||
#include "coverage.h"
|
||||
#include "plugin.h"
|
||||
#include "ipa-inline.h"
|
||||
|
||||
static void cgraph_expand_all_functions (void);
|
||||
static void cgraph_mark_functions_to_output (void);
|
||||
@ -252,7 +253,7 @@ cgraph_process_new_functions (void)
|
||||
|| !optimize)
|
||||
execute_pass_list (pass_early_local_passes.pass.sub);
|
||||
else
|
||||
compute_inline_parameters (node);
|
||||
compute_inline_parameters (node, true);
|
||||
free_dominance_info (CDI_POST_DOMINATORS);
|
||||
free_dominance_info (CDI_DOMINATORS);
|
||||
pop_cfun ();
|
||||
|
@ -1559,7 +1559,8 @@ open_base_files (void)
|
||||
"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", "lto-streamer.h", "target-globals.h", NULL
|
||||
"target.h", "ipa-prop.h", "lto-streamer.h", "target-globals.h",
|
||||
"ipa-inline.h", NULL
|
||||
};
|
||||
const char *const *ifp;
|
||||
outf_p gtype_desc_c;
|
||||
|
95
gcc/ipa-cp.c
95
gcc/ipa-cp.c
@ -278,77 +278,6 @@ ipa_lattice_meet (struct ipcp_lattice *res, struct ipcp_lattice *lat1,
|
||||
res->constant = lat1->constant;
|
||||
}
|
||||
|
||||
/* Return the lattice corresponding to the Ith formal parameter of the function
|
||||
described by INFO. */
|
||||
static inline struct ipcp_lattice *
|
||||
ipcp_get_lattice (struct ipa_node_params *info, int i)
|
||||
{
|
||||
return &(info->params[i].ipcp_lattice);
|
||||
}
|
||||
|
||||
/* Given the jump function JFUNC, compute the lattice LAT that describes the
|
||||
value coming down the callsite. INFO describes the caller node so that
|
||||
pass-through jump functions can be evaluated. */
|
||||
static void
|
||||
ipcp_lattice_from_jfunc (struct ipa_node_params *info, struct ipcp_lattice *lat,
|
||||
struct ipa_jump_func *jfunc)
|
||||
{
|
||||
if (jfunc->type == IPA_JF_CONST)
|
||||
{
|
||||
lat->type = IPA_CONST_VALUE;
|
||||
lat->constant = jfunc->value.constant;
|
||||
}
|
||||
else if (jfunc->type == IPA_JF_PASS_THROUGH)
|
||||
{
|
||||
struct ipcp_lattice *caller_lat;
|
||||
tree cst;
|
||||
|
||||
caller_lat = ipcp_get_lattice (info, jfunc->value.pass_through.formal_id);
|
||||
lat->type = caller_lat->type;
|
||||
if (caller_lat->type != IPA_CONST_VALUE)
|
||||
return;
|
||||
cst = caller_lat->constant;
|
||||
|
||||
if (jfunc->value.pass_through.operation != NOP_EXPR)
|
||||
{
|
||||
tree restype;
|
||||
if (TREE_CODE_CLASS (jfunc->value.pass_through.operation)
|
||||
== tcc_comparison)
|
||||
restype = boolean_type_node;
|
||||
else
|
||||
restype = TREE_TYPE (cst);
|
||||
cst = fold_binary (jfunc->value.pass_through.operation,
|
||||
restype, cst, jfunc->value.pass_through.operand);
|
||||
}
|
||||
if (!cst || !is_gimple_ip_invariant (cst))
|
||||
lat->type = IPA_BOTTOM;
|
||||
lat->constant = cst;
|
||||
}
|
||||
else if (jfunc->type == IPA_JF_ANCESTOR)
|
||||
{
|
||||
struct ipcp_lattice *caller_lat;
|
||||
tree t;
|
||||
|
||||
caller_lat = ipcp_get_lattice (info, jfunc->value.ancestor.formal_id);
|
||||
lat->type = caller_lat->type;
|
||||
if (caller_lat->type != IPA_CONST_VALUE)
|
||||
return;
|
||||
if (TREE_CODE (caller_lat->constant) != ADDR_EXPR)
|
||||
{
|
||||
/* This can happen when the constant is a NULL pointer. */
|
||||
lat->type = IPA_BOTTOM;
|
||||
return;
|
||||
}
|
||||
t = TREE_OPERAND (caller_lat->constant, 0);
|
||||
t = build_ref_for_offset (EXPR_LOCATION (t), t,
|
||||
jfunc->value.ancestor.offset,
|
||||
jfunc->value.ancestor.type, NULL, false);
|
||||
lat->constant = build_fold_addr_expr (t);
|
||||
}
|
||||
else
|
||||
lat->type = IPA_BOTTOM;
|
||||
}
|
||||
|
||||
/* True when OLD_LAT and NEW_LAT values are not the same. */
|
||||
|
||||
static bool
|
||||
@ -384,7 +313,7 @@ ipcp_print_all_lattices (FILE * f)
|
||||
count = ipa_get_param_count (info);
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
struct ipcp_lattice *lat = ipcp_get_lattice (info, i);
|
||||
struct ipcp_lattice *lat = ipa_get_lattice (info, i);
|
||||
|
||||
fprintf (f, " param [%d]: ", i);
|
||||
if (lat->type == IPA_CONST_VALUE)
|
||||
@ -582,7 +511,7 @@ ipcp_initialize_node_lattices (struct cgraph_node *node)
|
||||
|
||||
for (i = 0; i < ipa_get_param_count (info) ; i++)
|
||||
{
|
||||
ipcp_get_lattice (info, i)->type = type;
|
||||
ipa_get_lattice (info, i)->type = type;
|
||||
if (type == IPA_BOTTOM)
|
||||
ipa_set_param_cannot_devirtualize (info, i);
|
||||
}
|
||||
@ -659,7 +588,7 @@ ipcp_change_tops_to_bottom (void)
|
||||
count = ipa_get_param_count (info);
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
struct ipcp_lattice *lat = ipcp_get_lattice (info, i);
|
||||
struct ipcp_lattice *lat = ipa_get_lattice (info, i);
|
||||
if (lat->type == IPA_TOP)
|
||||
{
|
||||
prop_again = true;
|
||||
@ -842,8 +771,8 @@ ipcp_propagate_stage (void)
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
jump_func = ipa_get_ith_jump_func (args, i);
|
||||
ipcp_lattice_from_jfunc (info, &inc_lat, jump_func);
|
||||
dest_lat = ipcp_get_lattice (callee_info, i);
|
||||
ipa_lattice_from_jfunc (info, &inc_lat, jump_func);
|
||||
dest_lat = ipa_get_lattice (callee_info, i);
|
||||
ipa_lattice_meet (&new_lat, &inc_lat, dest_lat);
|
||||
if (ipcp_lattice_changed (&new_lat, dest_lat))
|
||||
{
|
||||
@ -1031,7 +960,7 @@ ipcp_need_redirect_p (struct cgraph_edge *cs)
|
||||
count = ipa_get_param_count (orig_callee_info);
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
struct ipcp_lattice *lat = ipcp_get_lattice (orig_callee_info, i);
|
||||
struct ipcp_lattice *lat = ipa_get_lattice (orig_callee_info, i);
|
||||
struct ipa_jump_func *jump_func;
|
||||
|
||||
jump_func = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i);
|
||||
@ -1067,7 +996,7 @@ ipcp_update_callgraph (void)
|
||||
args_to_skip = BITMAP_ALLOC (NULL);
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
struct ipcp_lattice *lat = ipcp_get_lattice (info, i);
|
||||
struct ipcp_lattice *lat = ipa_get_lattice (info, i);
|
||||
|
||||
/* We can proactively remove obviously unused arguments. */
|
||||
if (!ipa_is_param_used (info, i))
|
||||
@ -1155,7 +1084,7 @@ ipcp_estimate_growth (struct cgraph_node *node)
|
||||
if (node->local.can_change_signature)
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
struct ipcp_lattice *lat = ipcp_get_lattice (info, i);
|
||||
struct ipcp_lattice *lat = ipa_get_lattice (info, i);
|
||||
|
||||
/* We can proactively remove obviously unused arguments. */
|
||||
if (!ipa_is_param_used (info, i))
|
||||
@ -1237,7 +1166,7 @@ ipcp_process_devirtualization_opportunities (struct cgraph_node *node)
|
||||
if (param_index == -1)
|
||||
continue;
|
||||
|
||||
lat = ipcp_get_lattice (info, param_index);
|
||||
lat = ipa_get_lattice (info, param_index);
|
||||
token = ie->indirect_info->otr_token;
|
||||
anc_offset = ie->indirect_info->anc_offset;
|
||||
otr_type = ie->indirect_info->otr_type;
|
||||
@ -1309,7 +1238,7 @@ ipcp_const_param_count (struct cgraph_node *node)
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
struct ipcp_lattice *lat = ipcp_get_lattice (info, i);
|
||||
struct ipcp_lattice *lat = ipa_get_lattice (info, i);
|
||||
if ((ipcp_lat_is_insertable (lat)
|
||||
/* Do not count obviously unused arguments. */
|
||||
&& ipa_is_param_used (info, i))
|
||||
@ -1436,7 +1365,7 @@ ipcp_insert_stage (void)
|
||||
args_to_skip = NULL;
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
struct ipcp_lattice *lat = ipcp_get_lattice (info, i);
|
||||
struct ipcp_lattice *lat = ipa_get_lattice (info, i);
|
||||
parm_tree = ipa_get_param (info, i);
|
||||
|
||||
/* We can proactively remove obviously unused arguments. */
|
||||
@ -1504,7 +1433,7 @@ ipcp_insert_stage (void)
|
||||
info = IPA_NODE_REF (node);
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
struct ipcp_lattice *lat = ipcp_get_lattice (info, i);
|
||||
struct ipcp_lattice *lat = ipa_get_lattice (info, i);
|
||||
if (lat->type == IPA_CONST_VALUE)
|
||||
ipcp_discover_new_direct_edges (node1, i, lat->constant);
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -175,7 +175,6 @@ inline_call (struct cgraph_edge *e, bool update_original,
|
||||
int old_size = 0, new_size = 0;
|
||||
struct cgraph_node *to = NULL;
|
||||
struct cgraph_edge *curr = e;
|
||||
struct inline_summary *info;
|
||||
|
||||
/* Don't inline inlined edges. */
|
||||
gcc_assert (e->inline_failed);
|
||||
@ -185,18 +184,15 @@ inline_call (struct cgraph_edge *e, bool update_original,
|
||||
e->inline_failed = CIF_OK;
|
||||
DECL_POSSIBLY_INLINED (e->callee->decl) = true;
|
||||
|
||||
to = e->caller;
|
||||
if (to->global.inlined_to)
|
||||
to = to->global.inlined_to;
|
||||
old_size = inline_summary (to)->size;
|
||||
inline_merge_summary (e);
|
||||
new_size = inline_summary (to)->size;
|
||||
|
||||
clone_inlined_nodes (e, true, update_original, overall_size);
|
||||
|
||||
/* Now update size of caller and all functions caller is inlined into. */
|
||||
for (;e && !e->inline_failed; e = e->caller->callers)
|
||||
{
|
||||
to = e->caller;
|
||||
info = inline_summary (to);
|
||||
old_size = info->size;
|
||||
new_size = estimate_size_after_inlining (to, curr);
|
||||
info->size = new_size;
|
||||
info->time = estimate_time_after_inlining (to, curr);
|
||||
}
|
||||
gcc_assert (curr->callee->global.inlined_to == to);
|
||||
if (overall_size && new_size > old_size)
|
||||
*overall_size += new_size - old_size;
|
||||
|
@ -117,7 +117,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
|
||||
/* Statistics we collect about inlining algorithm. */
|
||||
static int overall_size;
|
||||
static gcov_type max_count, max_benefit;
|
||||
static gcov_type max_count;
|
||||
|
||||
/* Return false when inlining edge E would lead to violating
|
||||
limits on function unit growth or stack usage growth.
|
||||
@ -633,27 +633,23 @@ static int
|
||||
edge_badness (struct cgraph_edge *edge, bool dump)
|
||||
{
|
||||
gcov_type badness;
|
||||
int growth;
|
||||
int growth, time_growth;
|
||||
struct inline_summary *callee_info = inline_summary (edge->callee);
|
||||
|
||||
if (DECL_DISREGARD_INLINE_LIMITS (edge->callee->decl))
|
||||
return INT_MIN;
|
||||
|
||||
growth = estimate_edge_growth (edge);
|
||||
time_growth = estimate_edge_time (edge);
|
||||
|
||||
if (dump)
|
||||
{
|
||||
fprintf (dump_file, " Badness calculation for %s -> %s\n",
|
||||
cgraph_node_name (edge->caller),
|
||||
cgraph_node_name (edge->callee));
|
||||
fprintf (dump_file, " growth %i, time %i-%i, size %i-%i\n",
|
||||
fprintf (dump_file, " growth size %i, time %i\n",
|
||||
growth,
|
||||
callee_info->time,
|
||||
callee_info->time_inlining_benefit
|
||||
+ edge->call_stmt_time,
|
||||
callee_info->size,
|
||||
callee_info->size_inlining_benefit
|
||||
+ edge->call_stmt_size);
|
||||
time_growth);
|
||||
}
|
||||
|
||||
/* Always prefer inlining saving code size. */
|
||||
@ -669,11 +665,16 @@ edge_badness (struct cgraph_edge *edge, bool dump)
|
||||
So we optimize for overall number of "executed" inlined calls. */
|
||||
else if (max_count)
|
||||
{
|
||||
int benefitperc;
|
||||
benefitperc = (((gcov_type)callee_info->time
|
||||
* edge->frequency / CGRAPH_FREQ_BASE - time_growth) * 100
|
||||
/ (callee_info->time + 1) + 1);
|
||||
benefitperc = MIN (benefitperc, 100);
|
||||
benefitperc = MAX (benefitperc, 0);
|
||||
badness =
|
||||
((int)
|
||||
((double) edge->count * INT_MIN / max_count / (max_benefit + 1)) *
|
||||
(callee_info->time_inlining_benefit
|
||||
+ edge->call_stmt_time + 1)) / growth;
|
||||
((double) edge->count * INT_MIN / max_count / 100) *
|
||||
benefitperc) / growth;
|
||||
|
||||
/* Be sure that insanity of the profile won't lead to increasing counts
|
||||
in the scalling and thus to overflow in the computation above. */
|
||||
@ -685,9 +686,7 @@ edge_badness (struct cgraph_edge *edge, bool dump)
|
||||
" * Relative benefit %f\n",
|
||||
(int) badness, (double) badness / INT_MIN,
|
||||
(double) edge->count / max_count,
|
||||
(double) (inline_summary (edge->callee)->
|
||||
time_inlining_benefit
|
||||
+ edge->call_stmt_time + 1) / (max_benefit + 1));
|
||||
(double) benefitperc);
|
||||
}
|
||||
}
|
||||
|
||||
@ -706,11 +705,11 @@ edge_badness (struct cgraph_edge *edge, bool dump)
|
||||
int benefitperc;
|
||||
int growth_for_all;
|
||||
badness = growth * 10000;
|
||||
benefitperc =
|
||||
100 * (callee_info->time_inlining_benefit
|
||||
+ edge->call_stmt_time)
|
||||
/ (callee_info->time + 1) + 1;
|
||||
benefitperc = (((gcov_type)callee_info->time
|
||||
* edge->frequency / CGRAPH_FREQ_BASE - time_growth) * 100
|
||||
/ (callee_info->time + 1) + 1);
|
||||
benefitperc = MIN (benefitperc, 100);
|
||||
benefitperc = MAX (benefitperc, 0);
|
||||
div *= benefitperc;
|
||||
|
||||
/* Decrease badness if call is nested. */
|
||||
@ -822,7 +821,7 @@ update_caller_keys (fibheap_t heap, struct cgraph_node *node,
|
||||
return;
|
||||
if (!bitmap_set_bit (updated_nodes, node->uid))
|
||||
return;
|
||||
inline_summary (node)->estimated_growth = INT_MIN;
|
||||
reset_node_growth_cache (node);
|
||||
|
||||
/* See if there is something to do. */
|
||||
for (edge = node->callers; edge; edge = edge->next_caller)
|
||||
@ -834,6 +833,7 @@ update_caller_keys (fibheap_t heap, struct cgraph_node *node,
|
||||
for (; edge; edge = edge->next_caller)
|
||||
if (edge->inline_failed)
|
||||
{
|
||||
reset_edge_growth_cache (edge);
|
||||
if (can_inline_edge_p (edge, false)
|
||||
&& want_inline_small_function_p (edge, false))
|
||||
update_edge_key (heap, edge);
|
||||
@ -857,7 +857,7 @@ update_callee_keys (fibheap_t heap, struct cgraph_node *node,
|
||||
{
|
||||
struct cgraph_edge *e = node->callees;
|
||||
|
||||
inline_summary (node)->estimated_growth = INT_MIN;
|
||||
reset_node_growth_cache (node);
|
||||
|
||||
if (!e)
|
||||
return;
|
||||
@ -866,12 +866,13 @@ update_callee_keys (fibheap_t heap, struct cgraph_node *node,
|
||||
e = e->callee->callees;
|
||||
else
|
||||
{
|
||||
reset_edge_growth_cache (e);
|
||||
if (e->inline_failed
|
||||
&& inline_summary (e->callee)->inlinable
|
||||
&& cgraph_function_body_availability (e->callee) >= AVAIL_AVAILABLE
|
||||
&& !bitmap_bit_p (updated_nodes, e->callee->uid))
|
||||
{
|
||||
inline_summary (node)->estimated_growth = INT_MIN;
|
||||
reset_node_growth_cache (node);
|
||||
update_edge_key (heap, e);
|
||||
}
|
||||
if (e->next_callee)
|
||||
@ -899,7 +900,7 @@ update_all_callee_keys (fibheap_t heap, struct cgraph_node *node,
|
||||
{
|
||||
struct cgraph_edge *e = node->callees;
|
||||
|
||||
inline_summary (node)->estimated_growth = INT_MIN;
|
||||
reset_node_growth_cache (node);
|
||||
|
||||
if (!e)
|
||||
return;
|
||||
@ -1131,7 +1132,7 @@ inline_small_functions (void)
|
||||
metrics. */
|
||||
|
||||
max_count = 0;
|
||||
max_benefit = 0;
|
||||
initialize_growth_caches ();
|
||||
|
||||
for (node = cgraph_nodes; node; node = node->next)
|
||||
if (node->analyzed
|
||||
@ -1139,20 +1140,12 @@ inline_small_functions (void)
|
||||
{
|
||||
struct inline_summary *info = inline_summary (node);
|
||||
|
||||
info->estimated_growth = INT_MIN;
|
||||
|
||||
if (!DECL_EXTERNAL (node->decl))
|
||||
initial_size += info->size;
|
||||
|
||||
for (edge = node->callers; edge; edge = edge->next_caller)
|
||||
{
|
||||
int benefit = (info->time_inlining_benefit
|
||||
+ edge->call_stmt_time);
|
||||
if (max_count < edge->count)
|
||||
max_count = edge->count;
|
||||
if (max_benefit < benefit)
|
||||
max_benefit = benefit;
|
||||
}
|
||||
if (max_count < edge->count)
|
||||
max_count = edge->count;
|
||||
}
|
||||
|
||||
overall_size = initial_size;
|
||||
@ -1354,14 +1347,15 @@ inline_small_functions (void)
|
||||
}
|
||||
}
|
||||
|
||||
free_growth_caches ();
|
||||
if (new_indirect_edges)
|
||||
VEC_free (cgraph_edge_p, heap, new_indirect_edges);
|
||||
fibheap_delete (heap);
|
||||
if (dump_file)
|
||||
fprintf (dump_file,
|
||||
"Unit growth for small function inlining: %i->%i (%i%%)\n",
|
||||
overall_size, initial_size,
|
||||
overall_size * 100 / (initial_size + 1) - 100);
|
||||
initial_size, overall_size,
|
||||
initial_size ? overall_size * 100 / (initial_size) - 100: 0);
|
||||
BITMAP_FREE (updated_nodes);
|
||||
}
|
||||
|
||||
@ -1369,7 +1363,7 @@ inline_small_functions (void)
|
||||
at IPA inlining time. */
|
||||
|
||||
static void
|
||||
flatten_function (struct cgraph_node *node)
|
||||
flatten_function (struct cgraph_node *node, bool early)
|
||||
{
|
||||
struct cgraph_edge *e;
|
||||
|
||||
@ -1398,14 +1392,14 @@ flatten_function (struct cgraph_node *node)
|
||||
it in order to fully flatten the leaves. */
|
||||
if (!e->inline_failed)
|
||||
{
|
||||
flatten_function (e->callee);
|
||||
flatten_function (e->callee, early);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Flatten attribute needs to be processed during late inlining. For
|
||||
extra code quality we however do flattening during early optimization,
|
||||
too. */
|
||||
if (cgraph_state != CGRAPH_STATE_IPA_SSA
|
||||
if (!early
|
||||
? !can_inline_edge_p (e, true)
|
||||
: !can_early_inline_edge_p (e))
|
||||
continue;
|
||||
@ -1435,7 +1429,7 @@ flatten_function (struct cgraph_node *node)
|
||||
inline_call (e, true, NULL, NULL);
|
||||
if (e->callee != orig_callee)
|
||||
orig_callee->aux = (void *) node;
|
||||
flatten_function (e->callee);
|
||||
flatten_function (e->callee, early);
|
||||
if (e->callee != orig_callee)
|
||||
orig_callee->aux = NULL;
|
||||
}
|
||||
@ -1488,7 +1482,7 @@ ipa_inline (void)
|
||||
if (dump_file)
|
||||
fprintf (dump_file,
|
||||
"Flattening %s\n", cgraph_node_name (node));
|
||||
flatten_function (node);
|
||||
flatten_function (node, false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1696,7 +1690,7 @@ early_inliner (void)
|
||||
if (dump_file)
|
||||
fprintf (dump_file,
|
||||
"Flattening %s\n", cgraph_node_name (node));
|
||||
flatten_function (node);
|
||||
flatten_function (node, true);
|
||||
inlined = true;
|
||||
}
|
||||
else
|
||||
|
160
gcc/ipa-inline.h
160
gcc/ipa-inline.h
@ -19,9 +19,60 @@ You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Function inlining information. */
|
||||
/* Representation of inline parameters that do depend on context function is
|
||||
inlined into (i.e. known constant values of function parameters.
|
||||
|
||||
struct inline_summary
|
||||
Conditions that are interesting for function body are collected into CONDS
|
||||
vector. They are of simple for function_param OP VAL, where VAL is
|
||||
IPA invariant. The conditions are then refered by predicates. */
|
||||
|
||||
typedef struct GTY(()) condition
|
||||
{
|
||||
tree val;
|
||||
int operand_num;
|
||||
enum tree_code code;
|
||||
} condition;
|
||||
|
||||
DEF_VEC_O (condition);
|
||||
DEF_VEC_ALLOC_O (condition, gc);
|
||||
|
||||
typedef VEC(condition,gc) *conditions;
|
||||
|
||||
/* Representation of predicates i.e. formulas using conditions defined
|
||||
above. Predicates are simple logical formulas in conjunctive-disjunctive
|
||||
form.
|
||||
|
||||
Predicate is array of clauses terminated by 0. Every clause must be true
|
||||
in order to make predicate true.
|
||||
Clauses are represented as bitmaps of conditions. One of conditions
|
||||
must be true in order for clause to be true. */
|
||||
|
||||
#define MAX_CLAUSES 8
|
||||
typedef int clause_t;
|
||||
struct GTY(()) predicate
|
||||
{
|
||||
clause_t clause[MAX_CLAUSES + 1];
|
||||
};
|
||||
|
||||
/* Represnetation of function body size and time depending on the inline
|
||||
context. We keep simple array of record, every containing of predicate
|
||||
and time/size to account.
|
||||
|
||||
We keep values scaled up, so fractional sizes and times can be
|
||||
accounted. */
|
||||
#define INLINE_SIZE_SCALE 2
|
||||
#define INLINE_TIME_SCALE (CGRAPH_FREQ_BASE * 2)
|
||||
typedef struct GTY(()) size_time_entry
|
||||
{
|
||||
struct predicate predicate;
|
||||
int size;
|
||||
int time;
|
||||
} size_time_entry;
|
||||
DEF_VEC_O (size_time_entry);
|
||||
DEF_VEC_ALLOC_O (size_time_entry, gc);
|
||||
|
||||
/* Function inlining information. */
|
||||
struct GTY(()) inline_summary
|
||||
{
|
||||
/* Information about the function body itself. */
|
||||
|
||||
@ -29,12 +80,8 @@ struct inline_summary
|
||||
HOST_WIDE_INT estimated_self_stack_size;
|
||||
/* Size of the function body. */
|
||||
int self_size;
|
||||
/* How many instructions are likely going to disappear after inlining. */
|
||||
int size_inlining_benefit;
|
||||
/* Estimated time spent executing the function body. */
|
||||
/* Time of the function body. */
|
||||
int self_time;
|
||||
/* How much time is going to be saved by inlining. */
|
||||
int time_inlining_benefit;
|
||||
|
||||
/* False when there something makes inlining impossible (such as va_arg). */
|
||||
unsigned inlinable : 1;
|
||||
@ -53,15 +100,25 @@ struct inline_summary
|
||||
/* Estimated size of the function after inlining. */
|
||||
int time;
|
||||
int size;
|
||||
/* Cached estimated growth after inlining.
|
||||
INT_MIN if not computed. */
|
||||
int estimated_growth;
|
||||
|
||||
conditions conds;
|
||||
VEC(size_time_entry,gc) *entry;
|
||||
};
|
||||
|
||||
typedef struct inline_summary inline_summary_t;
|
||||
DEF_VEC_O(inline_summary_t);
|
||||
DEF_VEC_ALLOC_O(inline_summary_t,heap);
|
||||
extern VEC(inline_summary_t,heap) *inline_summary_vec;
|
||||
DEF_VEC_ALLOC_O(inline_summary_t,gc);
|
||||
extern GTY(()) VEC(inline_summary_t,gc) *inline_summary_vec;
|
||||
|
||||
typedef struct edge_growth_cache_entry
|
||||
{
|
||||
int time, size;
|
||||
} edge_growth_cache_entry;
|
||||
DEF_VEC_O(edge_growth_cache_entry);
|
||||
DEF_VEC_ALLOC_O(edge_growth_cache_entry,heap);
|
||||
|
||||
extern VEC(int,heap) *node_growth_cache;
|
||||
extern VEC(edge_growth_cache_entry,heap) *edge_growth_cache;
|
||||
|
||||
/* In ipa-inline-analysis.c */
|
||||
void debug_inline_summary (struct cgraph_node *);
|
||||
@ -73,7 +130,13 @@ void inline_free_summary (void);
|
||||
void initialize_inline_failed (struct cgraph_edge *);
|
||||
int estimate_time_after_inlining (struct cgraph_node *, struct cgraph_edge *);
|
||||
int estimate_size_after_inlining (struct cgraph_node *, struct cgraph_edge *);
|
||||
int estimate_growth (struct cgraph_node *);
|
||||
int do_estimate_growth (struct cgraph_node *);
|
||||
void inline_merge_summary (struct cgraph_edge *edge);
|
||||
int do_estimate_edge_growth (struct cgraph_edge *edge);
|
||||
int do_estimate_edge_time (struct cgraph_edge *edge);
|
||||
void initialize_growth_caches (void);
|
||||
void free_growth_caches (void);
|
||||
void compute_inline_parameters (struct cgraph_node *, bool);
|
||||
|
||||
/* In ipa-inline-transform.c */
|
||||
bool inline_call (struct cgraph_edge *, bool, VEC (cgraph_edge_p, heap) **, int *);
|
||||
@ -89,16 +152,71 @@ inline_summary (struct cgraph_node *node)
|
||||
return VEC_index (inline_summary_t, inline_summary_vec, node->uid);
|
||||
}
|
||||
|
||||
/* Estimate the growth of the caller when inlining EDGE. */
|
||||
|
||||
/* Return estimated unit growth after inlning all calls to NODE.
|
||||
Quick accesors to the inline growth caches.
|
||||
For convenience we keep zero 0 as unknown. Because growth
|
||||
can be both positive and negative, we simply increase positive
|
||||
growths by 1. */
|
||||
static inline int
|
||||
estimate_growth (struct cgraph_node *node)
|
||||
{
|
||||
int ret;
|
||||
if ((int)VEC_length (int, node_growth_cache) <= node->uid
|
||||
|| !(ret = VEC_index (int, node_growth_cache, node->uid)))
|
||||
return do_estimate_growth (node);
|
||||
return ret - (ret > 0);
|
||||
}
|
||||
|
||||
|
||||
/* Return estimated callee growth after inlining EDGE. */
|
||||
|
||||
static inline int
|
||||
estimate_edge_growth (struct cgraph_edge *edge)
|
||||
{
|
||||
int call_stmt_size;
|
||||
struct inline_summary *info = inline_summary (edge->callee);
|
||||
call_stmt_size = edge->call_stmt_size;
|
||||
gcc_checking_assert (call_stmt_size);
|
||||
return (info->size
|
||||
- info->size_inlining_benefit
|
||||
- call_stmt_size);
|
||||
int ret;
|
||||
if ((int)VEC_length (edge_growth_cache_entry, edge_growth_cache) <= edge->uid
|
||||
|| !(ret = VEC_index (edge_growth_cache_entry,
|
||||
edge_growth_cache,
|
||||
edge->uid)->size))
|
||||
return do_estimate_edge_growth (edge);
|
||||
return ret - (ret > 0);
|
||||
}
|
||||
|
||||
|
||||
/* Return estimated callee runtime increase after inlning
|
||||
EDGE. */
|
||||
|
||||
static inline int
|
||||
estimate_edge_time (struct cgraph_edge *edge)
|
||||
{
|
||||
int ret;
|
||||
if ((int)VEC_length (edge_growth_cache_entry, edge_growth_cache) <= edge->uid
|
||||
|| !(ret = VEC_index (edge_growth_cache_entry,
|
||||
edge_growth_cache,
|
||||
edge->uid)->size))
|
||||
return do_estimate_edge_time (edge);
|
||||
return ret - (ret > 0);
|
||||
}
|
||||
|
||||
|
||||
/* Reset cached value for NODE. */
|
||||
|
||||
static inline void
|
||||
reset_node_growth_cache (struct cgraph_node *node)
|
||||
{
|
||||
if ((int)VEC_length (int, node_growth_cache) > node->uid)
|
||||
VEC_replace (int, node_growth_cache, node->uid, 0);
|
||||
}
|
||||
|
||||
/* Reset cached value for EDGE. */
|
||||
|
||||
static inline void
|
||||
reset_edge_growth_cache (struct cgraph_edge *edge)
|
||||
{
|
||||
if ((int)VEC_length (edge_growth_cache_entry, edge_growth_cache) > edge->uid)
|
||||
{
|
||||
struct edge_growth_cache_entry zero = {0, 0};
|
||||
VEC_replace (edge_growth_cache_entry, edge_growth_cache, edge->uid, &zero);
|
||||
}
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ ipa_pop_func_from_list (struct ipa_func_list **wl)
|
||||
/* Return index of the formal whose tree is PTREE in function which corresponds
|
||||
to INFO. */
|
||||
|
||||
static int
|
||||
int
|
||||
ipa_get_param_decl_index (struct ipa_node_params *info, tree ptree)
|
||||
{
|
||||
int i, count;
|
||||
@ -2986,3 +2986,66 @@ ipa_update_after_lto_read (void)
|
||||
ipa_set_called_with_variable_arg (IPA_NODE_REF (cs->callee));
|
||||
}
|
||||
}
|
||||
|
||||
/* Given the jump function JFUNC, compute the lattice LAT that describes the
|
||||
value coming down the callsite. INFO describes the caller node so that
|
||||
pass-through jump functions can be evaluated. */
|
||||
void
|
||||
ipa_lattice_from_jfunc (struct ipa_node_params *info, struct ipcp_lattice *lat,
|
||||
struct ipa_jump_func *jfunc)
|
||||
{
|
||||
if (jfunc->type == IPA_JF_CONST)
|
||||
{
|
||||
lat->type = IPA_CONST_VALUE;
|
||||
lat->constant = jfunc->value.constant;
|
||||
}
|
||||
else if (jfunc->type == IPA_JF_PASS_THROUGH)
|
||||
{
|
||||
struct ipcp_lattice *caller_lat;
|
||||
tree cst;
|
||||
|
||||
caller_lat = ipa_get_lattice (info, jfunc->value.pass_through.formal_id);
|
||||
lat->type = caller_lat->type;
|
||||
if (caller_lat->type != IPA_CONST_VALUE)
|
||||
return;
|
||||
cst = caller_lat->constant;
|
||||
|
||||
if (jfunc->value.pass_through.operation != NOP_EXPR)
|
||||
{
|
||||
tree restype;
|
||||
if (TREE_CODE_CLASS (jfunc->value.pass_through.operation)
|
||||
== tcc_comparison)
|
||||
restype = boolean_type_node;
|
||||
else
|
||||
restype = TREE_TYPE (cst);
|
||||
cst = fold_binary (jfunc->value.pass_through.operation,
|
||||
restype, cst, jfunc->value.pass_through.operand);
|
||||
}
|
||||
if (!cst || !is_gimple_ip_invariant (cst))
|
||||
lat->type = IPA_BOTTOM;
|
||||
lat->constant = cst;
|
||||
}
|
||||
else if (jfunc->type == IPA_JF_ANCESTOR)
|
||||
{
|
||||
struct ipcp_lattice *caller_lat;
|
||||
tree t;
|
||||
|
||||
caller_lat = ipa_get_lattice (info, jfunc->value.ancestor.formal_id);
|
||||
lat->type = caller_lat->type;
|
||||
if (caller_lat->type != IPA_CONST_VALUE)
|
||||
return;
|
||||
if (TREE_CODE (caller_lat->constant) != ADDR_EXPR)
|
||||
{
|
||||
/* This can happen when the constant is a NULL pointer. */
|
||||
lat->type = IPA_BOTTOM;
|
||||
return;
|
||||
}
|
||||
t = TREE_OPERAND (caller_lat->constant, 0);
|
||||
t = build_ref_for_offset (EXPR_LOCATION (t), t,
|
||||
jfunc->value.ancestor.offset,
|
||||
jfunc->value.ancestor.type, NULL, false);
|
||||
lat->constant = build_fold_addr_expr (t);
|
||||
}
|
||||
else
|
||||
lat->type = IPA_BOTTOM;
|
||||
}
|
||||
|
@ -515,9 +515,20 @@ 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);
|
||||
int ipa_get_param_decl_index (struct ipa_node_params *, tree);
|
||||
void ipa_lattice_from_jfunc (struct ipa_node_params *info, struct ipcp_lattice *lat,
|
||||
struct ipa_jump_func *jfunc);
|
||||
|
||||
/* From tree-sra.c: */
|
||||
tree build_ref_for_offset (location_t, tree, HOST_WIDE_INT, tree,
|
||||
gimple_stmt_iterator *, bool);
|
||||
|
||||
/* Return the lattice corresponding to the Ith formal parameter of the function
|
||||
described by INFO. */
|
||||
static inline struct ipcp_lattice *
|
||||
ipa_get_lattice (struct ipa_node_params *info, int i)
|
||||
{
|
||||
return &(info->params[i].ipcp_lattice);
|
||||
}
|
||||
|
||||
#endif /* IPA_PROP_H */
|
||||
|
@ -1254,7 +1254,7 @@ split_function (struct split_point *split_point)
|
||||
}
|
||||
free_dominance_info (CDI_DOMINATORS);
|
||||
free_dominance_info (CDI_POST_DOMINATORS);
|
||||
compute_inline_parameters (node);
|
||||
compute_inline_parameters (node, true);
|
||||
}
|
||||
|
||||
/* Execute function splitting pass. */
|
||||
|
@ -188,7 +188,7 @@ DEFPARAM(PARAM_IPCP_UNIT_GROWTH,
|
||||
DEFPARAM(PARAM_EARLY_INLINING_INSNS,
|
||||
"early-inlining-insns",
|
||||
"Maximal estimated growth of function body caused by early inlining of single call",
|
||||
10, 0, 0)
|
||||
11, 0, 0)
|
||||
DEFPARAM(PARAM_LARGE_STACK_FRAME,
|
||||
"large-stack-frame",
|
||||
"The size of stack frame to be considered large",
|
||||
|
@ -1,3 +1,7 @@
|
||||
2011-04-22 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* gcc.dg/tree-ssa/pr38699.c: Fix testcase.
|
||||
|
||||
2011-04-22 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR tree-optimization/48717
|
||||
|
@ -17,6 +17,7 @@
|
||||
#define PORTC _SFR_IO8(0x15)
|
||||
#define PORTD _SFR_IO8(0x12)
|
||||
|
||||
|
||||
static void delay_wait_us( unsigned char timeout ) {
|
||||
__asm__ __volatile__ ("wdr");
|
||||
|
||||
@ -27,8 +28,12 @@ static void delay_wait_us( unsigned char timeout ) {
|
||||
while(!(TIFR & (1 << (TOV0))));
|
||||
}
|
||||
|
||||
/* The original testcase was multiplying by 1000. Gcc is now smart enough
|
||||
to work out that actual parameter is 5000 that is not what testcase was
|
||||
about. Obstructate the code somewhat then. */
|
||||
int a;
|
||||
static void delay_wait_us_ms( unsigned char timeout ) {
|
||||
delay_wait_us( timeout * 1000 );
|
||||
delay_wait_us( timeout * a );
|
||||
}
|
||||
|
||||
|
||||
|
@ -4366,7 +4366,7 @@ convert_callers (struct cgraph_node *node, tree old_decl,
|
||||
for (cs = node->callers; cs; cs = cs->next_caller)
|
||||
if (bitmap_set_bit (recomputed_callers, cs->caller->uid)
|
||||
&& gimple_in_ssa_p (DECL_STRUCT_FUNCTION (cs->caller->decl)))
|
||||
compute_inline_parameters (cs->caller);
|
||||
compute_inline_parameters (cs->caller, true);
|
||||
BITMAP_FREE (recomputed_callers);
|
||||
|
||||
current_function_decl = old_cur_fndecl;
|
||||
|
Loading…
x
Reference in New Issue
Block a user