hints &= ~INLINE_HINT_known_hot;
fprintf (f, " known_hot");
}
+ if (hints & INLINE_HINT_builtin_constant_p)
+ {
+ hints &= ~INLINE_HINT_builtin_constant_p;
+ fprintf (f, " builtin_constant_p");
+ }
gcc_assert (!hints);
}
vec_free (call_size_time_table);
vec_free (loop_iterations);
vec_free (loop_strides);
+ builtin_constant_p_parms.release ();
}
void
new_predicate = es->predicate->remap_after_duplication
(possible_truths);
if (new_predicate == false && *es->predicate != false)
- optimized_out_size += es->call_stmt_size * ipa_fn_summary::size_scale;
+ optimized_out_size
+ += es->call_stmt_size * ipa_fn_summary::size_scale;
edge_set_predicate (edge, &new_predicate);
}
info->loop_iterations
info->loop_strides
= remap_freqcounting_preds_after_dup (info->loop_strides,
possible_truths);
+ if (info->builtin_constant_p_parms.length())
+ {
+ vec <int, va_heap, vl_ptr> parms = info->builtin_constant_p_parms;
+ int ip;
+ info->builtin_constant_p_parms = vNULL;
+ for (i = 0; parms.iterate (i, &ip); i++)
+ if (!avals.m_known_vals[ip])
+ info->builtin_constant_p_parms.safe_push (ip);
+ }
/* If inliner or someone after inliner will ever start producing
non-trivial clones, we will get trouble with lack of information
info->loop_iterations = vec_safe_copy (info->loop_iterations);
info->loop_strides = vec_safe_copy (info->loop_strides);
+ info->builtin_constant_p_parms
+ = info->builtin_constant_p_parms.copy ();
+
ipa_freqcounting_predicate *f;
for (int i = 0; vec_safe_iterate (info->loop_iterations, i, &f); i++)
{
fprintf (f, " inlinable");
if (s->fp_expressions)
fprintf (f, " fp_expression");
+ if (s->builtin_constant_p_parms.length ())
+ {
+ fprintf (f, " builtin_constant_p_parms");
+ for (unsigned int i = 0;
+ i < s->builtin_constant_p_parms.length (); i++)
+ fprintf (f, " %i", s->builtin_constant_p_parms[i]);
+ }
fprintf (f, "\n global time: %f\n", s->time.to_double ());
fprintf (f, " self size: %i\n", ss->self_size);
fprintf (f, " global size: %i\n", ss->size);
return false;
}
+/* Record to SUMMARY that PARM is used by builtin_constant_p. */
+
+static void
+add_builtin_constant_p_parm (class ipa_fn_summary *summary, int parm)
+{
+ int ip;
+
+ /* Avoid duplicates. */
+ for (unsigned int i = 0;
+ summary->builtin_constant_p_parms.iterate (i, &ip); i++)
+ if (ip == parm)
+ return;
+ summary->builtin_constant_p_parms.safe_push (parm);
+}
+
/* If BB ends by a conditional we can turn into predicates, attach corresponding
predicates to the CFG edges. */
op2 = gimple_call_arg (set_stmt, 0);
if (!decompose_param_expr (fbi, set_stmt, op2, &index, ¶m_type, &aggpos))
return;
+ if (!aggpos.by_ref)
+ add_builtin_constant_p_parm (summary, index);
FOR_EACH_EDGE (e, ei, bb->succs) if (e->flags & EDGE_FALSE_VALUE)
{
predicate p = add_condition (summary, params_summary, index,
hints |= INLINE_HINT_in_scc;
if (DECL_DECLARED_INLINE_P (m_node->decl))
hints |= INLINE_HINT_declared_inline;
+ if (info->builtin_constant_p_parms.length ()
+ && DECL_DECLARED_INLINE_P (m_node->decl))
+ hints |= INLINE_HINT_builtin_constant_p;
ipa_freqcounting_predicate *fcp;
for (i = 0; vec_safe_iterate (info->loop_iterations, i, &fcp); i++)
operand_map[i] = map;
gcc_assert (map < ipa_get_param_count (params_summary));
}
+
+ int ip;
+ for (i = 0; callee_info->builtin_constant_p_parms.iterate (i, &ip); i++)
+ if (ip < count && operand_map[ip] >= 0)
+ add_builtin_constant_p_parm (info, operand_map[ip]);
}
- sreal freq = edge->sreal_frequency ();
+ sreal freq = edge->sreal_frequency ();
for (i = 0; vec_safe_iterate (callee_info->size_time_table, i, &e); i++)
{
predicate p;
vec_safe_push (info->loop_strides, fcp);
}
}
+ count2 = streamer_read_uhwi (&ib);
+ if (info && count2)
+ info->builtin_constant_p_parms.reserve_exact (count2);
+ for (j = 0; j < count2; j++)
+ {
+ int parm = streamer_read_uhwi (&ib);
+ if (info)
+ info->builtin_constant_p_parms.quick_push (parm);
+ }
for (e = node->callees; e; e = e->next_callee)
read_ipa_call_summary (&ib, e, info != NULL);
for (e = node->indirect_calls; e; e = e->next_callee)
fcp->predicate->stream_out (ob);
fcp->freq.stream_out (ob);
}
+ streamer_write_uhwi (ob, info->builtin_constant_p_parms.length ());
+ int ip;
+ for (i = 0; info->builtin_constant_p_parms.iterate (i, &ip);
+ i++)
+ streamer_write_uhwi (ob, ip);
for (edge = cnode->callees; edge; edge = edge->next_callee)
write_ipa_call_summary (ob, edge);
for (edge = cnode->indirect_calls; edge; edge = edge->next_callee)
Set by simple_edge_hints in ipa-inline-analysis.c. */
INLINE_HINT_cross_module = 64,
/* We know that the callee is hot by profile. */
- INLINE_HINT_known_hot = 128
+ INLINE_HINT_known_hot = 128,
+ /* There is builtin_constant_p dependent on parameter which is usually
+ a strong hint to inline. */
+ INLINE_HINT_builtin_constant_p = 256
};
typedef int ipa_hints;
ipa_fn_summary ()
: min_size (0),
inlinable (false), single_caller (false),
- fp_expressions (false), estimated_stack_size (false),
+ fp_expressions (false),
+ estimated_stack_size (false),
time (0), conds (NULL),
size_time_table (NULL), call_size_time_table (NULL),
loop_iterations (NULL), loop_strides (NULL),
+ builtin_constant_p_parms (vNULL),
growth (0), scc_no (0)
{
}
time (s.time), conds (s.conds), size_time_table (s.size_time_table),
call_size_time_table (NULL),
loop_iterations (s.loop_iterations), loop_strides (s.loop_strides),
+ builtin_constant_p_parms (s.builtin_constant_p_parms),
growth (s.growth), scc_no (s.scc_no)
{}
vec<ipa_freqcounting_predicate, va_gc> *loop_iterations;
/* Predicates on when some loops in the function can have known strides. */
vec<ipa_freqcounting_predicate, va_gc> *loop_strides;
+ /* Parameters tested by builtin_constant_p. */
+ vec<int, va_heap, vl_ptr> GTY((skip)) builtin_constant_p_parms;
/* Estimated growth for inlining all copies of the function before start
of small functions inlining.
This value will get out of date as the callers are duplicated, but