1 /* Function summary pass.
2    Copyright (C) 2003-2019 Free Software Foundation, Inc.
3    Contributed by Jan Hubicka
4 
5 This file is part of GCC.
6 
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
11 
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3.  If not see
19 <http://www.gnu.org/licenses/>.  */
20 
21 /* Analysis of function bodies used by inter-procedural passes
22 
23    We estimate for each function
24      - function body size and size after specializing into given context
25      - average function execution time in a given context
26      - function frame size
27    For each call
28      - call statement size, time and how often the parameters change
29 
30    ipa_fn_summary data structures store above information locally (i.e.
31    parameters of the function itself) and globally (i.e. parameters of
32    the function created by applying all the inline decisions already
33    present in the callgraph).
34 
35    We provide access to the ipa_fn_summary data structure and
36    basic logic updating the parameters when inlining is performed.
37 
38    The summaries are context sensitive.  Context means
39      1) partial assignment of known constant values of operands
40      2) whether function is inlined into the call or not.
41    It is easy to add more variants.  To represent function size and time
42    that depends on context (i.e. it is known to be optimized away when
43    context is known either by inlining or from IP-CP and cloning),
44    we use predicates.
45 
46    estimate_edge_size_and_time can be used to query
47    function size/time in the given context.  ipa_merge_fn_summary_after_inlining merges
48    properties of caller and callee after inlining.
49 
50    Finally pass_inline_parameters is exported.  This is used to drive
51    computation of function parameters used by the early inliner. IPA
52    inlined performs analysis via its analyze_function method. */
53 
54 #include "config.h"
55 #include "system.h"
56 #include "coretypes.h"
57 #include "backend.h"
58 #include "tree.h"
59 #include "gimple.h"
60 #include "alloc-pool.h"
61 #include "tree-pass.h"
62 #include "ssa.h"
63 #include "tree-streamer.h"
64 #include "cgraph.h"
65 #include "diagnostic.h"
66 #include "fold-const.h"
67 #include "print-tree.h"
68 #include "tree-inline.h"
69 #include "gimple-pretty-print.h"
70 #include "params.h"
71 #include "cfganal.h"
72 #include "gimple-iterator.h"
73 #include "tree-cfg.h"
74 #include "tree-ssa-loop-niter.h"
75 #include "tree-ssa-loop.h"
76 #include "symbol-summary.h"
77 #include "ipa-prop.h"
78 #include "ipa-fnsummary.h"
79 #include "cfgloop.h"
80 #include "tree-scalar-evolution.h"
81 #include "ipa-utils.h"
82 #include "cfgexpand.h"
83 #include "gimplify.h"
84 #include "stringpool.h"
85 #include "attribs.h"
86 
87 /* Summaries.  */
88 fast_function_summary <ipa_fn_summary *, va_gc> *ipa_fn_summaries;
89 fast_call_summary <ipa_call_summary *, va_heap> *ipa_call_summaries;
90 
91 /* Edge predicates goes here.  */
92 static object_allocator<predicate> edge_predicate_pool ("edge predicates");
93 
94 
95 /* Dump IPA hints.  */
96 void
ipa_dump_hints(FILE * f,ipa_hints hints)97 ipa_dump_hints (FILE *f, ipa_hints hints)
98 {
99   if (!hints)
100     return;
101   fprintf (f, "IPA hints:");
102   if (hints & INLINE_HINT_indirect_call)
103     {
104       hints &= ~INLINE_HINT_indirect_call;
105       fprintf (f, " indirect_call");
106     }
107   if (hints & INLINE_HINT_loop_iterations)
108     {
109       hints &= ~INLINE_HINT_loop_iterations;
110       fprintf (f, " loop_iterations");
111     }
112   if (hints & INLINE_HINT_loop_stride)
113     {
114       hints &= ~INLINE_HINT_loop_stride;
115       fprintf (f, " loop_stride");
116     }
117   if (hints & INLINE_HINT_same_scc)
118     {
119       hints &= ~INLINE_HINT_same_scc;
120       fprintf (f, " same_scc");
121     }
122   if (hints & INLINE_HINT_in_scc)
123     {
124       hints &= ~INLINE_HINT_in_scc;
125       fprintf (f, " in_scc");
126     }
127   if (hints & INLINE_HINT_cross_module)
128     {
129       hints &= ~INLINE_HINT_cross_module;
130       fprintf (f, " cross_module");
131     }
132   if (hints & INLINE_HINT_declared_inline)
133     {
134       hints &= ~INLINE_HINT_declared_inline;
135       fprintf (f, " declared_inline");
136     }
137   if (hints & INLINE_HINT_array_index)
138     {
139       hints &= ~INLINE_HINT_array_index;
140       fprintf (f, " array_index");
141     }
142   if (hints & INLINE_HINT_known_hot)
143     {
144       hints &= ~INLINE_HINT_known_hot;
145       fprintf (f, " known_hot");
146     }
147   gcc_assert (!hints);
148 }
149 
150 
151 /* Record SIZE and TIME to SUMMARY.
152    The accounted code will be executed when EXEC_PRED is true.
153    When NONCONST_PRED is false the code will evaulate to constant and
154    will get optimized out in specialized clones of the function.   */
155 
156 void
account_size_time(int size,sreal time,const predicate & exec_pred,const predicate & nonconst_pred_in)157 ipa_fn_summary::account_size_time (int size, sreal time,
158 				   const predicate &exec_pred,
159 				   const predicate &nonconst_pred_in)
160 {
161   size_time_entry *e;
162   bool found = false;
163   int i;
164   predicate nonconst_pred;
165 
166   if (exec_pred == false)
167     return;
168 
169   nonconst_pred = nonconst_pred_in & exec_pred;
170 
171   if (nonconst_pred == false)
172     return;
173 
174   /* We need to create initial empty unconitional clause, but otherwie
175      we don't need to account empty times and sizes.  */
176   if (!size && time == 0 && size_time_table)
177     return;
178 
179   gcc_assert (time >= 0);
180 
181   for (i = 0; vec_safe_iterate (size_time_table, i, &e); i++)
182     if (e->exec_predicate == exec_pred
183 	&& e->nonconst_predicate == nonconst_pred)
184       {
185 	found = true;
186 	break;
187       }
188   if (i == 256)
189     {
190       i = 0;
191       found = true;
192       e = &(*size_time_table)[0];
193       if (dump_file && (dump_flags & TDF_DETAILS))
194 	fprintf (dump_file,
195 		 "\t\tReached limit on number of entries, "
196 		 "ignoring the predicate.");
197     }
198   if (dump_file && (dump_flags & TDF_DETAILS) && (time != 0 || size))
199     {
200       fprintf (dump_file,
201 	       "\t\tAccounting size:%3.2f, time:%3.2f on %spredicate exec:",
202 	       ((double) size) / ipa_fn_summary::size_scale,
203 	       (time.to_double ()), found ? "" : "new ");
204       exec_pred.dump (dump_file, conds, 0);
205       if (exec_pred != nonconst_pred)
206 	{
207           fprintf (dump_file, " nonconst:");
208           nonconst_pred.dump (dump_file, conds);
209 	}
210       else
211         fprintf (dump_file, "\n");
212     }
213   if (!found)
214     {
215       struct size_time_entry new_entry;
216       new_entry.size = size;
217       new_entry.time = time;
218       new_entry.exec_predicate = exec_pred;
219       new_entry.nonconst_predicate = nonconst_pred;
220       vec_safe_push (size_time_table, new_entry);
221     }
222   else
223     {
224       e->size += size;
225       e->time += time;
226     }
227 }
228 
229 /* We proved E to be unreachable, redirect it to __bultin_unreachable.  */
230 
231 static struct cgraph_edge *
redirect_to_unreachable(struct cgraph_edge * e)232 redirect_to_unreachable (struct cgraph_edge *e)
233 {
234   struct cgraph_node *callee = !e->inline_failed ? e->callee : NULL;
235   struct cgraph_node *target = cgraph_node::get_create
236 		      (builtin_decl_implicit (BUILT_IN_UNREACHABLE));
237 
238   if (e->speculative)
239     e = e->resolve_speculation (target->decl);
240   else if (!e->callee)
241     e->make_direct (target);
242   else
243     e->redirect_callee (target);
244   struct ipa_call_summary *es = ipa_call_summaries->get (e);
245   e->inline_failed = CIF_UNREACHABLE;
246   e->count = profile_count::zero ();
247   es->call_stmt_size = 0;
248   es->call_stmt_time = 0;
249   if (callee)
250     callee->remove_symbol_and_inline_clones ();
251   return e;
252 }
253 
254 /* Set predicate for edge E.  */
255 
256 static void
edge_set_predicate(struct cgraph_edge * e,predicate * predicate)257 edge_set_predicate (struct cgraph_edge *e, predicate *predicate)
258 {
259   /* If the edge is determined to be never executed, redirect it
260      to BUILTIN_UNREACHABLE to make it clear to IPA passes the call will
261      be optimized out.  */
262   if (predicate && *predicate == false
263       /* When handling speculative edges, we need to do the redirection
264          just once.  Do it always on the direct edge, so we do not
265 	 attempt to resolve speculation while duplicating the edge.  */
266       && (!e->speculative || e->callee))
267     e = redirect_to_unreachable (e);
268 
269   struct ipa_call_summary *es = ipa_call_summaries->get (e);
270   if (predicate && *predicate != true)
271     {
272       if (!es->predicate)
273 	es->predicate = edge_predicate_pool.allocate ();
274       *es->predicate = *predicate;
275     }
276   else
277     {
278       if (es->predicate)
279 	edge_predicate_pool.remove (es->predicate);
280       es->predicate = NULL;
281     }
282 }
283 
284 /* Set predicate for hint *P.  */
285 
286 static void
set_hint_predicate(predicate ** p,predicate new_predicate)287 set_hint_predicate (predicate **p, predicate new_predicate)
288 {
289   if (new_predicate == false || new_predicate == true)
290     {
291       if (*p)
292 	edge_predicate_pool.remove (*p);
293       *p = NULL;
294     }
295   else
296     {
297       if (!*p)
298 	*p = edge_predicate_pool.allocate ();
299       **p = new_predicate;
300     }
301 }
302 
303 
304 /* Compute what conditions may or may not hold given invormation about
305    parameters.  RET_CLAUSE returns truths that may hold in a specialized copy,
306    whie RET_NONSPEC_CLAUSE returns truths that may hold in an nonspecialized
307    copy when called in a given context.  It is a bitmask of conditions. Bit
308    0 means that condition is known to be false, while bit 1 means that condition
309    may or may not be true.  These differs - for example NOT_INLINED condition
310    is always false in the second and also builtin_constant_p tests cannot use
311    the fact that parameter is indeed a constant.
312 
313    KNOWN_VALS is partial mapping of parameters of NODE to constant values.
314    KNOWN_AGGS is a vector of aggreggate jump functions for each parameter.
315    Return clause of possible truths. When INLINE_P is true, assume that we are
316    inlining.
317 
318    ERROR_MARK means compile time invariant.  */
319 
320 static void
evaluate_conditions_for_known_args(struct cgraph_node * node,bool inline_p,vec<tree> known_vals,vec<ipa_agg_jump_function_p> known_aggs,clause_t * ret_clause,clause_t * ret_nonspec_clause)321 evaluate_conditions_for_known_args (struct cgraph_node *node,
322 				    bool inline_p,
323 				    vec<tree> known_vals,
324 				    vec<ipa_agg_jump_function_p>
325 				    known_aggs,
326 				    clause_t *ret_clause,
327 				    clause_t *ret_nonspec_clause)
328 {
329   clause_t clause = inline_p ? 0 : 1 << predicate::not_inlined_condition;
330   clause_t nonspec_clause = 1 << predicate::not_inlined_condition;
331   struct ipa_fn_summary *info = ipa_fn_summaries->get (node);
332   int i;
333   struct condition *c;
334 
335   for (i = 0; vec_safe_iterate (info->conds, i, &c); i++)
336     {
337       tree val;
338       tree res;
339 
340       /* We allow call stmt to have fewer arguments than the callee function
341          (especially for K&R style programs).  So bound check here (we assume
342          known_aggs vector, if non-NULL, has the same length as
343          known_vals).  */
344       gcc_checking_assert (!known_aggs.exists ()
345 			   || (known_vals.length () == known_aggs.length ()));
346       if (c->operand_num >= (int) known_vals.length ())
347 	{
348 	  clause |= 1 << (i + predicate::first_dynamic_condition);
349 	  nonspec_clause |= 1 << (i + predicate::first_dynamic_condition);
350 	  continue;
351 	}
352 
353       if (c->agg_contents)
354 	{
355 	  struct ipa_agg_jump_function *agg;
356 
357 	  if (c->code == predicate::changed
358 	      && !c->by_ref
359 	      && (known_vals[c->operand_num] == error_mark_node))
360 	    continue;
361 
362 	  if (known_aggs.exists ())
363 	    {
364 	      agg = known_aggs[c->operand_num];
365 	      val = ipa_find_agg_cst_for_param (agg, known_vals[c->operand_num],
366 						c->offset, c->by_ref);
367 	    }
368 	  else
369 	    val = NULL_TREE;
370 	}
371       else
372 	{
373 	  val = known_vals[c->operand_num];
374 	  if (val == error_mark_node && c->code != predicate::changed)
375 	    val = NULL_TREE;
376 	}
377 
378       if (!val)
379 	{
380 	  clause |= 1 << (i + predicate::first_dynamic_condition);
381 	  nonspec_clause |= 1 << (i + predicate::first_dynamic_condition);
382 	  continue;
383 	}
384       if (c->code == predicate::changed)
385 	{
386 	  nonspec_clause |= 1 << (i + predicate::first_dynamic_condition);
387 	  continue;
388 	}
389 
390       if (tree_to_shwi (TYPE_SIZE (TREE_TYPE (val))) != c->size)
391 	{
392 	  clause |= 1 << (i + predicate::first_dynamic_condition);
393 	  nonspec_clause |= 1 << (i + predicate::first_dynamic_condition);
394 	  continue;
395 	}
396       if (c->code == predicate::is_not_constant)
397 	{
398 	  nonspec_clause |= 1 << (i + predicate::first_dynamic_condition);
399 	  continue;
400 	}
401 
402       val = fold_unary (VIEW_CONVERT_EXPR, TREE_TYPE (c->val), val);
403       res = val
404 	? fold_binary_to_constant (c->code, boolean_type_node, val, c->val)
405 	: NULL;
406 
407       if (res && integer_zerop (res))
408 	continue;
409 
410       clause |= 1 << (i + predicate::first_dynamic_condition);
411       nonspec_clause |= 1 << (i + predicate::first_dynamic_condition);
412     }
413   *ret_clause = clause;
414   if (ret_nonspec_clause)
415     *ret_nonspec_clause = nonspec_clause;
416 }
417 
418 
419 /* Work out what conditions might be true at invocation of E.  */
420 
421 void
evaluate_properties_for_edge(struct cgraph_edge * e,bool inline_p,clause_t * clause_ptr,clause_t * nonspec_clause_ptr,vec<tree> * known_vals_ptr,vec<ipa_polymorphic_call_context> * known_contexts_ptr,vec<ipa_agg_jump_function_p> * known_aggs_ptr)422 evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
423 			      clause_t *clause_ptr,
424 			      clause_t *nonspec_clause_ptr,
425 			      vec<tree> *known_vals_ptr,
426 			      vec<ipa_polymorphic_call_context>
427 			      *known_contexts_ptr,
428 			      vec<ipa_agg_jump_function_p> *known_aggs_ptr)
429 {
430   struct cgraph_node *callee = e->callee->ultimate_alias_target ();
431   struct ipa_fn_summary *info = ipa_fn_summaries->get (callee);
432   vec<tree> known_vals = vNULL;
433   vec<ipa_agg_jump_function_p> known_aggs = vNULL;
434 
435   if (clause_ptr)
436     *clause_ptr = inline_p ? 0 : 1 << predicate::not_inlined_condition;
437   if (known_vals_ptr)
438     known_vals_ptr->create (0);
439   if (known_contexts_ptr)
440     known_contexts_ptr->create (0);
441 
442   if (ipa_node_params_sum
443       && !e->call_stmt_cannot_inline_p
444       && ((clause_ptr && info->conds) || known_vals_ptr || known_contexts_ptr))
445     {
446       struct ipa_node_params *caller_parms_info, *callee_pi;
447       struct ipa_edge_args *args = IPA_EDGE_REF (e);
448       struct ipa_call_summary *es = ipa_call_summaries->get (e);
449       int i, count = ipa_get_cs_argument_count (args);
450 
451       if (e->caller->global.inlined_to)
452 	caller_parms_info = IPA_NODE_REF (e->caller->global.inlined_to);
453       else
454 	caller_parms_info = IPA_NODE_REF (e->caller);
455       callee_pi = IPA_NODE_REF (e->callee);
456 
457       if (count && (info->conds || known_vals_ptr))
458 	known_vals.safe_grow_cleared (count);
459       if (count && (info->conds || known_aggs_ptr))
460 	known_aggs.safe_grow_cleared (count);
461       if (count && known_contexts_ptr)
462 	known_contexts_ptr->safe_grow_cleared (count);
463 
464       for (i = 0; i < count; i++)
465 	{
466 	  struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
467 	  tree cst = ipa_value_from_jfunc (caller_parms_info, jf,
468 					   ipa_get_type (callee_pi, i));
469 
470 	  if (!cst && e->call_stmt
471 	      && i < (int)gimple_call_num_args (e->call_stmt))
472 	    {
473 	      cst = gimple_call_arg (e->call_stmt, i);
474 	      if (!is_gimple_min_invariant (cst))
475 		cst = NULL;
476 	    }
477 	  if (cst)
478 	    {
479 	      gcc_checking_assert (TREE_CODE (cst) != TREE_BINFO);
480 	      if (known_vals.exists ())
481 		known_vals[i] = cst;
482 	    }
483 	  else if (inline_p && !es->param[i].change_prob)
484 	    known_vals[i] = error_mark_node;
485 
486 	  if (known_contexts_ptr)
487 	    (*known_contexts_ptr)[i]
488 	      = ipa_context_from_jfunc (caller_parms_info, e, i, jf);
489 	  /* TODO: When IPA-CP starts propagating and merging aggregate jump
490 	     functions, use its knowledge of the caller too, just like the
491 	     scalar case above.  */
492 	  known_aggs[i] = &jf->agg;
493 	}
494     }
495   else if (e->call_stmt && !e->call_stmt_cannot_inline_p
496 	   && ((clause_ptr && info->conds) || known_vals_ptr))
497     {
498       int i, count = (int)gimple_call_num_args (e->call_stmt);
499 
500       if (count && (info->conds || known_vals_ptr))
501 	known_vals.safe_grow_cleared (count);
502       for (i = 0; i < count; i++)
503 	{
504 	  tree cst = gimple_call_arg (e->call_stmt, i);
505 	  if (!is_gimple_min_invariant (cst))
506 	    cst = NULL;
507 	  if (cst)
508 	    known_vals[i] = cst;
509 	}
510     }
511 
512   evaluate_conditions_for_known_args (callee, inline_p,
513 				      known_vals, known_aggs, clause_ptr,
514 				      nonspec_clause_ptr);
515 
516   if (known_vals_ptr)
517     *known_vals_ptr = known_vals;
518   else
519     known_vals.release ();
520 
521   if (known_aggs_ptr)
522     *known_aggs_ptr = known_aggs;
523   else
524     known_aggs.release ();
525 }
526 
527 
528 /* Allocate the function summary. */
529 
530 static void
ipa_fn_summary_alloc(void)531 ipa_fn_summary_alloc (void)
532 {
533   gcc_checking_assert (!ipa_fn_summaries);
534   ipa_fn_summaries = ipa_fn_summary_t::create_ggc (symtab);
535   ipa_call_summaries = new ipa_call_summary_t (symtab);
536 }
537 
~ipa_call_summary()538 ipa_call_summary::~ipa_call_summary ()
539 {
540   if (predicate)
541     edge_predicate_pool.remove (predicate);
542 
543   param.release ();
544 }
545 
~ipa_fn_summary()546 ipa_fn_summary::~ipa_fn_summary ()
547 {
548   if (loop_iterations)
549     edge_predicate_pool.remove (loop_iterations);
550   if (loop_stride)
551     edge_predicate_pool.remove (loop_stride);
552   if (array_index)
553     edge_predicate_pool.remove (array_index);
554   vec_free (conds);
555   vec_free (size_time_table);
556 }
557 
558 void
remove_callees(cgraph_node * node)559 ipa_fn_summary_t::remove_callees (cgraph_node *node)
560 {
561   cgraph_edge *e;
562   for (e = node->callees; e; e = e->next_callee)
563     ipa_call_summaries->remove (e);
564   for (e = node->indirect_calls; e; e = e->next_callee)
565     ipa_call_summaries->remove (e);
566 }
567 
568 /* Same as remap_predicate_after_duplication but handle hint predicate *P.
569    Additionally care about allocating new memory slot for updated predicate
570    and set it to NULL when it becomes true or false (and thus uninteresting).
571  */
572 
573 static void
remap_hint_predicate_after_duplication(predicate ** p,clause_t possible_truths)574 remap_hint_predicate_after_duplication (predicate **p,
575 					clause_t possible_truths)
576 {
577   predicate new_predicate;
578 
579   if (!*p)
580     return;
581 
582   new_predicate = (*p)->remap_after_duplication (possible_truths);
583   /* We do not want to free previous predicate; it is used by node origin.  */
584   *p = NULL;
585   set_hint_predicate (p, new_predicate);
586 }
587 
588 
589 /* Hook that is called by cgraph.c when a node is duplicated.  */
590 void
duplicate(cgraph_node * src,cgraph_node * dst,ipa_fn_summary *,ipa_fn_summary * info)591 ipa_fn_summary_t::duplicate (cgraph_node *src,
592 			     cgraph_node *dst,
593 			     ipa_fn_summary *,
594 			     ipa_fn_summary *info)
595 {
596   new (info) ipa_fn_summary (*ipa_fn_summaries->get (src));
597   /* TODO: as an optimization, we may avoid copying conditions
598      that are known to be false or true.  */
599   info->conds = vec_safe_copy (info->conds);
600 
601   /* When there are any replacements in the function body, see if we can figure
602      out that something was optimized out.  */
603   if (ipa_node_params_sum && dst->clone.tree_map)
604     {
605       vec<size_time_entry, va_gc> *entry = info->size_time_table;
606       /* Use SRC parm info since it may not be copied yet.  */
607       struct ipa_node_params *parms_info = IPA_NODE_REF (src);
608       vec<tree> known_vals = vNULL;
609       int count = ipa_get_param_count (parms_info);
610       int i, j;
611       clause_t possible_truths;
612       predicate true_pred = true;
613       size_time_entry *e;
614       int optimized_out_size = 0;
615       bool inlined_to_p = false;
616       struct cgraph_edge *edge, *next;
617 
618       info->size_time_table = 0;
619       known_vals.safe_grow_cleared (count);
620       for (i = 0; i < count; i++)
621 	{
622 	  struct ipa_replace_map *r;
623 
624 	  for (j = 0; vec_safe_iterate (dst->clone.tree_map, j, &r); j++)
625 	    {
626 	      if (((!r->old_tree && r->parm_num == i)
627 		   || (r->old_tree && r->old_tree == ipa_get_param (parms_info, i)))
628 		   && r->replace_p && !r->ref_p)
629 		{
630 		  known_vals[i] = r->new_tree;
631 		  break;
632 		}
633 	    }
634 	}
635       evaluate_conditions_for_known_args (dst, false,
636 					  known_vals,
637 					  vNULL,
638 					  &possible_truths,
639 					  /* We are going to specialize,
640 					     so ignore nonspec truths.  */
641 					  NULL);
642       known_vals.release ();
643 
644       info->account_size_time (0, 0, true_pred, true_pred);
645 
646       /* Remap size_time vectors.
647          Simplify the predicate by prunning out alternatives that are known
648          to be false.
649          TODO: as on optimization, we can also eliminate conditions known
650          to be true.  */
651       for (i = 0; vec_safe_iterate (entry, i, &e); i++)
652 	{
653 	  predicate new_exec_pred;
654 	  predicate new_nonconst_pred;
655 	  new_exec_pred = e->exec_predicate.remap_after_duplication
656 				 (possible_truths);
657 	  new_nonconst_pred = e->nonconst_predicate.remap_after_duplication
658 		  		 (possible_truths);
659 	  if (new_exec_pred == false || new_nonconst_pred == false)
660 	    optimized_out_size += e->size;
661 	  else
662 	    info->account_size_time (e->size, e->time, new_exec_pred,
663 			             new_nonconst_pred);
664 	}
665 
666       /* Remap edge predicates with the same simplification as above.
667          Also copy constantness arrays.   */
668       for (edge = dst->callees; edge; edge = next)
669 	{
670 	  predicate new_predicate;
671 	  struct ipa_call_summary *es = ipa_call_summaries->get_create (edge);
672 	  next = edge->next_callee;
673 
674 	  if (!edge->inline_failed)
675 	    inlined_to_p = true;
676 	  if (!es->predicate)
677 	    continue;
678 	  new_predicate = es->predicate->remap_after_duplication
679 	    (possible_truths);
680 	  if (new_predicate == false && *es->predicate != false)
681 	    optimized_out_size += es->call_stmt_size * ipa_fn_summary::size_scale;
682 	  edge_set_predicate (edge, &new_predicate);
683 	}
684 
685       /* Remap indirect edge predicates with the same simplificaiton as above.
686          Also copy constantness arrays.   */
687       for (edge = dst->indirect_calls; edge; edge = next)
688 	{
689 	  predicate new_predicate;
690 	  struct ipa_call_summary *es = ipa_call_summaries->get_create (edge);
691 	  next = edge->next_callee;
692 
693 	  gcc_checking_assert (edge->inline_failed);
694 	  if (!es->predicate)
695 	    continue;
696 	  new_predicate = es->predicate->remap_after_duplication
697 				 (possible_truths);
698 	  if (new_predicate == false && *es->predicate != false)
699 	    optimized_out_size += es->call_stmt_size * ipa_fn_summary::size_scale;
700 	  edge_set_predicate (edge, &new_predicate);
701 	}
702       remap_hint_predicate_after_duplication (&info->loop_iterations,
703 					      possible_truths);
704       remap_hint_predicate_after_duplication (&info->loop_stride,
705 					      possible_truths);
706       remap_hint_predicate_after_duplication (&info->array_index,
707 					      possible_truths);
708 
709       /* If inliner or someone after inliner will ever start producing
710          non-trivial clones, we will get trouble with lack of information
711          about updating self sizes, because size vectors already contains
712          sizes of the calees.  */
713       gcc_assert (!inlined_to_p || !optimized_out_size);
714     }
715   else
716     {
717       info->size_time_table = vec_safe_copy (info->size_time_table);
718       if (info->loop_iterations)
719 	{
720 	  predicate p = *info->loop_iterations;
721 	  info->loop_iterations = NULL;
722 	  set_hint_predicate (&info->loop_iterations, p);
723 	}
724       if (info->loop_stride)
725 	{
726 	  predicate p = *info->loop_stride;
727 	  info->loop_stride = NULL;
728 	  set_hint_predicate (&info->loop_stride, p);
729 	}
730       if (info->array_index)
731 	{
732 	  predicate p = *info->array_index;
733 	  info->array_index = NULL;
734 	  set_hint_predicate (&info->array_index, p);
735 	}
736     }
737   if (!dst->global.inlined_to)
738     ipa_update_overall_fn_summary (dst);
739 }
740 
741 
742 /* Hook that is called by cgraph.c when a node is duplicated.  */
743 
744 void
duplicate(struct cgraph_edge * src,struct cgraph_edge * dst,struct ipa_call_summary * srcinfo,struct ipa_call_summary * info)745 ipa_call_summary_t::duplicate (struct cgraph_edge *src,
746 			       struct cgraph_edge *dst,
747 			       struct ipa_call_summary *srcinfo,
748 			       struct ipa_call_summary *info)
749 {
750   new (info) ipa_call_summary (*srcinfo);
751   info->predicate = NULL;
752   edge_set_predicate (dst, srcinfo->predicate);
753   info->param = srcinfo->param.copy ();
754   if (!dst->indirect_unknown_callee && src->indirect_unknown_callee)
755     {
756       info->call_stmt_size -= (eni_size_weights.indirect_call_cost
757 			       - eni_size_weights.call_cost);
758       info->call_stmt_time -= (eni_time_weights.indirect_call_cost
759 			       - eni_time_weights.call_cost);
760     }
761 }
762 
763 /* Dump edge summaries associated to NODE and recursively to all clones.
764    Indent by INDENT.  */
765 
766 static void
dump_ipa_call_summary(FILE * f,int indent,struct cgraph_node * node,struct ipa_fn_summary * info)767 dump_ipa_call_summary (FILE *f, int indent, struct cgraph_node *node,
768 		       struct ipa_fn_summary *info)
769 {
770   struct cgraph_edge *edge;
771   for (edge = node->callees; edge; edge = edge->next_callee)
772     {
773       struct ipa_call_summary *es = ipa_call_summaries->get (edge);
774       struct cgraph_node *callee = edge->callee->ultimate_alias_target ();
775       int i;
776 
777       fprintf (f,
778 	       "%*s%s/%i %s\n%*s  loop depth:%2i freq:%4.2f size:%2i time: %2i",
779 	       indent, "", callee->name (), callee->order,
780 	       !edge->inline_failed
781 	       ? "inlined" : cgraph_inline_failed_string (edge-> inline_failed),
782 	       indent, "", es->loop_depth, edge->sreal_frequency ().to_double (),
783 	       es->call_stmt_size, es->call_stmt_time);
784 
785       ipa_fn_summary *s = ipa_fn_summaries->get (callee);
786       if (s != NULL)
787 	fprintf (f, "callee size:%2i stack:%2i",
788 		 (int) (s->size / ipa_fn_summary::size_scale),
789 		 (int) s->estimated_stack_size);
790 
791       if (es->predicate)
792 	{
793 	  fprintf (f, " predicate: ");
794 	  es->predicate->dump (f, info->conds);
795 	}
796       else
797 	fprintf (f, "\n");
798       if (es->param.exists ())
799 	for (i = 0; i < (int) es->param.length (); i++)
800 	  {
801 	    int prob = es->param[i].change_prob;
802 
803 	    if (!prob)
804 	      fprintf (f, "%*s op%i is compile time invariant\n",
805 		       indent + 2, "", i);
806 	    else if (prob != REG_BR_PROB_BASE)
807 	      fprintf (f, "%*s op%i change %f%% of time\n", indent + 2, "", i,
808 		       prob * 100.0 / REG_BR_PROB_BASE);
809 	  }
810       if (!edge->inline_failed)
811 	{
812 	  ipa_fn_summary *s = ipa_fn_summaries->get (callee);
813 	  fprintf (f, "%*sStack frame offset %i, callee self size %i,"
814 		   " callee size %i\n",
815 		   indent + 2, "",
816 		   (int) s->stack_frame_offset,
817 		   (int) s->estimated_self_stack_size,
818 		   (int) s->estimated_stack_size);
819 	  dump_ipa_call_summary (f, indent + 2, callee, info);
820 	}
821     }
822   for (edge = node->indirect_calls; edge; edge = edge->next_callee)
823     {
824       struct ipa_call_summary *es = ipa_call_summaries->get (edge);
825       fprintf (f, "%*sindirect call loop depth:%2i freq:%4.2f size:%2i"
826 	       " time: %2i",
827 	       indent, "",
828 	       es->loop_depth,
829 	       edge->sreal_frequency ().to_double (), es->call_stmt_size,
830 	       es->call_stmt_time);
831       if (es->predicate)
832 	{
833 	  fprintf (f, "predicate: ");
834 	  es->predicate->dump (f, info->conds);
835 	}
836       else
837 	fprintf (f, "\n");
838     }
839 }
840 
841 
842 void
ipa_dump_fn_summary(FILE * f,struct cgraph_node * node)843 ipa_dump_fn_summary (FILE *f, struct cgraph_node *node)
844 {
845   if (node->definition)
846     {
847       struct ipa_fn_summary *s = ipa_fn_summaries->get (node);
848       if (s != NULL)
849 	{
850 	  size_time_entry *e;
851 	  int i;
852 	  fprintf (f, "IPA function summary for %s", node->dump_name ());
853 	  if (DECL_DISREGARD_INLINE_LIMITS (node->decl))
854 	    fprintf (f, " always_inline");
855 	  if (s->inlinable)
856 	    fprintf (f, " inlinable");
857 	  if (s->fp_expressions)
858 	    fprintf (f, " fp_expression");
859 	  fprintf (f, "\n  global time:     %f\n", s->time.to_double ());
860 	  fprintf (f, "  self size:       %i\n", s->self_size);
861 	  fprintf (f, "  global size:     %i\n", s->size);
862 	  fprintf (f, "  min size:       %i\n", s->min_size);
863 	  fprintf (f, "  self stack:      %i\n",
864 		   (int) s->estimated_self_stack_size);
865 	  fprintf (f, "  global stack:    %i\n", (int) s->estimated_stack_size);
866 	  if (s->growth)
867 	    fprintf (f, "  estimated growth:%i\n", (int) s->growth);
868 	  if (s->scc_no)
869 	    fprintf (f, "  In SCC:          %i\n", (int) s->scc_no);
870 	  for (i = 0; vec_safe_iterate (s->size_time_table, i, &e); i++)
871 	    {
872 	      fprintf (f, "    size:%f, time:%f",
873 		       (double) e->size / ipa_fn_summary::size_scale,
874 		       e->time.to_double ());
875 	      if (e->exec_predicate != true)
876 		{
877 		  fprintf (f, ",  executed if:");
878 		  e->exec_predicate.dump (f, s->conds, 0);
879 		}
880 	      if (e->exec_predicate != e->nonconst_predicate)
881 		{
882 		  fprintf (f, ",  nonconst if:");
883 		  e->nonconst_predicate.dump (f, s->conds, 0);
884 		}
885 	      fprintf (f, "\n");
886 	    }
887 	  if (s->loop_iterations)
888 	    {
889 	      fprintf (f, "  loop iterations:");
890 	      s->loop_iterations->dump (f, s->conds);
891 	    }
892 	  if (s->loop_stride)
893 	    {
894 	      fprintf (f, "  loop stride:");
895 	      s->loop_stride->dump (f, s->conds);
896 	    }
897 	  if (s->array_index)
898 	    {
899 	      fprintf (f, "  array index:");
900 	      s->array_index->dump (f, s->conds);
901 	    }
902 	  fprintf (f, "  calls:\n");
903 	  dump_ipa_call_summary (f, 4, node, s);
904 	  fprintf (f, "\n");
905 	}
906       else
907 	fprintf (f, "IPA summary for %s is missing.\n", node->dump_name ());
908     }
909 }
910 
911 DEBUG_FUNCTION void
ipa_debug_fn_summary(struct cgraph_node * node)912 ipa_debug_fn_summary (struct cgraph_node *node)
913 {
914   ipa_dump_fn_summary (stderr, node);
915 }
916 
917 void
ipa_dump_fn_summaries(FILE * f)918 ipa_dump_fn_summaries (FILE *f)
919 {
920   struct cgraph_node *node;
921 
922   FOR_EACH_DEFINED_FUNCTION (node)
923     if (!node->global.inlined_to)
924       ipa_dump_fn_summary (f, node);
925 }
926 
927 /* Callback of walk_aliased_vdefs.  Flags that it has been invoked to the
928    boolean variable pointed to by DATA.  */
929 
930 static bool
mark_modified(ao_ref * ao ATTRIBUTE_UNUSED,tree vdef ATTRIBUTE_UNUSED,void * data)931 mark_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED,
932 	       void *data)
933 {
934   bool *b = (bool *) data;
935   *b = true;
936   return true;
937 }
938 
939 /* If OP refers to value of function parameter, return the corresponding
940    parameter.  If non-NULL, the size of the memory load (or the SSA_NAME of the
941    PARM_DECL) will be stored to *SIZE_P in that case too.  */
942 
943 static tree
unmodified_parm_1(ipa_func_body_info * fbi,gimple * stmt,tree op,HOST_WIDE_INT * size_p)944 unmodified_parm_1 (ipa_func_body_info *fbi, gimple *stmt, tree op,
945 		   HOST_WIDE_INT *size_p)
946 {
947   /* SSA_NAME referring to parm default def?  */
948   if (TREE_CODE (op) == SSA_NAME
949       && SSA_NAME_IS_DEFAULT_DEF (op)
950       && TREE_CODE (SSA_NAME_VAR (op)) == PARM_DECL)
951     {
952       if (size_p)
953 	*size_p = tree_to_shwi (TYPE_SIZE (TREE_TYPE (op)));
954       return SSA_NAME_VAR (op);
955     }
956   /* Non-SSA parm reference?  */
957   if (TREE_CODE (op) == PARM_DECL)
958     {
959       bool modified = false;
960 
961       ao_ref refd;
962       ao_ref_init (&refd, op);
963       int walked = walk_aliased_vdefs (&refd, gimple_vuse (stmt),
964 				       mark_modified, &modified, NULL, NULL,
965 				       fbi->aa_walk_budget + 1);
966       if (walked < 0)
967 	{
968 	  fbi->aa_walk_budget = 0;
969 	  return NULL_TREE;
970 	}
971       if (!modified)
972 	{
973 	  if (size_p)
974 	    *size_p = tree_to_shwi (TYPE_SIZE (TREE_TYPE (op)));
975 	  return op;
976 	}
977     }
978   return NULL_TREE;
979 }
980 
981 /* If OP refers to value of function parameter, return the corresponding
982    parameter.  Also traverse chains of SSA register assignments.  If non-NULL,
983    the size of the memory load (or the SSA_NAME of the PARM_DECL) will be
984    stored to *SIZE_P in that case too.  */
985 
986 static tree
unmodified_parm(ipa_func_body_info * fbi,gimple * stmt,tree op,HOST_WIDE_INT * size_p)987 unmodified_parm (ipa_func_body_info *fbi, gimple *stmt, tree op,
988 		 HOST_WIDE_INT *size_p)
989 {
990   tree res = unmodified_parm_1 (fbi, stmt, op, size_p);
991   if (res)
992     return res;
993 
994   if (TREE_CODE (op) == SSA_NAME
995       && !SSA_NAME_IS_DEFAULT_DEF (op)
996       && gimple_assign_single_p (SSA_NAME_DEF_STMT (op)))
997     return unmodified_parm (fbi, SSA_NAME_DEF_STMT (op),
998 			    gimple_assign_rhs1 (SSA_NAME_DEF_STMT (op)),
999 			    size_p);
1000   return NULL_TREE;
1001 }
1002 
1003 /* If OP refers to a value of a function parameter or value loaded from an
1004    aggregate passed to a parameter (either by value or reference), return TRUE
1005    and store the number of the parameter to *INDEX_P, the access size into
1006    *SIZE_P, and information whether and how it has been loaded from an
1007    aggregate into *AGGPOS.  INFO describes the function parameters, STMT is the
1008    statement in which OP is used or loaded.  */
1009 
1010 static bool
unmodified_parm_or_parm_agg_item(struct ipa_func_body_info * fbi,gimple * stmt,tree op,int * index_p,HOST_WIDE_INT * size_p,struct agg_position_info * aggpos)1011 unmodified_parm_or_parm_agg_item (struct ipa_func_body_info *fbi,
1012 				  gimple *stmt, tree op, int *index_p,
1013 				  HOST_WIDE_INT *size_p,
1014 				  struct agg_position_info *aggpos)
1015 {
1016   tree res = unmodified_parm_1 (fbi, stmt, op, size_p);
1017 
1018   gcc_checking_assert (aggpos);
1019   if (res)
1020     {
1021       *index_p = ipa_get_param_decl_index (fbi->info, res);
1022       if (*index_p < 0)
1023 	return false;
1024       aggpos->agg_contents = false;
1025       aggpos->by_ref = false;
1026       return true;
1027     }
1028 
1029   if (TREE_CODE (op) == SSA_NAME)
1030     {
1031       if (SSA_NAME_IS_DEFAULT_DEF (op)
1032 	  || !gimple_assign_single_p (SSA_NAME_DEF_STMT (op)))
1033 	return false;
1034       stmt = SSA_NAME_DEF_STMT (op);
1035       op = gimple_assign_rhs1 (stmt);
1036       if (!REFERENCE_CLASS_P (op))
1037 	return unmodified_parm_or_parm_agg_item (fbi, stmt, op, index_p, size_p,
1038 						 aggpos);
1039     }
1040 
1041   aggpos->agg_contents = true;
1042   return ipa_load_from_parm_agg (fbi, fbi->info->descriptors,
1043 				 stmt, op, index_p, &aggpos->offset,
1044 				 size_p, &aggpos->by_ref);
1045 }
1046 
1047 /* See if statement might disappear after inlining.
1048    0 - means not eliminated
1049    1 - half of statements goes away
1050    2 - for sure it is eliminated.
1051    We are not terribly sophisticated, basically looking for simple abstraction
1052    penalty wrappers.  */
1053 
1054 static int
eliminated_by_inlining_prob(ipa_func_body_info * fbi,gimple * stmt)1055 eliminated_by_inlining_prob (ipa_func_body_info *fbi, gimple *stmt)
1056 {
1057   enum gimple_code code = gimple_code (stmt);
1058   enum tree_code rhs_code;
1059 
1060   if (!optimize)
1061     return 0;
1062 
1063   switch (code)
1064     {
1065     case GIMPLE_RETURN:
1066       return 2;
1067     case GIMPLE_ASSIGN:
1068       if (gimple_num_ops (stmt) != 2)
1069 	return 0;
1070 
1071       rhs_code = gimple_assign_rhs_code (stmt);
1072 
1073       /* Casts of parameters, loads from parameters passed by reference
1074          and stores to return value or parameters are often free after
1075          inlining dua to SRA and further combining.
1076          Assume that half of statements goes away.  */
1077       if (CONVERT_EXPR_CODE_P (rhs_code)
1078 	  || rhs_code == VIEW_CONVERT_EXPR
1079 	  || rhs_code == ADDR_EXPR
1080 	  || gimple_assign_rhs_class (stmt) == GIMPLE_SINGLE_RHS)
1081 	{
1082 	  tree rhs = gimple_assign_rhs1 (stmt);
1083 	  tree lhs = gimple_assign_lhs (stmt);
1084 	  tree inner_rhs = get_base_address (rhs);
1085 	  tree inner_lhs = get_base_address (lhs);
1086 	  bool rhs_free = false;
1087 	  bool lhs_free = false;
1088 
1089 	  if (!inner_rhs)
1090 	    inner_rhs = rhs;
1091 	  if (!inner_lhs)
1092 	    inner_lhs = lhs;
1093 
1094 	  /* Reads of parameter are expected to be free.  */
1095 	  if (unmodified_parm (fbi, stmt, inner_rhs, NULL))
1096 	    rhs_free = true;
1097 	  /* Match expressions of form &this->field. Those will most likely
1098 	     combine with something upstream after inlining.  */
1099 	  else if (TREE_CODE (inner_rhs) == ADDR_EXPR)
1100 	    {
1101 	      tree op = get_base_address (TREE_OPERAND (inner_rhs, 0));
1102 	      if (TREE_CODE (op) == PARM_DECL)
1103 		rhs_free = true;
1104 	      else if (TREE_CODE (op) == MEM_REF
1105 		       && unmodified_parm (fbi, stmt, TREE_OPERAND (op, 0),
1106 					   NULL))
1107 		rhs_free = true;
1108 	    }
1109 
1110 	  /* When parameter is not SSA register because its address is taken
1111 	     and it is just copied into one, the statement will be completely
1112 	     free after inlining (we will copy propagate backward).   */
1113 	  if (rhs_free && is_gimple_reg (lhs))
1114 	    return 2;
1115 
1116 	  /* Reads of parameters passed by reference
1117 	     expected to be free (i.e. optimized out after inlining).  */
1118 	  if (TREE_CODE (inner_rhs) == MEM_REF
1119 	      && unmodified_parm (fbi, stmt, TREE_OPERAND (inner_rhs, 0), NULL))
1120 	    rhs_free = true;
1121 
1122 	  /* Copying parameter passed by reference into gimple register is
1123 	     probably also going to copy propagate, but we can't be quite
1124 	     sure.  */
1125 	  if (rhs_free && is_gimple_reg (lhs))
1126 	    lhs_free = true;
1127 
1128 	  /* Writes to parameters, parameters passed by value and return value
1129 	     (either dirrectly or passed via invisible reference) are free.
1130 
1131 	     TODO: We ought to handle testcase like
1132 	     struct a {int a,b;};
1133 	     struct a
1134 	     retrurnsturct (void)
1135 	     {
1136 	     struct a a ={1,2};
1137 	     return a;
1138 	     }
1139 
1140 	     This translate into:
1141 
1142 	     retrurnsturct ()
1143 	     {
1144 	     int a$b;
1145 	     int a$a;
1146 	     struct a a;
1147 	     struct a D.2739;
1148 
1149 	     <bb 2>:
1150 	     D.2739.a = 1;
1151 	     D.2739.b = 2;
1152 	     return D.2739;
1153 
1154 	     }
1155 	     For that we either need to copy ipa-split logic detecting writes
1156 	     to return value.  */
1157 	  if (TREE_CODE (inner_lhs) == PARM_DECL
1158 	      || TREE_CODE (inner_lhs) == RESULT_DECL
1159 	      || (TREE_CODE (inner_lhs) == MEM_REF
1160 		  && (unmodified_parm (fbi, stmt, TREE_OPERAND (inner_lhs, 0),
1161 				       NULL)
1162 		      || (TREE_CODE (TREE_OPERAND (inner_lhs, 0)) == SSA_NAME
1163 			  && SSA_NAME_VAR (TREE_OPERAND (inner_lhs, 0))
1164 			  && TREE_CODE (SSA_NAME_VAR (TREE_OPERAND
1165 						      (inner_lhs,
1166 						       0))) == RESULT_DECL))))
1167 	    lhs_free = true;
1168 	  if (lhs_free
1169 	      && (is_gimple_reg (rhs) || is_gimple_min_invariant (rhs)))
1170 	    rhs_free = true;
1171 	  if (lhs_free && rhs_free)
1172 	    return 1;
1173 	}
1174       return 0;
1175     default:
1176       return 0;
1177     }
1178 }
1179 
1180 
1181 /* If BB ends by a conditional we can turn into predicates, attach corresponding
1182    predicates to the CFG edges.   */
1183 
1184 static void
set_cond_stmt_execution_predicate(struct ipa_func_body_info * fbi,struct ipa_fn_summary * summary,basic_block bb)1185 set_cond_stmt_execution_predicate (struct ipa_func_body_info *fbi,
1186 				   struct ipa_fn_summary *summary,
1187 				   basic_block bb)
1188 {
1189   gimple *last;
1190   tree op;
1191   int index;
1192   HOST_WIDE_INT size;
1193   struct agg_position_info aggpos;
1194   enum tree_code code, inverted_code;
1195   edge e;
1196   edge_iterator ei;
1197   gimple *set_stmt;
1198   tree op2;
1199 
1200   last = last_stmt (bb);
1201   if (!last || gimple_code (last) != GIMPLE_COND)
1202     return;
1203   if (!is_gimple_ip_invariant (gimple_cond_rhs (last)))
1204     return;
1205   op = gimple_cond_lhs (last);
1206   /* TODO: handle conditionals like
1207      var = op0 < 4;
1208      if (var != 0).  */
1209   if (unmodified_parm_or_parm_agg_item (fbi, last, op, &index, &size, &aggpos))
1210     {
1211       code = gimple_cond_code (last);
1212       inverted_code = invert_tree_comparison (code, HONOR_NANS (op));
1213 
1214       FOR_EACH_EDGE (e, ei, bb->succs)
1215 	{
1216 	  enum tree_code this_code = (e->flags & EDGE_TRUE_VALUE
1217 				      ? code : inverted_code);
1218 	  /* invert_tree_comparison will return ERROR_MARK on FP
1219 	     comparsions that are not EQ/NE instead of returning proper
1220 	     unordered one.  Be sure it is not confused with NON_CONSTANT.  */
1221 	  if (this_code != ERROR_MARK)
1222 	    {
1223 	      predicate p
1224 		= add_condition (summary, index, size, &aggpos, this_code,
1225 				 unshare_expr_without_location
1226 				 (gimple_cond_rhs (last)));
1227 	      e->aux = edge_predicate_pool.allocate ();
1228 	      *(predicate *) e->aux = p;
1229 	    }
1230 	}
1231     }
1232 
1233   if (TREE_CODE (op) != SSA_NAME)
1234     return;
1235   /* Special case
1236      if (builtin_constant_p (op))
1237      constant_code
1238      else
1239      nonconstant_code.
1240      Here we can predicate nonconstant_code.  We can't
1241      really handle constant_code since we have no predicate
1242      for this and also the constant code is not known to be
1243      optimized away when inliner doen't see operand is constant.
1244      Other optimizers might think otherwise.  */
1245   if (gimple_cond_code (last) != NE_EXPR
1246       || !integer_zerop (gimple_cond_rhs (last)))
1247     return;
1248   set_stmt = SSA_NAME_DEF_STMT (op);
1249   if (!gimple_call_builtin_p (set_stmt, BUILT_IN_CONSTANT_P)
1250       || gimple_call_num_args (set_stmt) != 1)
1251     return;
1252   op2 = gimple_call_arg (set_stmt, 0);
1253   if (!unmodified_parm_or_parm_agg_item (fbi, set_stmt, op2, &index, &size,
1254 					 &aggpos))
1255     return;
1256   FOR_EACH_EDGE (e, ei, bb->succs) if (e->flags & EDGE_FALSE_VALUE)
1257     {
1258       predicate p = add_condition (summary, index, size, &aggpos,
1259 				   predicate::is_not_constant, NULL_TREE);
1260       e->aux = edge_predicate_pool.allocate ();
1261       *(predicate *) e->aux = p;
1262     }
1263 }
1264 
1265 
1266 /* If BB ends by a switch we can turn into predicates, attach corresponding
1267    predicates to the CFG edges.   */
1268 
1269 static void
set_switch_stmt_execution_predicate(struct ipa_func_body_info * fbi,struct ipa_fn_summary * summary,basic_block bb)1270 set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi,
1271 				     struct ipa_fn_summary *summary,
1272 				     basic_block bb)
1273 {
1274   gimple *lastg;
1275   tree op;
1276   int index;
1277   HOST_WIDE_INT size;
1278   struct agg_position_info aggpos;
1279   edge e;
1280   edge_iterator ei;
1281   size_t n;
1282   size_t case_idx;
1283 
1284   lastg = last_stmt (bb);
1285   if (!lastg || gimple_code (lastg) != GIMPLE_SWITCH)
1286     return;
1287   gswitch *last = as_a <gswitch *> (lastg);
1288   op = gimple_switch_index (last);
1289   if (!unmodified_parm_or_parm_agg_item (fbi, last, op, &index, &size, &aggpos))
1290     return;
1291 
1292   FOR_EACH_EDGE (e, ei, bb->succs)
1293     {
1294       e->aux = edge_predicate_pool.allocate ();
1295       *(predicate *) e->aux = false;
1296     }
1297   n = gimple_switch_num_labels (last);
1298   for (case_idx = 0; case_idx < n; ++case_idx)
1299     {
1300       tree cl = gimple_switch_label (last, case_idx);
1301       tree min, max;
1302       predicate p;
1303 
1304       e = gimple_switch_edge (cfun, last, case_idx);
1305       min = CASE_LOW (cl);
1306       max = CASE_HIGH (cl);
1307 
1308       /* For default we might want to construct predicate that none
1309          of cases is met, but it is bit hard to do not having negations
1310          of conditionals handy.  */
1311       if (!min && !max)
1312 	p = true;
1313       else if (!max)
1314 	p = add_condition (summary, index, size, &aggpos, EQ_EXPR,
1315 			   unshare_expr_without_location (min));
1316       else
1317 	{
1318 	  predicate p1, p2;
1319 	  p1 = add_condition (summary, index, size, &aggpos, GE_EXPR,
1320 			      unshare_expr_without_location (min));
1321 	  p2 = add_condition (summary, index, size, &aggpos, LE_EXPR,
1322 			      unshare_expr_without_location (max));
1323 	  p = p1 & p2;
1324 	}
1325       *(struct predicate *) e->aux
1326 	= p.or_with (summary->conds, *(struct predicate *) e->aux);
1327     }
1328 }
1329 
1330 
1331 /* For each BB in NODE attach to its AUX pointer predicate under
1332    which it is executable.  */
1333 
1334 static void
compute_bb_predicates(struct ipa_func_body_info * fbi,struct cgraph_node * node,struct ipa_fn_summary * summary)1335 compute_bb_predicates (struct ipa_func_body_info *fbi,
1336 		       struct cgraph_node *node,
1337 		       struct ipa_fn_summary *summary)
1338 {
1339   struct function *my_function = DECL_STRUCT_FUNCTION (node->decl);
1340   bool done = false;
1341   basic_block bb;
1342 
1343   FOR_EACH_BB_FN (bb, my_function)
1344     {
1345       set_cond_stmt_execution_predicate (fbi, summary, bb);
1346       set_switch_stmt_execution_predicate (fbi, summary, bb);
1347     }
1348 
1349   /* Entry block is always executable.  */
1350   ENTRY_BLOCK_PTR_FOR_FN (my_function)->aux
1351     = edge_predicate_pool.allocate ();
1352   *(predicate *) ENTRY_BLOCK_PTR_FOR_FN (my_function)->aux = true;
1353 
1354   /* A simple dataflow propagation of predicates forward in the CFG.
1355      TODO: work in reverse postorder.  */
1356   while (!done)
1357     {
1358       done = true;
1359       FOR_EACH_BB_FN (bb, my_function)
1360 	{
1361 	  predicate p = false;
1362 	  edge e;
1363 	  edge_iterator ei;
1364 	  FOR_EACH_EDGE (e, ei, bb->preds)
1365 	    {
1366 	      if (e->src->aux)
1367 		{
1368 		  predicate this_bb_predicate
1369 		    = *(predicate *) e->src->aux;
1370 		  if (e->aux)
1371 		    this_bb_predicate &= (*(struct predicate *) e->aux);
1372 		  p = p.or_with (summary->conds, this_bb_predicate);
1373 		  if (p == true)
1374 		    break;
1375 		}
1376 	    }
1377 	  if (p == false)
1378 	    gcc_checking_assert (!bb->aux);
1379 	  else
1380 	    {
1381 	      if (!bb->aux)
1382 		{
1383 		  done = false;
1384 		  bb->aux = edge_predicate_pool.allocate ();
1385 		  *((predicate *) bb->aux) = p;
1386 		}
1387 	      else if (p != *(predicate *) bb->aux)
1388 		{
1389 		  /* This OR operation is needed to ensure monotonous data flow
1390 		     in the case we hit the limit on number of clauses and the
1391 		     and/or operations above give approximate answers.  */
1392 		  p = p.or_with (summary->conds, *(predicate *)bb->aux);
1393 	          if (p != *(predicate *) bb->aux)
1394 		    {
1395 		      done = false;
1396 		      *((predicate *) bb->aux) = p;
1397 		    }
1398 		}
1399 	    }
1400 	}
1401     }
1402 }
1403 
1404 
1405 /* Return predicate specifying when the STMT might have result that is not
1406    a compile time constant.  */
1407 
1408 static predicate
will_be_nonconstant_expr_predicate(ipa_func_body_info * fbi,struct ipa_fn_summary * summary,tree expr,vec<predicate> nonconstant_names)1409 will_be_nonconstant_expr_predicate (ipa_func_body_info *fbi,
1410 				    struct ipa_fn_summary *summary,
1411 				    tree expr,
1412 				    vec<predicate> nonconstant_names)
1413 {
1414   tree parm;
1415   int index;
1416   HOST_WIDE_INT size;
1417 
1418   while (UNARY_CLASS_P (expr))
1419     expr = TREE_OPERAND (expr, 0);
1420 
1421   parm = unmodified_parm (fbi, NULL, expr, &size);
1422   if (parm && (index = ipa_get_param_decl_index (fbi->info, parm)) >= 0)
1423     return add_condition (summary, index, size, NULL, predicate::changed,
1424 			  NULL_TREE);
1425   if (is_gimple_min_invariant (expr))
1426     return false;
1427   if (TREE_CODE (expr) == SSA_NAME)
1428     return nonconstant_names[SSA_NAME_VERSION (expr)];
1429   if (BINARY_CLASS_P (expr) || COMPARISON_CLASS_P (expr))
1430     {
1431       predicate p1
1432 	= will_be_nonconstant_expr_predicate (fbi, summary,
1433 					      TREE_OPERAND (expr, 0),
1434 					      nonconstant_names);
1435       if (p1 == true)
1436 	return p1;
1437 
1438       predicate p2
1439 	= will_be_nonconstant_expr_predicate (fbi, summary,
1440 					      TREE_OPERAND (expr, 1),
1441 					      nonconstant_names);
1442       return p1.or_with (summary->conds, p2);
1443     }
1444   else if (TREE_CODE (expr) == COND_EXPR)
1445     {
1446       predicate p1
1447 	= will_be_nonconstant_expr_predicate (fbi, summary,
1448 					      TREE_OPERAND (expr, 0),
1449 					      nonconstant_names);
1450       if (p1 == true)
1451 	return p1;
1452 
1453       predicate p2
1454 	= will_be_nonconstant_expr_predicate (fbi, summary,
1455 					      TREE_OPERAND (expr, 1),
1456 					      nonconstant_names);
1457       if (p2 == true)
1458 	return p2;
1459       p1 = p1.or_with (summary->conds, p2);
1460       p2 = will_be_nonconstant_expr_predicate (fbi, summary,
1461 					       TREE_OPERAND (expr, 2),
1462 					       nonconstant_names);
1463       return p2.or_with (summary->conds, p1);
1464     }
1465   else if (TREE_CODE (expr) == CALL_EXPR)
1466     return true;
1467   else
1468     {
1469       debug_tree (expr);
1470       gcc_unreachable ();
1471     }
1472   return false;
1473 }
1474 
1475 
1476 /* Return predicate specifying when the STMT might have result that is not
1477    a compile time constant.  */
1478 
1479 static predicate
will_be_nonconstant_predicate(struct ipa_func_body_info * fbi,struct ipa_fn_summary * summary,gimple * stmt,vec<predicate> nonconstant_names)1480 will_be_nonconstant_predicate (struct ipa_func_body_info *fbi,
1481 			       struct ipa_fn_summary *summary,
1482 			       gimple *stmt,
1483 			       vec<predicate> nonconstant_names)
1484 {
1485   predicate p = true;
1486   ssa_op_iter iter;
1487   tree use;
1488   predicate op_non_const;
1489   bool is_load;
1490   int base_index;
1491   HOST_WIDE_INT size;
1492   struct agg_position_info aggpos;
1493 
1494   /* What statments might be optimized away
1495      when their arguments are constant.  */
1496   if (gimple_code (stmt) != GIMPLE_ASSIGN
1497       && gimple_code (stmt) != GIMPLE_COND
1498       && gimple_code (stmt) != GIMPLE_SWITCH
1499       && (gimple_code (stmt) != GIMPLE_CALL
1500 	  || !(gimple_call_flags (stmt) & ECF_CONST)))
1501     return p;
1502 
1503   /* Stores will stay anyway.  */
1504   if (gimple_store_p (stmt))
1505     return p;
1506 
1507   is_load = gimple_assign_load_p (stmt);
1508 
1509   /* Loads can be optimized when the value is known.  */
1510   if (is_load)
1511     {
1512       tree op;
1513       gcc_assert (gimple_assign_single_p (stmt));
1514       op = gimple_assign_rhs1 (stmt);
1515       if (!unmodified_parm_or_parm_agg_item (fbi, stmt, op, &base_index, &size,
1516 					     &aggpos))
1517 	return p;
1518     }
1519   else
1520     base_index = -1;
1521 
1522   /* See if we understand all operands before we start
1523      adding conditionals.  */
1524   FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
1525     {
1526       tree parm = unmodified_parm (fbi, stmt, use, NULL);
1527       /* For arguments we can build a condition.  */
1528       if (parm && ipa_get_param_decl_index (fbi->info, parm) >= 0)
1529 	continue;
1530       if (TREE_CODE (use) != SSA_NAME)
1531 	return p;
1532       /* If we know when operand is constant,
1533 	 we still can say something useful.  */
1534       if (nonconstant_names[SSA_NAME_VERSION (use)] != true)
1535 	continue;
1536       return p;
1537     }
1538 
1539   if (is_load)
1540     op_non_const =
1541       add_condition (summary, base_index, size, &aggpos, predicate::changed,
1542 		     NULL);
1543   else
1544     op_non_const = false;
1545   FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
1546     {
1547       HOST_WIDE_INT size;
1548       tree parm = unmodified_parm (fbi, stmt, use, &size);
1549       int index;
1550 
1551       if (parm && (index = ipa_get_param_decl_index (fbi->info, parm)) >= 0)
1552 	{
1553 	  if (index != base_index)
1554 	    p = add_condition (summary, index, size, NULL, predicate::changed,
1555 			       NULL_TREE);
1556 	  else
1557 	    continue;
1558 	}
1559       else
1560 	p = nonconstant_names[SSA_NAME_VERSION (use)];
1561       op_non_const = p.or_with (summary->conds, op_non_const);
1562     }
1563   if ((gimple_code (stmt) == GIMPLE_ASSIGN || gimple_code (stmt) == GIMPLE_CALL)
1564       && gimple_op (stmt, 0)
1565       && TREE_CODE (gimple_op (stmt, 0)) == SSA_NAME)
1566     nonconstant_names[SSA_NAME_VERSION (gimple_op (stmt, 0))]
1567       = op_non_const;
1568   return op_non_const;
1569 }
1570 
1571 struct record_modified_bb_info
1572 {
1573   tree op;
1574   bitmap bb_set;
1575   gimple *stmt;
1576 };
1577 
1578 /* Value is initialized in INIT_BB and used in USE_BB.  We want to copute
1579    probability how often it changes between USE_BB.
1580    INIT_BB->count/USE_BB->count is an estimate, but if INIT_BB
1581    is in different loop nest, we can do better.
1582    This is all just estimate.  In theory we look for minimal cut separating
1583    INIT_BB and USE_BB, but we only want to anticipate loop invariant motion
1584    anyway.  */
1585 
1586 static basic_block
get_minimal_bb(basic_block init_bb,basic_block use_bb)1587 get_minimal_bb (basic_block init_bb, basic_block use_bb)
1588 {
1589   struct loop *l = find_common_loop (init_bb->loop_father, use_bb->loop_father);
1590   if (l && l->header->count < init_bb->count)
1591     return l->header;
1592   return init_bb;
1593 }
1594 
1595 /* Callback of walk_aliased_vdefs.  Records basic blocks where the value may be
1596    set except for info->stmt.  */
1597 
1598 static bool
record_modified(ao_ref * ao ATTRIBUTE_UNUSED,tree vdef,void * data)1599 record_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef, void *data)
1600 {
1601   struct record_modified_bb_info *info =
1602     (struct record_modified_bb_info *) data;
1603   if (SSA_NAME_DEF_STMT (vdef) == info->stmt)
1604     return false;
1605   if (gimple_clobber_p (SSA_NAME_DEF_STMT (vdef)))
1606     return false;
1607   bitmap_set_bit (info->bb_set,
1608 		  SSA_NAME_IS_DEFAULT_DEF (vdef)
1609 		  ? ENTRY_BLOCK_PTR_FOR_FN (cfun)->index
1610 		  : get_minimal_bb
1611 			 (gimple_bb (SSA_NAME_DEF_STMT (vdef)),
1612 			  gimple_bb (info->stmt))->index);
1613   if (dump_file)
1614     {
1615       fprintf (dump_file, "     Param ");
1616       print_generic_expr (dump_file, info->op, TDF_SLIM);
1617       fprintf (dump_file, " changed at bb %i, minimal: %i stmt: ",
1618 	       gimple_bb (SSA_NAME_DEF_STMT (vdef))->index,
1619 	       get_minimal_bb
1620 			 (gimple_bb (SSA_NAME_DEF_STMT (vdef)),
1621 			  gimple_bb (info->stmt))->index);
1622       print_gimple_stmt (dump_file, SSA_NAME_DEF_STMT (vdef), 0);
1623     }
1624   return false;
1625 }
1626 
1627 /* Return probability (based on REG_BR_PROB_BASE) that I-th parameter of STMT
1628    will change since last invocation of STMT.
1629 
1630    Value 0 is reserved for compile time invariants.
1631    For common parameters it is REG_BR_PROB_BASE.  For loop invariants it
1632    ought to be REG_BR_PROB_BASE / estimated_iters.  */
1633 
1634 static int
param_change_prob(ipa_func_body_info * fbi,gimple * stmt,int i)1635 param_change_prob (ipa_func_body_info *fbi, gimple *stmt, int i)
1636 {
1637   tree op = gimple_call_arg (stmt, i);
1638   basic_block bb = gimple_bb (stmt);
1639 
1640   if (TREE_CODE (op) == WITH_SIZE_EXPR)
1641     op = TREE_OPERAND (op, 0);
1642 
1643   tree base = get_base_address (op);
1644 
1645   /* Global invariants never change.  */
1646   if (is_gimple_min_invariant (base))
1647     return 0;
1648 
1649   /* We would have to do non-trivial analysis to really work out what
1650      is the probability of value to change (i.e. when init statement
1651      is in a sibling loop of the call).
1652 
1653      We do an conservative estimate: when call is executed N times more often
1654      than the statement defining value, we take the frequency 1/N.  */
1655   if (TREE_CODE (base) == SSA_NAME)
1656     {
1657       profile_count init_count;
1658 
1659       if (!bb->count.nonzero_p ())
1660 	return REG_BR_PROB_BASE;
1661 
1662       if (SSA_NAME_IS_DEFAULT_DEF (base))
1663 	init_count = ENTRY_BLOCK_PTR_FOR_FN (cfun)->count;
1664       else
1665 	init_count = get_minimal_bb
1666 		      (gimple_bb (SSA_NAME_DEF_STMT (base)),
1667 		       gimple_bb (stmt))->count;
1668 
1669       if (init_count < bb->count)
1670         return MAX ((init_count.to_sreal_scale (bb->count)
1671 		     * REG_BR_PROB_BASE).to_int (), 1);
1672       return REG_BR_PROB_BASE;
1673     }
1674   else
1675     {
1676       ao_ref refd;
1677       profile_count max = ENTRY_BLOCK_PTR_FOR_FN (cfun)->count;
1678       struct record_modified_bb_info info;
1679       tree init = ctor_for_folding (base);
1680 
1681       if (init != error_mark_node)
1682 	return 0;
1683       if (!bb->count.nonzero_p ())
1684 	return REG_BR_PROB_BASE;
1685       if (dump_file)
1686 	{
1687 	  fprintf (dump_file, "     Analyzing param change probablity of ");
1688           print_generic_expr (dump_file, op, TDF_SLIM);
1689 	  fprintf (dump_file, "\n");
1690 	}
1691       ao_ref_init (&refd, op);
1692       info.op = op;
1693       info.stmt = stmt;
1694       info.bb_set = BITMAP_ALLOC (NULL);
1695       int walked
1696 	= walk_aliased_vdefs (&refd, gimple_vuse (stmt), record_modified, &info,
1697 			      NULL, NULL, fbi->aa_walk_budget);
1698       if (walked < 0 || bitmap_bit_p (info.bb_set, bb->index))
1699 	{
1700 	  if (dump_file)
1701 	    {
1702 	      if (walked < 0)
1703 		fprintf (dump_file, "     Ran out of AA walking budget.\n");
1704 	      else
1705 		fprintf (dump_file, "     Set in same BB as used.\n");
1706 	    }
1707 	  BITMAP_FREE (info.bb_set);
1708 	  return REG_BR_PROB_BASE;
1709 	}
1710 
1711       bitmap_iterator bi;
1712       unsigned index;
1713       /* Lookup the most frequent update of the value and believe that
1714 	 it dominates all the other; precise analysis here is difficult.  */
1715       EXECUTE_IF_SET_IN_BITMAP (info.bb_set, 0, index, bi)
1716 	max = max.max (BASIC_BLOCK_FOR_FN (cfun, index)->count);
1717       if (dump_file)
1718 	{
1719           fprintf (dump_file, "     Set with count ");
1720 	  max.dump (dump_file);
1721           fprintf (dump_file, " and used with count ");
1722 	  bb->count.dump (dump_file);
1723           fprintf (dump_file, " freq %f\n",
1724 		   max.to_sreal_scale (bb->count).to_double ());
1725 	}
1726 
1727       BITMAP_FREE (info.bb_set);
1728       if (max < bb->count)
1729         return MAX ((max.to_sreal_scale (bb->count)
1730 		     * REG_BR_PROB_BASE).to_int (), 1);
1731       return REG_BR_PROB_BASE;
1732     }
1733 }
1734 
1735 /* Find whether a basic block BB is the final block of a (half) diamond CFG
1736    sub-graph and if the predicate the condition depends on is known.  If so,
1737    return true and store the pointer the predicate in *P.  */
1738 
1739 static bool
phi_result_unknown_predicate(ipa_func_body_info * fbi,ipa_fn_summary * summary,basic_block bb,predicate * p,vec<predicate> nonconstant_names)1740 phi_result_unknown_predicate (ipa_func_body_info *fbi,
1741 			      ipa_fn_summary *summary, basic_block bb,
1742 			      predicate *p,
1743 			      vec<predicate> nonconstant_names)
1744 {
1745   edge e;
1746   edge_iterator ei;
1747   basic_block first_bb = NULL;
1748   gimple *stmt;
1749 
1750   if (single_pred_p (bb))
1751     {
1752       *p = false;
1753       return true;
1754     }
1755 
1756   FOR_EACH_EDGE (e, ei, bb->preds)
1757     {
1758       if (single_succ_p (e->src))
1759 	{
1760 	  if (!single_pred_p (e->src))
1761 	    return false;
1762 	  if (!first_bb)
1763 	    first_bb = single_pred (e->src);
1764 	  else if (single_pred (e->src) != first_bb)
1765 	    return false;
1766 	}
1767       else
1768 	{
1769 	  if (!first_bb)
1770 	    first_bb = e->src;
1771 	  else if (e->src != first_bb)
1772 	    return false;
1773 	}
1774     }
1775 
1776   if (!first_bb)
1777     return false;
1778 
1779   stmt = last_stmt (first_bb);
1780   if (!stmt
1781       || gimple_code (stmt) != GIMPLE_COND
1782       || !is_gimple_ip_invariant (gimple_cond_rhs (stmt)))
1783     return false;
1784 
1785   *p = will_be_nonconstant_expr_predicate (fbi, summary,
1786 					   gimple_cond_lhs (stmt),
1787 					   nonconstant_names);
1788   if (*p == true)
1789     return false;
1790   else
1791     return true;
1792 }
1793 
1794 /* Given a PHI statement in a function described by inline properties SUMMARY
1795    and *P being the predicate describing whether the selected PHI argument is
1796    known, store a predicate for the result of the PHI statement into
1797    NONCONSTANT_NAMES, if possible.  */
1798 
1799 static void
predicate_for_phi_result(struct ipa_fn_summary * summary,gphi * phi,predicate * p,vec<predicate> nonconstant_names)1800 predicate_for_phi_result (struct ipa_fn_summary *summary, gphi *phi,
1801 			  predicate *p,
1802 			  vec<predicate> nonconstant_names)
1803 {
1804   unsigned i;
1805 
1806   for (i = 0; i < gimple_phi_num_args (phi); i++)
1807     {
1808       tree arg = gimple_phi_arg (phi, i)->def;
1809       if (!is_gimple_min_invariant (arg))
1810 	{
1811 	  gcc_assert (TREE_CODE (arg) == SSA_NAME);
1812 	  *p = p->or_with (summary->conds,
1813 			   nonconstant_names[SSA_NAME_VERSION (arg)]);
1814 	  if (*p == true)
1815 	    return;
1816 	}
1817     }
1818 
1819   if (dump_file && (dump_flags & TDF_DETAILS))
1820     {
1821       fprintf (dump_file, "\t\tphi predicate: ");
1822       p->dump (dump_file, summary->conds);
1823     }
1824   nonconstant_names[SSA_NAME_VERSION (gimple_phi_result (phi))] = *p;
1825 }
1826 
1827 /* Return predicate specifying when array index in access OP becomes non-constant.  */
1828 
1829 static predicate
array_index_predicate(ipa_fn_summary * info,vec<predicate> nonconstant_names,tree op)1830 array_index_predicate (ipa_fn_summary *info,
1831 		       vec< predicate> nonconstant_names, tree op)
1832 {
1833   predicate p = false;
1834   while (handled_component_p (op))
1835     {
1836       if (TREE_CODE (op) == ARRAY_REF || TREE_CODE (op) == ARRAY_RANGE_REF)
1837 	{
1838 	  if (TREE_CODE (TREE_OPERAND (op, 1)) == SSA_NAME)
1839 	    p = p.or_with (info->conds,
1840 			   nonconstant_names[SSA_NAME_VERSION
1841 						  (TREE_OPERAND (op, 1))]);
1842 	}
1843       op = TREE_OPERAND (op, 0);
1844     }
1845   return p;
1846 }
1847 
1848 /* For a typical usage of __builtin_expect (a<b, 1), we
1849    may introduce an extra relation stmt:
1850    With the builtin, we have
1851      t1 = a <= b;
1852      t2 = (long int) t1;
1853      t3 = __builtin_expect (t2, 1);
1854      if (t3 != 0)
1855        goto ...
1856    Without the builtin, we have
1857      if (a<=b)
1858        goto...
1859    This affects the size/time estimation and may have
1860    an impact on the earlier inlining.
1861    Here find this pattern and fix it up later.  */
1862 
1863 static gimple *
find_foldable_builtin_expect(basic_block bb)1864 find_foldable_builtin_expect (basic_block bb)
1865 {
1866   gimple_stmt_iterator bsi;
1867 
1868   for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
1869     {
1870       gimple *stmt = gsi_stmt (bsi);
1871       if (gimple_call_builtin_p (stmt, BUILT_IN_EXPECT)
1872 	  || gimple_call_builtin_p (stmt, BUILT_IN_EXPECT_WITH_PROBABILITY)
1873 	  || gimple_call_internal_p (stmt, IFN_BUILTIN_EXPECT))
1874         {
1875           tree var = gimple_call_lhs (stmt);
1876           tree arg = gimple_call_arg (stmt, 0);
1877           use_operand_p use_p;
1878 	  gimple *use_stmt;
1879           bool match = false;
1880           bool done = false;
1881 
1882           if (!var || !arg)
1883             continue;
1884           gcc_assert (TREE_CODE (var) == SSA_NAME);
1885 
1886           while (TREE_CODE (arg) == SSA_NAME)
1887             {
1888 	      gimple *stmt_tmp = SSA_NAME_DEF_STMT (arg);
1889               if (!is_gimple_assign (stmt_tmp))
1890                 break;
1891               switch (gimple_assign_rhs_code (stmt_tmp))
1892                 {
1893                   case LT_EXPR:
1894                   case LE_EXPR:
1895                   case GT_EXPR:
1896                   case GE_EXPR:
1897                   case EQ_EXPR:
1898                   case NE_EXPR:
1899                     match = true;
1900                     done = true;
1901                     break;
1902                   CASE_CONVERT:
1903                     break;
1904                   default:
1905                     done = true;
1906                     break;
1907                 }
1908               if (done)
1909                 break;
1910               arg = gimple_assign_rhs1 (stmt_tmp);
1911             }
1912 
1913           if (match && single_imm_use (var, &use_p, &use_stmt)
1914               && gimple_code (use_stmt) == GIMPLE_COND)
1915             return use_stmt;
1916         }
1917     }
1918   return NULL;
1919 }
1920 
1921 /* Return true when the basic blocks contains only clobbers followed by RESX.
1922    Such BBs are kept around to make removal of dead stores possible with
1923    presence of EH and will be optimized out by optimize_clobbers later in the
1924    game.
1925 
1926    NEED_EH is used to recurse in case the clobber has non-EH predecestors
1927    that can be clobber only, too.. When it is false, the RESX is not necessary
1928    on the end of basic block.  */
1929 
1930 static bool
1931 clobber_only_eh_bb_p (basic_block bb, bool need_eh = true)
1932 {
1933   gimple_stmt_iterator gsi = gsi_last_bb (bb);
1934   edge_iterator ei;
1935   edge e;
1936 
1937   if (need_eh)
1938     {
1939       if (gsi_end_p (gsi))
1940 	return false;
1941       if (gimple_code (gsi_stmt (gsi)) != GIMPLE_RESX)
1942         return false;
1943       gsi_prev (&gsi);
1944     }
1945   else if (!single_succ_p (bb))
1946     return false;
1947 
1948   for (; !gsi_end_p (gsi); gsi_prev (&gsi))
1949     {
1950       gimple *stmt = gsi_stmt (gsi);
1951       if (is_gimple_debug (stmt))
1952 	continue;
1953       if (gimple_clobber_p (stmt))
1954 	continue;
1955       if (gimple_code (stmt) == GIMPLE_LABEL)
1956 	break;
1957       return false;
1958     }
1959 
1960   /* See if all predecestors are either throws or clobber only BBs.  */
1961   FOR_EACH_EDGE (e, ei, bb->preds)
1962     if (!(e->flags & EDGE_EH)
1963 	&& !clobber_only_eh_bb_p (e->src, false))
1964       return false;
1965 
1966   return true;
1967 }
1968 
1969 /* Return true if STMT compute a floating point expression that may be affected
1970    by -ffast-math and similar flags.  */
1971 
1972 static bool
fp_expression_p(gimple * stmt)1973 fp_expression_p (gimple *stmt)
1974 {
1975   ssa_op_iter i;
1976   tree op;
1977 
1978   FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_DEF|SSA_OP_USE)
1979     if (FLOAT_TYPE_P (TREE_TYPE (op)))
1980       return true;
1981   return false;
1982 }
1983 
1984 /* Analyze function body for NODE.
1985    EARLY indicates run from early optimization pipeline.  */
1986 
1987 static void
analyze_function_body(struct cgraph_node * node,bool early)1988 analyze_function_body (struct cgraph_node *node, bool early)
1989 {
1990   sreal time = PARAM_VALUE (PARAM_UNINLINED_FUNCTION_TIME);
1991   /* Estimate static overhead for function prologue/epilogue and alignment. */
1992   int size = PARAM_VALUE (PARAM_UNINLINED_FUNCTION_INSNS);
1993   /* Benefits are scaled by probability of elimination that is in range
1994      <0,2>.  */
1995   basic_block bb;
1996   struct function *my_function = DECL_STRUCT_FUNCTION (node->decl);
1997   sreal freq;
1998   struct ipa_fn_summary *info = ipa_fn_summaries->get_create (node);
1999   predicate bb_predicate;
2000   struct ipa_func_body_info fbi;
2001   vec<predicate> nonconstant_names = vNULL;
2002   int nblocks, n;
2003   int *order;
2004   predicate array_index = true;
2005   gimple *fix_builtin_expect_stmt;
2006 
2007   gcc_assert (my_function && my_function->cfg);
2008   gcc_assert (cfun == my_function);
2009 
2010   memset(&fbi, 0, sizeof(fbi));
2011   vec_free (info->conds);
2012   info->conds = NULL;
2013   vec_free (info->size_time_table);
2014   info->size_time_table = NULL;
2015 
2016   /* When optimizing and analyzing for IPA inliner, initialize loop optimizer
2017      so we can produce proper inline hints.
2018 
2019      When optimizing and analyzing for early inliner, initialize node params
2020      so we can produce correct BB predicates.  */
2021 
2022   if (opt_for_fn (node->decl, optimize))
2023     {
2024       calculate_dominance_info (CDI_DOMINATORS);
2025       if (!early)
2026         loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS);
2027       else
2028 	{
2029 	  ipa_check_create_node_params ();
2030 	  ipa_initialize_node_params (node);
2031 	}
2032 
2033       if (ipa_node_params_sum)
2034 	{
2035 	  fbi.node = node;
2036 	  fbi.info = IPA_NODE_REF (node);
2037 	  fbi.bb_infos = vNULL;
2038 	  fbi.bb_infos.safe_grow_cleared (last_basic_block_for_fn (cfun));
2039 	  fbi.param_count = count_formal_params (node->decl);
2040 	  fbi.aa_walk_budget = PARAM_VALUE (PARAM_IPA_MAX_AA_STEPS);
2041 
2042 	  nonconstant_names.safe_grow_cleared
2043 	    (SSANAMES (my_function)->length ());
2044 	}
2045     }
2046 
2047   if (dump_file)
2048     fprintf (dump_file, "\nAnalyzing function body size: %s\n",
2049 	     node->name ());
2050 
2051   /* When we run into maximal number of entries, we assign everything to the
2052      constant truth case.  Be sure to have it in list. */
2053   bb_predicate = true;
2054   info->account_size_time (0, 0, bb_predicate, bb_predicate);
2055 
2056   bb_predicate = predicate::not_inlined ();
2057   info->account_size_time (PARAM_VALUE (PARAM_UNINLINED_FUNCTION_INSNS)
2058 			   * ipa_fn_summary::size_scale,
2059 			   PARAM_VALUE (PARAM_UNINLINED_FUNCTION_TIME),
2060 			   bb_predicate,
2061 		           bb_predicate);
2062 
2063   if (fbi.info)
2064     compute_bb_predicates (&fbi, node, info);
2065   order = XNEWVEC (int, n_basic_blocks_for_fn (cfun));
2066   nblocks = pre_and_rev_post_order_compute (NULL, order, false);
2067   for (n = 0; n < nblocks; n++)
2068     {
2069       bb = BASIC_BLOCK_FOR_FN (cfun, order[n]);
2070       freq = bb->count.to_sreal_scale (ENTRY_BLOCK_PTR_FOR_FN (cfun)->count);
2071       if (clobber_only_eh_bb_p (bb))
2072 	{
2073 	  if (dump_file && (dump_flags & TDF_DETAILS))
2074 	    fprintf (dump_file, "\n Ignoring BB %i;"
2075 		     " it will be optimized away by cleanup_clobbers\n",
2076 		     bb->index);
2077 	  continue;
2078 	}
2079 
2080       /* TODO: Obviously predicates can be propagated down across CFG.  */
2081       if (fbi.info)
2082 	{
2083 	  if (bb->aux)
2084 	    bb_predicate = *(predicate *) bb->aux;
2085 	  else
2086 	    bb_predicate = false;
2087 	}
2088       else
2089 	bb_predicate = true;
2090 
2091       if (dump_file && (dump_flags & TDF_DETAILS))
2092 	{
2093 	  fprintf (dump_file, "\n BB %i predicate:", bb->index);
2094 	  bb_predicate.dump (dump_file, info->conds);
2095 	}
2096 
2097       if (fbi.info && nonconstant_names.exists ())
2098 	{
2099 	  predicate phi_predicate;
2100 	  bool first_phi = true;
2101 
2102 	  for (gphi_iterator bsi = gsi_start_phis (bb); !gsi_end_p (bsi);
2103 	       gsi_next (&bsi))
2104 	    {
2105 	      if (first_phi
2106 		  && !phi_result_unknown_predicate (&fbi, info, bb,
2107 						    &phi_predicate,
2108 						    nonconstant_names))
2109 		break;
2110 	      first_phi = false;
2111 	      if (dump_file && (dump_flags & TDF_DETAILS))
2112 		{
2113 		  fprintf (dump_file, "  ");
2114 		  print_gimple_stmt (dump_file, gsi_stmt (bsi), 0);
2115 		}
2116 	      predicate_for_phi_result (info, bsi.phi (), &phi_predicate,
2117 					nonconstant_names);
2118 	    }
2119 	}
2120 
2121       fix_builtin_expect_stmt = find_foldable_builtin_expect (bb);
2122 
2123       for (gimple_stmt_iterator bsi = gsi_start_bb (bb); !gsi_end_p (bsi);
2124 	   gsi_next (&bsi))
2125 	{
2126 	  gimple *stmt = gsi_stmt (bsi);
2127 	  int this_size = estimate_num_insns (stmt, &eni_size_weights);
2128 	  int this_time = estimate_num_insns (stmt, &eni_time_weights);
2129 	  int prob;
2130 	  predicate will_be_nonconstant;
2131 
2132           /* This relation stmt should be folded after we remove
2133              buildin_expect call. Adjust the cost here.  */
2134 	  if (stmt == fix_builtin_expect_stmt)
2135             {
2136               this_size--;
2137               this_time--;
2138             }
2139 
2140 	  if (dump_file && (dump_flags & TDF_DETAILS))
2141 	    {
2142 	      fprintf (dump_file, "  ");
2143 	      print_gimple_stmt (dump_file, stmt, 0);
2144 	      fprintf (dump_file, "\t\tfreq:%3.2f size:%3i time:%3i\n",
2145 		       freq.to_double (), this_size,
2146 		       this_time);
2147 	    }
2148 
2149 	  if (gimple_assign_load_p (stmt) && nonconstant_names.exists ())
2150 	    {
2151 	      predicate this_array_index;
2152 	      this_array_index =
2153 		array_index_predicate (info, nonconstant_names,
2154 				       gimple_assign_rhs1 (stmt));
2155 	      if (this_array_index != false)
2156 		array_index &= this_array_index;
2157 	    }
2158 	  if (gimple_store_p (stmt) && nonconstant_names.exists ())
2159 	    {
2160 	      predicate this_array_index;
2161 	      this_array_index =
2162 		array_index_predicate (info, nonconstant_names,
2163 				       gimple_get_lhs (stmt));
2164 	      if (this_array_index != false)
2165 		array_index &= this_array_index;
2166 	    }
2167 
2168 
2169 	  if (is_gimple_call (stmt)
2170 	      && !gimple_call_internal_p (stmt))
2171 	    {
2172 	      struct cgraph_edge *edge = node->get_edge (stmt);
2173 	      ipa_call_summary *es = ipa_call_summaries->get_create (edge);
2174 
2175 	      /* Special case: results of BUILT_IN_CONSTANT_P will be always
2176 	         resolved as constant.  We however don't want to optimize
2177 	         out the cgraph edges.  */
2178 	      if (nonconstant_names.exists ()
2179 		  && gimple_call_builtin_p (stmt, BUILT_IN_CONSTANT_P)
2180 		  && gimple_call_lhs (stmt)
2181 		  && TREE_CODE (gimple_call_lhs (stmt)) == SSA_NAME)
2182 		{
2183 		  predicate false_p = false;
2184 		  nonconstant_names[SSA_NAME_VERSION (gimple_call_lhs (stmt))]
2185 		    = false_p;
2186 		}
2187 	      if (ipa_node_params_sum)
2188 		{
2189 		  int count = gimple_call_num_args (stmt);
2190 		  int i;
2191 
2192 		  if (count)
2193 		    es->param.safe_grow_cleared (count);
2194 		  for (i = 0; i < count; i++)
2195 		    {
2196 		      int prob = param_change_prob (&fbi, stmt, i);
2197 		      gcc_assert (prob >= 0 && prob <= REG_BR_PROB_BASE);
2198 		      es->param[i].change_prob = prob;
2199 		    }
2200 		}
2201 
2202 	      es->call_stmt_size = this_size;
2203 	      es->call_stmt_time = this_time;
2204 	      es->loop_depth = bb_loop_depth (bb);
2205 	      edge_set_predicate (edge, &bb_predicate);
2206 	      if (edge->speculative)
2207 		{
2208 		  cgraph_edge *direct, *indirect;
2209 		  ipa_ref *ref;
2210 		  edge->speculative_call_info (direct, indirect, ref);
2211 		  gcc_assert (direct == edge);
2212 	          ipa_call_summary *es2
2213 			 = ipa_call_summaries->get_create (indirect);
2214 		  ipa_call_summaries->duplicate (edge, indirect,
2215 						 es, es2);
2216 		}
2217 	    }
2218 
2219 	  /* TODO: When conditional jump or swithc is known to be constant, but
2220 	     we did not translate it into the predicates, we really can account
2221 	     just maximum of the possible paths.  */
2222 	  if (fbi.info)
2223 	    will_be_nonconstant
2224 	      = will_be_nonconstant_predicate (&fbi, info,
2225 					       stmt, nonconstant_names);
2226 	  else
2227 	    will_be_nonconstant = true;
2228 	  if (this_time || this_size)
2229 	    {
2230 	      sreal final_time = (sreal)this_time * freq;
2231 
2232 	      prob = eliminated_by_inlining_prob (&fbi, stmt);
2233 	      if (prob == 1 && dump_file && (dump_flags & TDF_DETAILS))
2234 		fprintf (dump_file,
2235 			 "\t\t50%% will be eliminated by inlining\n");
2236 	      if (prob == 2 && dump_file && (dump_flags & TDF_DETAILS))
2237 		fprintf (dump_file, "\t\tWill be eliminated by inlining\n");
2238 
2239 	      struct predicate p = bb_predicate & will_be_nonconstant;
2240 
2241 	      /* We can ignore statement when we proved it is never going
2242 		 to happen, but we cannot do that for call statements
2243 		 because edges are accounted specially.  */
2244 
2245 	      if (*(is_gimple_call (stmt) ? &bb_predicate : &p) != false)
2246 		{
2247 		  time += final_time;
2248 		  size += this_size;
2249 		}
2250 
2251 	      /* We account everything but the calls.  Calls have their own
2252 	         size/time info attached to cgraph edges.  This is necessary
2253 	         in order to make the cost disappear after inlining.  */
2254 	      if (!is_gimple_call (stmt))
2255 		{
2256 		  if (prob)
2257 		    {
2258 		      predicate ip = bb_predicate & predicate::not_inlined ();
2259 		      info->account_size_time (this_size * prob,
2260 					       (final_time * prob) / 2, ip,
2261 					       p);
2262 		    }
2263 		  if (prob != 2)
2264 		    info->account_size_time (this_size * (2 - prob),
2265 					     (final_time * (2 - prob) / 2),
2266 					     bb_predicate,
2267 					     p);
2268 		}
2269 
2270 	      if (!info->fp_expressions && fp_expression_p (stmt))
2271 		{
2272 		  info->fp_expressions = true;
2273 		  if (dump_file)
2274 		    fprintf (dump_file, "   fp_expression set\n");
2275 		}
2276 
2277 	      gcc_assert (time >= 0);
2278 	      gcc_assert (size >= 0);
2279 	    }
2280 	}
2281     }
2282   set_hint_predicate (&ipa_fn_summaries->get_create (node)->array_index,
2283 		      array_index);
2284   free (order);
2285 
2286   if (nonconstant_names.exists () && !early)
2287     {
2288       struct loop *loop;
2289       predicate loop_iterations = true;
2290       predicate loop_stride = true;
2291 
2292       if (dump_file && (dump_flags & TDF_DETAILS))
2293 	flow_loops_dump (dump_file, NULL, 0);
2294       scev_initialize ();
2295       FOR_EACH_LOOP (loop, 0)
2296 	{
2297 	  vec<edge> exits;
2298 	  edge ex;
2299 	  unsigned int j;
2300 	  struct tree_niter_desc niter_desc;
2301 	  bb_predicate = *(predicate *) loop->header->aux;
2302 
2303 	  exits = get_loop_exit_edges (loop);
2304 	  FOR_EACH_VEC_ELT (exits, j, ex)
2305 	    if (number_of_iterations_exit (loop, ex, &niter_desc, false)
2306 		&& !is_gimple_min_invariant (niter_desc.niter))
2307 	    {
2308 	      predicate will_be_nonconstant
2309 		= will_be_nonconstant_expr_predicate (&fbi, info,
2310 						      niter_desc.niter,
2311 						      nonconstant_names);
2312 	      if (will_be_nonconstant != true)
2313 		will_be_nonconstant = bb_predicate & will_be_nonconstant;
2314 	      if (will_be_nonconstant != true
2315 		  && will_be_nonconstant != false)
2316 		/* This is slightly inprecise.  We may want to represent each
2317 		   loop with independent predicate.  */
2318 		loop_iterations &= will_be_nonconstant;
2319 	    }
2320 	  exits.release ();
2321 	}
2322 
2323       /* To avoid quadratic behavior we analyze stride predicates only
2324          with respect to the containing loop.  Thus we simply iterate
2325 	 over all defs in the outermost loop body.  */
2326       for (loop = loops_for_fn (cfun)->tree_root->inner;
2327 	   loop != NULL; loop = loop->next)
2328 	{
2329 	  basic_block *body = get_loop_body (loop);
2330 	  for (unsigned i = 0; i < loop->num_nodes; i++)
2331 	    {
2332 	      gimple_stmt_iterator gsi;
2333 	      bb_predicate = *(predicate *) body[i]->aux;
2334 	      for (gsi = gsi_start_bb (body[i]); !gsi_end_p (gsi);
2335 		   gsi_next (&gsi))
2336 		{
2337 		  gimple *stmt = gsi_stmt (gsi);
2338 
2339 		  if (!is_gimple_assign (stmt))
2340 		    continue;
2341 
2342 		  tree def = gimple_assign_lhs (stmt);
2343 		  if (TREE_CODE (def) != SSA_NAME)
2344 		    continue;
2345 
2346 		  affine_iv iv;
2347 		  if (!simple_iv (loop_containing_stmt (stmt),
2348 				  loop_containing_stmt (stmt),
2349 				  def, &iv, true)
2350 		      || is_gimple_min_invariant (iv.step))
2351 		    continue;
2352 
2353 		  predicate will_be_nonconstant
2354 		    = will_be_nonconstant_expr_predicate (&fbi, info, iv.step,
2355 							  nonconstant_names);
2356 		  if (will_be_nonconstant != true)
2357 		    will_be_nonconstant = bb_predicate & will_be_nonconstant;
2358 		  if (will_be_nonconstant != true
2359 		      && will_be_nonconstant != false)
2360 		    /* This is slightly inprecise.  We may want to represent
2361 		       each loop with independent predicate.  */
2362 		    loop_stride = loop_stride & will_be_nonconstant;
2363 		}
2364 	    }
2365 	  free (body);
2366 	}
2367       ipa_fn_summary *s = ipa_fn_summaries->get (node);
2368       set_hint_predicate (&s->loop_iterations, loop_iterations);
2369       set_hint_predicate (&s->loop_stride, loop_stride);
2370       scev_finalize ();
2371     }
2372   FOR_ALL_BB_FN (bb, my_function)
2373     {
2374       edge e;
2375       edge_iterator ei;
2376 
2377       if (bb->aux)
2378 	edge_predicate_pool.remove ((predicate *)bb->aux);
2379       bb->aux = NULL;
2380       FOR_EACH_EDGE (e, ei, bb->succs)
2381 	{
2382 	  if (e->aux)
2383 	    edge_predicate_pool.remove ((predicate *) e->aux);
2384 	  e->aux = NULL;
2385 	}
2386     }
2387   ipa_fn_summary *s = ipa_fn_summaries->get (node);
2388   s->time = time;
2389   s->self_size = size;
2390   nonconstant_names.release ();
2391   ipa_release_body_info (&fbi);
2392   if (opt_for_fn (node->decl, optimize))
2393     {
2394       if (!early)
2395         loop_optimizer_finalize ();
2396       else if (!ipa_edge_args_sum)
2397 	ipa_free_all_node_params ();
2398       free_dominance_info (CDI_DOMINATORS);
2399     }
2400   if (dump_file)
2401     {
2402       fprintf (dump_file, "\n");
2403       ipa_dump_fn_summary (dump_file, node);
2404     }
2405 }
2406 
2407 
2408 /* Compute function summary.
2409    EARLY is true when we compute parameters during early opts.  */
2410 
2411 void
compute_fn_summary(struct cgraph_node * node,bool early)2412 compute_fn_summary (struct cgraph_node *node, bool early)
2413 {
2414   HOST_WIDE_INT self_stack_size;
2415   struct cgraph_edge *e;
2416   struct ipa_fn_summary *info;
2417 
2418   gcc_assert (!node->global.inlined_to);
2419 
2420   if (!ipa_fn_summaries)
2421     ipa_fn_summary_alloc ();
2422 
2423   /* Create a new ipa_fn_summary.  */
2424   ((ipa_fn_summary_t *)ipa_fn_summaries)->remove_callees (node);
2425   ipa_fn_summaries->remove (node);
2426   info = ipa_fn_summaries->get_create (node);
2427 
2428   /* Estimate the stack size for the function if we're optimizing.  */
2429   self_stack_size = optimize && !node->thunk.thunk_p
2430 		    ? estimated_stack_frame_size (node) : 0;
2431   info->estimated_self_stack_size = self_stack_size;
2432   info->estimated_stack_size = self_stack_size;
2433   info->stack_frame_offset = 0;
2434 
2435   if (node->thunk.thunk_p)
2436     {
2437       ipa_call_summary *es = ipa_call_summaries->get_create (node->callees);
2438       predicate t = true;
2439 
2440       node->local.can_change_signature = false;
2441       es->call_stmt_size = eni_size_weights.call_cost;
2442       es->call_stmt_time = eni_time_weights.call_cost;
2443       info->account_size_time (ipa_fn_summary::size_scale
2444 			       * PARAM_VALUE
2445 				 (PARAM_UNINLINED_FUNCTION_THUNK_INSNS),
2446 			       PARAM_VALUE
2447 				 (PARAM_UNINLINED_FUNCTION_THUNK_TIME), t, t);
2448       t = predicate::not_inlined ();
2449       info->account_size_time (2 * ipa_fn_summary::size_scale, 0, t, t);
2450       ipa_update_overall_fn_summary (node);
2451       info->self_size = info->size;
2452       if (stdarg_p (TREE_TYPE (node->decl)))
2453 	{
2454 	  info->inlinable = false;
2455 	  node->callees->inline_failed = CIF_VARIADIC_THUNK;
2456 	}
2457       else
2458         info->inlinable = true;
2459     }
2460   else
2461     {
2462        /* Even is_gimple_min_invariant rely on current_function_decl.  */
2463        push_cfun (DECL_STRUCT_FUNCTION (node->decl));
2464 
2465        /* Can this function be inlined at all?  */
2466        if (!opt_for_fn (node->decl, optimize)
2467 	   && !lookup_attribute ("always_inline",
2468 				 DECL_ATTRIBUTES (node->decl)))
2469 	 info->inlinable = false;
2470        else
2471 	 info->inlinable = tree_inlinable_function_p (node->decl);
2472 
2473        /* Type attributes can use parameter indices to describe them.  */
2474        if (TYPE_ATTRIBUTES (TREE_TYPE (node->decl))
2475 	   /* Likewise for #pragma omp declare simd functions or functions
2476 	      with simd attribute.  */
2477 	   || lookup_attribute ("omp declare simd",
2478 				DECL_ATTRIBUTES (node->decl)))
2479 	 node->local.can_change_signature = false;
2480        else
2481 	 {
2482 	   /* Otherwise, inlinable functions always can change signature.  */
2483 	   if (info->inlinable)
2484 	     node->local.can_change_signature = true;
2485 	   else
2486 	     {
2487 	       /* Functions calling builtin_apply cannot change signature.  */
2488 	       for (e = node->callees; e; e = e->next_callee)
2489 		 {
2490 		   tree cdecl = e->callee->decl;
2491 		   if (fndecl_built_in_p (cdecl, BUILT_IN_APPLY_ARGS)
2492 		       || fndecl_built_in_p (cdecl, BUILT_IN_VA_START))
2493 		     break;
2494 		 }
2495 	       node->local.can_change_signature = !e;
2496 	     }
2497 	 }
2498        analyze_function_body (node, early);
2499        pop_cfun ();
2500      }
2501   for (e = node->callees; e; e = e->next_callee)
2502     if (e->callee->comdat_local_p ())
2503       break;
2504   node->calls_comdat_local = (e != NULL);
2505 
2506   /* Inlining characteristics are maintained by the cgraph_mark_inline.  */
2507   info->size = info->self_size;
2508   info->stack_frame_offset = 0;
2509   info->estimated_stack_size = info->estimated_self_stack_size;
2510 
2511   /* Code above should compute exactly the same result as
2512      ipa_update_overall_fn_summary but because computation happens in
2513      different order the roundoff errors result in slight changes.  */
2514   ipa_update_overall_fn_summary (node);
2515   /* In LTO mode we may have speculative edges set.  */
2516   gcc_assert (in_lto_p || info->size == info->self_size);
2517 }
2518 
2519 
2520 /* Compute parameters of functions used by inliner using
2521    current_function_decl.  */
2522 
2523 static unsigned int
compute_fn_summary_for_current(void)2524 compute_fn_summary_for_current (void)
2525 {
2526   compute_fn_summary (cgraph_node::get (current_function_decl), true);
2527   return 0;
2528 }
2529 
2530 /* Estimate benefit devirtualizing indirect edge IE, provided KNOWN_VALS,
2531    KNOWN_CONTEXTS and KNOWN_AGGS.  */
2532 
2533 static bool
estimate_edge_devirt_benefit(struct cgraph_edge * ie,int * size,int * time,vec<tree> known_vals,vec<ipa_polymorphic_call_context> known_contexts,vec<ipa_agg_jump_function_p> known_aggs)2534 estimate_edge_devirt_benefit (struct cgraph_edge *ie,
2535 			      int *size, int *time,
2536 			      vec<tree> known_vals,
2537 			      vec<ipa_polymorphic_call_context> known_contexts,
2538 			      vec<ipa_agg_jump_function_p> known_aggs)
2539 {
2540   tree target;
2541   struct cgraph_node *callee;
2542   struct ipa_fn_summary *isummary;
2543   enum availability avail;
2544   bool speculative;
2545 
2546   if (!known_vals.exists () && !known_contexts.exists ())
2547     return false;
2548   if (!opt_for_fn (ie->caller->decl, flag_indirect_inlining))
2549     return false;
2550 
2551   target = ipa_get_indirect_edge_target (ie, known_vals, known_contexts,
2552 					 known_aggs, &speculative);
2553   if (!target || speculative)
2554     return false;
2555 
2556   /* Account for difference in cost between indirect and direct calls.  */
2557   *size -= (eni_size_weights.indirect_call_cost - eni_size_weights.call_cost);
2558   *time -= (eni_time_weights.indirect_call_cost - eni_time_weights.call_cost);
2559   gcc_checking_assert (*time >= 0);
2560   gcc_checking_assert (*size >= 0);
2561 
2562   callee = cgraph_node::get (target);
2563   if (!callee || !callee->definition)
2564     return false;
2565   callee = callee->function_symbol (&avail);
2566   if (avail < AVAIL_AVAILABLE)
2567     return false;
2568   isummary = ipa_fn_summaries->get (callee);
2569   if (isummary == NULL)
2570     return false;
2571 
2572   return isummary->inlinable;
2573 }
2574 
2575 /* Increase SIZE, MIN_SIZE (if non-NULL) and TIME for size and time needed to
2576    handle edge E with probability PROB.
2577    Set HINTS if edge may be devirtualized.
2578    KNOWN_VALS, KNOWN_AGGS and KNOWN_CONTEXTS describe context of the call
2579    site.  */
2580 
2581 static inline void
estimate_edge_size_and_time(struct cgraph_edge * e,int * size,int * min_size,sreal * time,int prob,vec<tree> known_vals,vec<ipa_polymorphic_call_context> known_contexts,vec<ipa_agg_jump_function_p> known_aggs,ipa_hints * hints)2582 estimate_edge_size_and_time (struct cgraph_edge *e, int *size, int *min_size,
2583 			     sreal *time,
2584 			     int prob,
2585 			     vec<tree> known_vals,
2586 			     vec<ipa_polymorphic_call_context> known_contexts,
2587 			     vec<ipa_agg_jump_function_p> known_aggs,
2588 			     ipa_hints *hints)
2589 {
2590   struct ipa_call_summary *es = ipa_call_summaries->get (e);
2591   int call_size = es->call_stmt_size;
2592   int call_time = es->call_stmt_time;
2593   int cur_size;
2594   if (!e->callee
2595       && estimate_edge_devirt_benefit (e, &call_size, &call_time,
2596 				       known_vals, known_contexts, known_aggs)
2597       && hints && e->maybe_hot_p ())
2598     *hints |= INLINE_HINT_indirect_call;
2599   cur_size = call_size * ipa_fn_summary::size_scale;
2600   *size += cur_size;
2601   if (min_size)
2602     *min_size += cur_size;
2603   if (prob == REG_BR_PROB_BASE)
2604     *time += ((sreal)call_time) * e->sreal_frequency ();
2605   else
2606     *time += ((sreal)call_time * prob) * e->sreal_frequency ();
2607 }
2608 
2609 
2610 
2611 /* Increase SIZE, MIN_SIZE and TIME for size and time needed to handle all
2612    calls in NODE.  POSSIBLE_TRUTHS, KNOWN_VALS, KNOWN_AGGS and KNOWN_CONTEXTS
2613    describe context of the call site.  */
2614 
2615 static void
estimate_calls_size_and_time(struct cgraph_node * node,int * size,int * min_size,sreal * time,ipa_hints * hints,clause_t possible_truths,vec<tree> known_vals,vec<ipa_polymorphic_call_context> known_contexts,vec<ipa_agg_jump_function_p> known_aggs)2616 estimate_calls_size_and_time (struct cgraph_node *node, int *size,
2617 			      int *min_size, sreal *time,
2618 			      ipa_hints *hints,
2619 			      clause_t possible_truths,
2620 			      vec<tree> known_vals,
2621 			      vec<ipa_polymorphic_call_context> known_contexts,
2622 			      vec<ipa_agg_jump_function_p> known_aggs)
2623 {
2624   struct cgraph_edge *e;
2625   for (e = node->callees; e; e = e->next_callee)
2626     {
2627       struct ipa_call_summary *es = ipa_call_summaries->get_create (e);
2628 
2629       /* Do not care about zero sized builtins.  */
2630       if (e->inline_failed && !es->call_stmt_size)
2631 	{
2632 	  gcc_checking_assert (!es->call_stmt_time);
2633 	  continue;
2634 	}
2635       if (!es->predicate
2636 	  || es->predicate->evaluate (possible_truths))
2637 	{
2638 	  if (e->inline_failed)
2639 	    {
2640 	      /* Predicates of calls shall not use NOT_CHANGED codes,
2641 	         sowe do not need to compute probabilities.  */
2642 	      estimate_edge_size_and_time (e, size,
2643 					   es->predicate ? NULL : min_size,
2644 					   time, REG_BR_PROB_BASE,
2645 					   known_vals, known_contexts,
2646 					   known_aggs, hints);
2647 	    }
2648 	  else
2649 	    estimate_calls_size_and_time (e->callee, size, min_size, time,
2650 					  hints,
2651 					  possible_truths,
2652 					  known_vals, known_contexts,
2653 					  known_aggs);
2654 	}
2655     }
2656   for (e = node->indirect_calls; e; e = e->next_callee)
2657     {
2658       struct ipa_call_summary *es = ipa_call_summaries->get_create (e);
2659       if (!es->predicate
2660 	  || es->predicate->evaluate (possible_truths))
2661 	estimate_edge_size_and_time (e, size,
2662 				     es->predicate ? NULL : min_size,
2663 				     time, REG_BR_PROB_BASE,
2664 				     known_vals, known_contexts, known_aggs,
2665 				     hints);
2666     }
2667 }
2668 
2669 
2670 /* Estimate size and time needed to execute NODE assuming
2671    POSSIBLE_TRUTHS clause, and KNOWN_VALS, KNOWN_AGGS and KNOWN_CONTEXTS
2672    information about NODE's arguments.  If non-NULL use also probability
2673    information present in INLINE_PARAM_SUMMARY vector.
2674    Additionally detemine hints determined by the context.  Finally compute
2675    minimal size needed for the call that is independent on the call context and
2676    can be used for fast estimates.  Return the values in RET_SIZE,
2677    RET_MIN_SIZE, RET_TIME and RET_HINTS.  */
2678 
2679 void
estimate_node_size_and_time(struct cgraph_node * node,clause_t possible_truths,clause_t nonspec_possible_truths,vec<tree> known_vals,vec<ipa_polymorphic_call_context> known_contexts,vec<ipa_agg_jump_function_p> known_aggs,int * ret_size,int * ret_min_size,sreal * ret_time,sreal * ret_nonspecialized_time,ipa_hints * ret_hints,vec<inline_param_summary> inline_param_summary)2680 estimate_node_size_and_time (struct cgraph_node *node,
2681 			     clause_t possible_truths,
2682 			     clause_t nonspec_possible_truths,
2683 			     vec<tree> known_vals,
2684 			     vec<ipa_polymorphic_call_context> known_contexts,
2685 			     vec<ipa_agg_jump_function_p> known_aggs,
2686 			     int *ret_size, int *ret_min_size,
2687 			     sreal *ret_time,
2688 			     sreal *ret_nonspecialized_time,
2689 			     ipa_hints *ret_hints,
2690 			     vec<inline_param_summary>
2691 			     inline_param_summary)
2692 {
2693   struct ipa_fn_summary *info = ipa_fn_summaries->get_create (node);
2694   size_time_entry *e;
2695   int size = 0;
2696   sreal time = 0;
2697   int min_size = 0;
2698   ipa_hints hints = 0;
2699   int i;
2700 
2701   if (dump_file && (dump_flags & TDF_DETAILS))
2702     {
2703       bool found = false;
2704       fprintf (dump_file, "   Estimating body: %s/%i\n"
2705 	       "   Known to be false: ", node->name (),
2706 	       node->order);
2707 
2708       for (i = predicate::not_inlined_condition;
2709 	   i < (predicate::first_dynamic_condition
2710 		+ (int) vec_safe_length (info->conds)); i++)
2711 	if (!(possible_truths & (1 << i)))
2712 	  {
2713 	    if (found)
2714 	      fprintf (dump_file, ", ");
2715 	    found = true;
2716 	    dump_condition (dump_file, info->conds, i);
2717 	  }
2718     }
2719 
2720   estimate_calls_size_and_time (node, &size, &min_size, &time, &hints, possible_truths,
2721 				known_vals, known_contexts, known_aggs);
2722   sreal nonspecialized_time = time;
2723 
2724   for (i = 0; vec_safe_iterate (info->size_time_table, i, &e); i++)
2725     {
2726       bool exec = e->exec_predicate.evaluate (nonspec_possible_truths);
2727 
2728       /* Because predicates are conservative, it can happen that nonconst is 1
2729 	 but exec is 0.  */
2730       if (exec)
2731         {
2732           bool nonconst = e->nonconst_predicate.evaluate (possible_truths);
2733 
2734 	  gcc_checking_assert (e->time >= 0);
2735 	  gcc_checking_assert (time >= 0);
2736 
2737 	  /* We compute specialized size only because size of nonspecialized
2738 	     copy is context independent.
2739 
2740 	     The difference between nonspecialized execution and specialized is
2741 	     that nonspecialized is not going to have optimized out computations
2742 	     known to be constant in a specialized setting.  */
2743 	  if (nonconst)
2744 	    size += e->size;
2745 	  nonspecialized_time += e->time;
2746 	  if (!nonconst)
2747 	    ;
2748 	  else if (!inline_param_summary.exists ())
2749 	    {
2750 	      if (nonconst)
2751 	        time += e->time;
2752 	    }
2753 	  else
2754 	    {
2755 	      int prob = e->nonconst_predicate.probability
2756 					       (info->conds, possible_truths,
2757 					        inline_param_summary);
2758 	      gcc_checking_assert (prob >= 0);
2759 	      gcc_checking_assert (prob <= REG_BR_PROB_BASE);
2760 	      time += e->time * prob / REG_BR_PROB_BASE;
2761 	    }
2762 	  gcc_checking_assert (time >= 0);
2763         }
2764      }
2765   gcc_checking_assert ((*info->size_time_table)[0].exec_predicate == true);
2766   gcc_checking_assert ((*info->size_time_table)[0].nonconst_predicate == true);
2767   min_size = (*info->size_time_table)[0].size;
2768   gcc_checking_assert (size >= 0);
2769   gcc_checking_assert (time >= 0);
2770   /* nonspecialized_time should be always bigger than specialized time.
2771      Roundoff issues however may get into the way.  */
2772   gcc_checking_assert ((nonspecialized_time - time * 99 / 100) >= -1);
2773 
2774   /* Roundoff issues may make specialized time bigger than nonspecialized
2775      time.  We do not really want that to happen because some heurstics
2776      may get confused by seeing negative speedups.  */
2777   if (time > nonspecialized_time)
2778     time = nonspecialized_time;
2779 
2780   if (info->loop_iterations
2781       && !info->loop_iterations->evaluate (possible_truths))
2782     hints |= INLINE_HINT_loop_iterations;
2783   if (info->loop_stride
2784       && !info->loop_stride->evaluate (possible_truths))
2785     hints |= INLINE_HINT_loop_stride;
2786   if (info->array_index
2787       && !info->array_index->evaluate (possible_truths))
2788     hints |= INLINE_HINT_array_index;
2789   if (info->scc_no)
2790     hints |= INLINE_HINT_in_scc;
2791   if (DECL_DECLARED_INLINE_P (node->decl))
2792     hints |= INLINE_HINT_declared_inline;
2793 
2794   size = RDIV (size, ipa_fn_summary::size_scale);
2795   min_size = RDIV (min_size, ipa_fn_summary::size_scale);
2796 
2797   if (dump_file && (dump_flags & TDF_DETAILS))
2798     fprintf (dump_file, "\n   size:%i time:%f nonspec time:%f\n", (int) size,
2799 	     time.to_double (), nonspecialized_time.to_double ());
2800   if (ret_time)
2801     *ret_time = time;
2802   if (ret_nonspecialized_time)
2803     *ret_nonspecialized_time = nonspecialized_time;
2804   if (ret_size)
2805     *ret_size = size;
2806   if (ret_min_size)
2807     *ret_min_size = min_size;
2808   if (ret_hints)
2809     *ret_hints = hints;
2810   return;
2811 }
2812 
2813 
2814 /* Estimate size and time needed to execute callee of EDGE assuming that
2815    parameters known to be constant at caller of EDGE are propagated.
2816    KNOWN_VALS and KNOWN_CONTEXTS are vectors of assumed known constant values
2817    and types for parameters.  */
2818 
2819 void
estimate_ipcp_clone_size_and_time(struct cgraph_node * node,vec<tree> known_vals,vec<ipa_polymorphic_call_context> known_contexts,vec<ipa_agg_jump_function_p> known_aggs,int * ret_size,sreal * ret_time,sreal * ret_nonspec_time,ipa_hints * hints)2820 estimate_ipcp_clone_size_and_time (struct cgraph_node *node,
2821 				   vec<tree> known_vals,
2822 				   vec<ipa_polymorphic_call_context>
2823 				   known_contexts,
2824 				   vec<ipa_agg_jump_function_p> known_aggs,
2825 				   int *ret_size, sreal *ret_time,
2826 				   sreal *ret_nonspec_time,
2827 				   ipa_hints *hints)
2828 {
2829   clause_t clause, nonspec_clause;
2830 
2831   evaluate_conditions_for_known_args (node, false, known_vals, known_aggs,
2832 				      &clause, &nonspec_clause);
2833   estimate_node_size_and_time (node, clause, nonspec_clause,
2834 			       known_vals, known_contexts,
2835 			       known_aggs, ret_size, NULL, ret_time,
2836 			       ret_nonspec_time, hints, vNULL);
2837 }
2838 
2839 
2840 /* Update summary information of inline clones after inlining.
2841    Compute peak stack usage.  */
2842 
2843 static void
inline_update_callee_summaries(struct cgraph_node * node,int depth)2844 inline_update_callee_summaries (struct cgraph_node *node, int depth)
2845 {
2846   struct cgraph_edge *e;
2847   ipa_fn_summary *callee_info = ipa_fn_summaries->get (node);
2848   ipa_fn_summary *caller_info = ipa_fn_summaries->get (node->callers->caller);
2849   HOST_WIDE_INT peak;
2850 
2851   callee_info->stack_frame_offset
2852     = caller_info->stack_frame_offset
2853     + caller_info->estimated_self_stack_size;
2854   peak = callee_info->stack_frame_offset
2855     + callee_info->estimated_self_stack_size;
2856 
2857   ipa_fn_summary *s = ipa_fn_summaries->get (node->global.inlined_to);
2858   if (s->estimated_stack_size < peak)
2859     s->estimated_stack_size = peak;
2860   ipa_propagate_frequency (node);
2861   for (e = node->callees; e; e = e->next_callee)
2862     {
2863       if (!e->inline_failed)
2864 	inline_update_callee_summaries (e->callee, depth);
2865       ipa_call_summaries->get (e)->loop_depth += depth;
2866     }
2867   for (e = node->indirect_calls; e; e = e->next_callee)
2868     ipa_call_summaries->get (e)->loop_depth += depth;
2869 }
2870 
2871 /* Update change_prob of EDGE after INLINED_EDGE has been inlined.
2872    When functoin A is inlined in B and A calls C with parameter that
2873    changes with probability PROB1 and C is known to be passthroug
2874    of argument if B that change with probability PROB2, the probability
2875    of change is now PROB1*PROB2.  */
2876 
2877 static void
remap_edge_change_prob(struct cgraph_edge * inlined_edge,struct cgraph_edge * edge)2878 remap_edge_change_prob (struct cgraph_edge *inlined_edge,
2879 			struct cgraph_edge *edge)
2880 {
2881   if (ipa_node_params_sum)
2882     {
2883       int i;
2884       struct ipa_edge_args *args = IPA_EDGE_REF (edge);
2885       struct ipa_call_summary *es = ipa_call_summaries->get (edge);
2886       struct ipa_call_summary *inlined_es
2887 	= ipa_call_summaries->get (inlined_edge);
2888 
2889       if (es->param.length () == 0)
2890 	return;
2891 
2892       for (i = 0; i < ipa_get_cs_argument_count (args); i++)
2893 	{
2894 	  struct ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, i);
2895 	  if (jfunc->type == IPA_JF_PASS_THROUGH
2896 	      || jfunc->type == IPA_JF_ANCESTOR)
2897 	    {
2898 	      int id = jfunc->type == IPA_JF_PASS_THROUGH
2899 		       ? ipa_get_jf_pass_through_formal_id (jfunc)
2900 		       : ipa_get_jf_ancestor_formal_id (jfunc);
2901 	      if (id < (int) inlined_es->param.length ())
2902 		{
2903 		  int prob1 = es->param[i].change_prob;
2904 		  int prob2 = inlined_es->param[id].change_prob;
2905 		  int prob = combine_probabilities (prob1, prob2);
2906 
2907 		  if (prob1 && prob2 && !prob)
2908 		    prob = 1;
2909 
2910 		  es->param[i].change_prob = prob;
2911 		}
2912 	    }
2913 	}
2914     }
2915 }
2916 
2917 /* Update edge summaries of NODE after INLINED_EDGE has been inlined.
2918 
2919    Remap predicates of callees of NODE.  Rest of arguments match
2920    remap_predicate.
2921 
2922    Also update change probabilities.  */
2923 
2924 static void
remap_edge_summaries(struct cgraph_edge * inlined_edge,struct cgraph_node * node,struct ipa_fn_summary * info,struct ipa_fn_summary * callee_info,vec<int> operand_map,vec<int> offset_map,clause_t possible_truths,predicate * toplev_predicate)2925 remap_edge_summaries (struct cgraph_edge *inlined_edge,
2926 		      struct cgraph_node *node,
2927 		      struct ipa_fn_summary *info,
2928 		      struct ipa_fn_summary *callee_info,
2929 		      vec<int> operand_map,
2930 		      vec<int> offset_map,
2931 		      clause_t possible_truths,
2932 		      predicate *toplev_predicate)
2933 {
2934   struct cgraph_edge *e, *next;
2935   for (e = node->callees; e; e = next)
2936     {
2937       struct ipa_call_summary *es = ipa_call_summaries->get (e);
2938       predicate p;
2939       next = e->next_callee;
2940 
2941       if (e->inline_failed)
2942 	{
2943 	  remap_edge_change_prob (inlined_edge, e);
2944 
2945 	  if (es->predicate)
2946 	    {
2947 	      p = es->predicate->remap_after_inlining
2948 				     (info, callee_info, operand_map,
2949 				      offset_map, possible_truths,
2950 				      *toplev_predicate);
2951 	      edge_set_predicate (e, &p);
2952 	    }
2953 	  else
2954 	    edge_set_predicate (e, toplev_predicate);
2955 	}
2956       else
2957 	remap_edge_summaries (inlined_edge, e->callee, info, callee_info,
2958 			      operand_map, offset_map, possible_truths,
2959 			      toplev_predicate);
2960     }
2961   for (e = node->indirect_calls; e; e = next)
2962     {
2963       struct ipa_call_summary *es = ipa_call_summaries->get (e);
2964       predicate p;
2965       next = e->next_callee;
2966 
2967       remap_edge_change_prob (inlined_edge, e);
2968       if (es->predicate)
2969 	{
2970 	  p = es->predicate->remap_after_inlining
2971 				 (info, callee_info, operand_map, offset_map,
2972 			          possible_truths, *toplev_predicate);
2973 	  edge_set_predicate (e, &p);
2974 	}
2975       else
2976 	edge_set_predicate (e, toplev_predicate);
2977     }
2978 }
2979 
2980 /* Same as remap_predicate, but set result into hint *HINT.  */
2981 
2982 static void
remap_hint_predicate(struct ipa_fn_summary * info,struct ipa_fn_summary * callee_info,predicate ** hint,vec<int> operand_map,vec<int> offset_map,clause_t possible_truths,predicate * toplev_predicate)2983 remap_hint_predicate (struct ipa_fn_summary *info,
2984 		      struct ipa_fn_summary *callee_info,
2985 		      predicate **hint,
2986 		      vec<int> operand_map,
2987 		      vec<int> offset_map,
2988 		      clause_t possible_truths,
2989 		      predicate *toplev_predicate)
2990 {
2991   predicate p;
2992 
2993   if (!*hint)
2994     return;
2995   p = (*hint)->remap_after_inlining
2996 			 (info, callee_info,
2997 			  operand_map, offset_map,
2998 			  possible_truths, *toplev_predicate);
2999   if (p != false && p != true)
3000     {
3001       if (!*hint)
3002 	set_hint_predicate (hint, p);
3003       else
3004 	**hint &= p;
3005     }
3006 }
3007 
3008 /* We inlined EDGE.  Update summary of the function we inlined into.  */
3009 
3010 void
ipa_merge_fn_summary_after_inlining(struct cgraph_edge * edge)3011 ipa_merge_fn_summary_after_inlining (struct cgraph_edge *edge)
3012 {
3013   ipa_fn_summary *callee_info = ipa_fn_summaries->get (edge->callee);
3014   struct cgraph_node *to = (edge->caller->global.inlined_to
3015 			    ? edge->caller->global.inlined_to : edge->caller);
3016   struct ipa_fn_summary *info = ipa_fn_summaries->get (to);
3017   clause_t clause = 0;	/* not_inline is known to be false.  */
3018   size_time_entry *e;
3019   vec<int> operand_map = vNULL;
3020   vec<int> offset_map = vNULL;
3021   int i;
3022   predicate toplev_predicate;
3023   predicate true_p = true;
3024   struct ipa_call_summary *es = ipa_call_summaries->get (edge);
3025 
3026   if (es->predicate)
3027     toplev_predicate = *es->predicate;
3028   else
3029     toplev_predicate = true;
3030 
3031   info->fp_expressions |= callee_info->fp_expressions;
3032 
3033   if (callee_info->conds)
3034     evaluate_properties_for_edge (edge, true, &clause, NULL, NULL, NULL, NULL);
3035   if (ipa_node_params_sum && callee_info->conds)
3036     {
3037       struct ipa_edge_args *args = IPA_EDGE_REF (edge);
3038       int count = ipa_get_cs_argument_count (args);
3039       int i;
3040 
3041       if (count)
3042 	{
3043 	  operand_map.safe_grow_cleared (count);
3044 	  offset_map.safe_grow_cleared (count);
3045 	}
3046       for (i = 0; i < count; i++)
3047 	{
3048 	  struct ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, i);
3049 	  int map = -1;
3050 
3051 	  /* TODO: handle non-NOPs when merging.  */
3052 	  if (jfunc->type == IPA_JF_PASS_THROUGH)
3053 	    {
3054 	      if (ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
3055 		map = ipa_get_jf_pass_through_formal_id (jfunc);
3056 	      if (!ipa_get_jf_pass_through_agg_preserved (jfunc))
3057 		offset_map[i] = -1;
3058 	    }
3059 	  else if (jfunc->type == IPA_JF_ANCESTOR)
3060 	    {
3061 	      HOST_WIDE_INT offset = ipa_get_jf_ancestor_offset (jfunc);
3062 	      if (offset >= 0 && offset < INT_MAX)
3063 		{
3064 		  map = ipa_get_jf_ancestor_formal_id (jfunc);
3065 		  if (!ipa_get_jf_ancestor_agg_preserved (jfunc))
3066 		    offset = -1;
3067 		  offset_map[i] = offset;
3068 		}
3069 	    }
3070 	  operand_map[i] = map;
3071 	  gcc_assert (map < ipa_get_param_count (IPA_NODE_REF (to)));
3072 	}
3073     }
3074   for (i = 0; vec_safe_iterate (callee_info->size_time_table, i, &e); i++)
3075     {
3076       predicate p;
3077       p = e->exec_predicate.remap_after_inlining
3078 			     (info, callee_info, operand_map,
3079 			      offset_map, clause,
3080 			      toplev_predicate);
3081       predicate nonconstp;
3082       nonconstp = e->nonconst_predicate.remap_after_inlining
3083 				     (info, callee_info, operand_map,
3084 				      offset_map, clause,
3085 				      toplev_predicate);
3086       if (p != false && nonconstp != false)
3087 	{
3088 	  sreal add_time = ((sreal)e->time * edge->sreal_frequency ());
3089 	  int prob = e->nonconst_predicate.probability (callee_info->conds,
3090 							clause, es->param);
3091 	  add_time = add_time * prob / REG_BR_PROB_BASE;
3092 	  if (prob != REG_BR_PROB_BASE
3093 	      && dump_file && (dump_flags & TDF_DETAILS))
3094 	    {
3095 	      fprintf (dump_file, "\t\tScaling time by probability:%f\n",
3096 		       (double) prob / REG_BR_PROB_BASE);
3097 	    }
3098 	  info->account_size_time (e->size, add_time, p, nonconstp);
3099 	}
3100     }
3101   remap_edge_summaries (edge, edge->callee, info, callee_info, operand_map,
3102 			offset_map, clause, &toplev_predicate);
3103   remap_hint_predicate (info, callee_info,
3104 			&callee_info->loop_iterations,
3105 			operand_map, offset_map, clause, &toplev_predicate);
3106   remap_hint_predicate (info, callee_info,
3107 			&callee_info->loop_stride,
3108 			operand_map, offset_map, clause, &toplev_predicate);
3109   remap_hint_predicate (info, callee_info,
3110 			&callee_info->array_index,
3111 			operand_map, offset_map, clause, &toplev_predicate);
3112 
3113   ipa_call_summary *s = ipa_call_summaries->get (edge);
3114   inline_update_callee_summaries (edge->callee, s->loop_depth);
3115 
3116   /* We do not maintain predicates of inlined edges, free it.  */
3117   edge_set_predicate (edge, &true_p);
3118   /* Similarly remove param summaries.  */
3119   es->param.release ();
3120   operand_map.release ();
3121   offset_map.release ();
3122 }
3123 
3124 /* For performance reasons ipa_merge_fn_summary_after_inlining is not updating overall size
3125    and time.  Recompute it.  */
3126 
3127 void
ipa_update_overall_fn_summary(struct cgraph_node * node)3128 ipa_update_overall_fn_summary (struct cgraph_node *node)
3129 {
3130   struct ipa_fn_summary *info = ipa_fn_summaries->get_create (node);
3131   size_time_entry *e;
3132   int i;
3133 
3134   info->size = 0;
3135   info->time = 0;
3136   for (i = 0; vec_safe_iterate (info->size_time_table, i, &e); i++)
3137     {
3138       info->size += e->size;
3139       info->time += e->time;
3140     }
3141   estimate_calls_size_and_time (node, &info->size, &info->min_size,
3142 				&info->time, NULL,
3143 				~(clause_t) (1 << predicate::false_condition),
3144 				vNULL, vNULL, vNULL);
3145   info->size = (info->size + ipa_fn_summary::size_scale / 2) / ipa_fn_summary::size_scale;
3146 }
3147 
3148 
3149 /* This function performs intraprocedural analysis in NODE that is required to
3150    inline indirect calls.  */
3151 
3152 static void
inline_indirect_intraprocedural_analysis(struct cgraph_node * node)3153 inline_indirect_intraprocedural_analysis (struct cgraph_node *node)
3154 {
3155   ipa_analyze_node (node);
3156   if (dump_file && (dump_flags & TDF_DETAILS))
3157     {
3158       ipa_print_node_params (dump_file, node);
3159       ipa_print_node_jump_functions (dump_file, node);
3160     }
3161 }
3162 
3163 
3164 /* Note function body size.  */
3165 
3166 void
inline_analyze_function(struct cgraph_node * node)3167 inline_analyze_function (struct cgraph_node *node)
3168 {
3169   push_cfun (DECL_STRUCT_FUNCTION (node->decl));
3170 
3171   if (dump_file)
3172     fprintf (dump_file, "\nAnalyzing function: %s/%u\n",
3173 	     node->name (), node->order);
3174   if (opt_for_fn (node->decl, optimize) && !node->thunk.thunk_p)
3175     inline_indirect_intraprocedural_analysis (node);
3176   compute_fn_summary (node, false);
3177   if (!optimize)
3178     {
3179       struct cgraph_edge *e;
3180       for (e = node->callees; e; e = e->next_callee)
3181 	e->inline_failed = CIF_FUNCTION_NOT_OPTIMIZED;
3182       for (e = node->indirect_calls; e; e = e->next_callee)
3183 	e->inline_failed = CIF_FUNCTION_NOT_OPTIMIZED;
3184     }
3185 
3186   pop_cfun ();
3187 }
3188 
3189 
3190 /* Called when new function is inserted to callgraph late.  */
3191 
3192 void
insert(struct cgraph_node * node,ipa_fn_summary *)3193 ipa_fn_summary_t::insert (struct cgraph_node *node, ipa_fn_summary *)
3194 {
3195   inline_analyze_function (node);
3196 }
3197 
3198 /* Note function body size.  */
3199 
3200 static void
ipa_fn_summary_generate(void)3201 ipa_fn_summary_generate (void)
3202 {
3203   struct cgraph_node *node;
3204 
3205   FOR_EACH_DEFINED_FUNCTION (node)
3206     if (DECL_STRUCT_FUNCTION (node->decl))
3207       node->local.versionable = tree_versionable_function_p (node->decl);
3208 
3209   ipa_fn_summary_alloc ();
3210 
3211   ipa_fn_summaries->enable_insertion_hook ();
3212 
3213   ipa_register_cgraph_hooks ();
3214 
3215   FOR_EACH_DEFINED_FUNCTION (node)
3216     if (!node->alias
3217 	&& (flag_generate_lto || flag_generate_offload|| flag_wpa
3218 	    || opt_for_fn (node->decl, optimize)))
3219       inline_analyze_function (node);
3220 }
3221 
3222 
3223 /* Write inline summary for edge E to OB.  */
3224 
3225 static void
read_ipa_call_summary(struct lto_input_block * ib,struct cgraph_edge * e,bool prevails)3226 read_ipa_call_summary (struct lto_input_block *ib, struct cgraph_edge *e,
3227 		       bool prevails)
3228 {
3229   struct ipa_call_summary *es = prevails
3230 				? ipa_call_summaries->get_create (e) : NULL;
3231   predicate p;
3232   int length, i;
3233 
3234   int size = streamer_read_uhwi (ib);
3235   int time = streamer_read_uhwi (ib);
3236   int depth = streamer_read_uhwi (ib);
3237 
3238   if (es)
3239     {
3240       es->call_stmt_size = size;
3241       es->call_stmt_time = time;
3242       es->loop_depth = depth;
3243     }
3244 
3245   bitpack_d bp = streamer_read_bitpack (ib);
3246   if (es)
3247     es->is_return_callee_uncaptured = bp_unpack_value (&bp, 1);
3248   else
3249     bp_unpack_value (&bp, 1);
3250 
3251   p.stream_in (ib);
3252   if (es)
3253     edge_set_predicate (e, &p);
3254   length = streamer_read_uhwi (ib);
3255   if (length && es && e->possibly_call_in_translation_unit_p ())
3256     {
3257       es->param.safe_grow_cleared (length);
3258       for (i = 0; i < length; i++)
3259 	es->param[i].change_prob = streamer_read_uhwi (ib);
3260     }
3261   else
3262     {
3263       for (i = 0; i < length; i++)
3264 	streamer_read_uhwi (ib);
3265     }
3266 }
3267 
3268 
3269 /* Stream in inline summaries from the section.  */
3270 
3271 static void
inline_read_section(struct lto_file_decl_data * file_data,const char * data,size_t len)3272 inline_read_section (struct lto_file_decl_data *file_data, const char *data,
3273 		     size_t len)
3274 {
3275   const struct lto_function_header *header =
3276     (const struct lto_function_header *) data;
3277   const int cfg_offset = sizeof (struct lto_function_header);
3278   const int main_offset = cfg_offset + header->cfg_size;
3279   const int string_offset = main_offset + header->main_size;
3280   struct data_in *data_in;
3281   unsigned int i, count2, j;
3282   unsigned int f_count;
3283 
3284   lto_input_block ib ((const char *) data + main_offset, header->main_size,
3285 		      file_data->mode_table);
3286 
3287   data_in =
3288     lto_data_in_create (file_data, (const char *) data + string_offset,
3289 			header->string_size, vNULL);
3290   f_count = streamer_read_uhwi (&ib);
3291   for (i = 0; i < f_count; i++)
3292     {
3293       unsigned int index;
3294       struct cgraph_node *node;
3295       struct ipa_fn_summary *info;
3296       lto_symtab_encoder_t encoder;
3297       struct bitpack_d bp;
3298       struct cgraph_edge *e;
3299       predicate p;
3300 
3301       index = streamer_read_uhwi (&ib);
3302       encoder = file_data->symtab_node_encoder;
3303       node = dyn_cast<cgraph_node *> (lto_symtab_encoder_deref (encoder,
3304 								index));
3305       info = node->prevailing_p () ? ipa_fn_summaries->get_create (node) : NULL;
3306 
3307       int stack_size = streamer_read_uhwi (&ib);
3308       int size = streamer_read_uhwi (&ib);
3309       sreal time = sreal::stream_in (&ib);
3310 
3311       if (info)
3312 	{
3313 	  info->estimated_stack_size
3314 	    = info->estimated_self_stack_size = stack_size;
3315 	  info->size = info->self_size = size;
3316 	  info->time = time;
3317 	}
3318 
3319       bp = streamer_read_bitpack (&ib);
3320       if (info)
3321 	{
3322           info->inlinable = bp_unpack_value (&bp, 1);
3323           info->fp_expressions = bp_unpack_value (&bp, 1);
3324 	}
3325       else
3326 	{
3327           bp_unpack_value (&bp, 1);
3328           bp_unpack_value (&bp, 1);
3329 	}
3330 
3331       count2 = streamer_read_uhwi (&ib);
3332       gcc_assert (!info || !info->conds);
3333       for (j = 0; j < count2; j++)
3334 	{
3335 	  struct condition c;
3336 	  c.operand_num = streamer_read_uhwi (&ib);
3337 	  c.size = streamer_read_uhwi (&ib);
3338 	  c.code = (enum tree_code) streamer_read_uhwi (&ib);
3339 	  c.val = stream_read_tree (&ib, data_in);
3340 	  bp = streamer_read_bitpack (&ib);
3341 	  c.agg_contents = bp_unpack_value (&bp, 1);
3342 	  c.by_ref = bp_unpack_value (&bp, 1);
3343 	  if (c.agg_contents)
3344 	    c.offset = streamer_read_uhwi (&ib);
3345 	  if (info)
3346 	    vec_safe_push (info->conds, c);
3347 	}
3348       count2 = streamer_read_uhwi (&ib);
3349       gcc_assert (!info || !info->size_time_table);
3350       for (j = 0; j < count2; j++)
3351 	{
3352 	  struct size_time_entry e;
3353 
3354 	  e.size = streamer_read_uhwi (&ib);
3355 	  e.time = sreal::stream_in (&ib);
3356 	  e.exec_predicate.stream_in (&ib);
3357 	  e.nonconst_predicate.stream_in (&ib);
3358 
3359 	  if (info)
3360 	    vec_safe_push (info->size_time_table, e);
3361 	}
3362 
3363       p.stream_in (&ib);
3364       if (info)
3365         set_hint_predicate (&info->loop_iterations, p);
3366       p.stream_in (&ib);
3367       if (info)
3368         set_hint_predicate (&info->loop_stride, p);
3369       p.stream_in (&ib);
3370       if (info)
3371         set_hint_predicate (&info->array_index, p);
3372       for (e = node->callees; e; e = e->next_callee)
3373 	read_ipa_call_summary (&ib, e, info != NULL);
3374       for (e = node->indirect_calls; e; e = e->next_callee)
3375 	read_ipa_call_summary (&ib, e, info != NULL);
3376     }
3377 
3378   lto_free_section_data (file_data, LTO_section_ipa_fn_summary, NULL, data,
3379 			 len);
3380   lto_data_in_delete (data_in);
3381 }
3382 
3383 
3384 /* Read inline summary.  Jump functions are shared among ipa-cp
3385    and inliner, so when ipa-cp is active, we don't need to write them
3386    twice.  */
3387 
3388 static void
ipa_fn_summary_read(void)3389 ipa_fn_summary_read (void)
3390 {
3391   struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
3392   struct lto_file_decl_data *file_data;
3393   unsigned int j = 0;
3394 
3395   ipa_fn_summary_alloc ();
3396 
3397   while ((file_data = file_data_vec[j++]))
3398     {
3399       size_t len;
3400       const char *data = lto_get_section_data (file_data,
3401 					       LTO_section_ipa_fn_summary,
3402 					       NULL, &len);
3403       if (data)
3404 	inline_read_section (file_data, data, len);
3405       else
3406 	/* Fatal error here.  We do not want to support compiling ltrans units
3407 	   with different version of compiler or different flags than the WPA
3408 	   unit, so this should never happen.  */
3409 	fatal_error (input_location,
3410 		     "ipa inline summary is missing in input file");
3411     }
3412   ipa_register_cgraph_hooks ();
3413   if (!flag_ipa_cp)
3414     ipa_prop_read_jump_functions ();
3415 
3416   gcc_assert (ipa_fn_summaries);
3417   ipa_fn_summaries->enable_insertion_hook ();
3418 }
3419 
3420 
3421 /* Write inline summary for edge E to OB.  */
3422 
3423 static void
write_ipa_call_summary(struct output_block * ob,struct cgraph_edge * e)3424 write_ipa_call_summary (struct output_block *ob, struct cgraph_edge *e)
3425 {
3426   struct ipa_call_summary *es = ipa_call_summaries->get (e);
3427   int i;
3428 
3429   streamer_write_uhwi (ob, es->call_stmt_size);
3430   streamer_write_uhwi (ob, es->call_stmt_time);
3431   streamer_write_uhwi (ob, es->loop_depth);
3432 
3433   bitpack_d bp = bitpack_create (ob->main_stream);
3434   bp_pack_value (&bp, es->is_return_callee_uncaptured, 1);
3435   streamer_write_bitpack (&bp);
3436 
3437   if (es->predicate)
3438     es->predicate->stream_out (ob);
3439   else
3440     streamer_write_uhwi (ob, 0);
3441   streamer_write_uhwi (ob, es->param.length ());
3442   for (i = 0; i < (int) es->param.length (); i++)
3443     streamer_write_uhwi (ob, es->param[i].change_prob);
3444 }
3445 
3446 
3447 /* Write inline summary for node in SET.
3448    Jump functions are shared among ipa-cp and inliner, so when ipa-cp is
3449    active, we don't need to write them twice.  */
3450 
3451 static void
ipa_fn_summary_write(void)3452 ipa_fn_summary_write (void)
3453 {
3454   struct output_block *ob = create_output_block (LTO_section_ipa_fn_summary);
3455   lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
3456   unsigned int count = 0;
3457   int i;
3458 
3459   for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
3460     {
3461       symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
3462       cgraph_node *cnode = dyn_cast <cgraph_node *> (snode);
3463       if (cnode && cnode->definition && !cnode->alias)
3464 	count++;
3465     }
3466   streamer_write_uhwi (ob, count);
3467 
3468   for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
3469     {
3470       symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
3471       cgraph_node *cnode = dyn_cast <cgraph_node *> (snode);
3472       if (cnode && cnode->definition && !cnode->alias)
3473 	{
3474 	  struct ipa_fn_summary *info = ipa_fn_summaries->get (cnode);
3475 	  struct bitpack_d bp;
3476 	  struct cgraph_edge *edge;
3477 	  int i;
3478 	  size_time_entry *e;
3479 	  struct condition *c;
3480 
3481 	  streamer_write_uhwi (ob, lto_symtab_encoder_encode (encoder, cnode));
3482 	  streamer_write_hwi (ob, info->estimated_self_stack_size);
3483 	  streamer_write_hwi (ob, info->self_size);
3484 	  info->time.stream_out (ob);
3485 	  bp = bitpack_create (ob->main_stream);
3486 	  bp_pack_value (&bp, info->inlinable, 1);
3487 	  bp_pack_value (&bp, false, 1);
3488 	  bp_pack_value (&bp, info->fp_expressions, 1);
3489 	  streamer_write_bitpack (&bp);
3490 	  streamer_write_uhwi (ob, vec_safe_length (info->conds));
3491 	  for (i = 0; vec_safe_iterate (info->conds, i, &c); i++)
3492 	    {
3493 	      streamer_write_uhwi (ob, c->operand_num);
3494 	      streamer_write_uhwi (ob, c->size);
3495 	      streamer_write_uhwi (ob, c->code);
3496 	      stream_write_tree (ob, c->val, true);
3497 	      bp = bitpack_create (ob->main_stream);
3498 	      bp_pack_value (&bp, c->agg_contents, 1);
3499 	      bp_pack_value (&bp, c->by_ref, 1);
3500 	      streamer_write_bitpack (&bp);
3501 	      if (c->agg_contents)
3502 		streamer_write_uhwi (ob, c->offset);
3503 	    }
3504 	  streamer_write_uhwi (ob, vec_safe_length (info->size_time_table));
3505 	  for (i = 0; vec_safe_iterate (info->size_time_table, i, &e); i++)
3506 	    {
3507 	      streamer_write_uhwi (ob, e->size);
3508 	      e->time.stream_out (ob);
3509 	      e->exec_predicate.stream_out (ob);
3510 	      e->nonconst_predicate.stream_out (ob);
3511 	    }
3512 	  if (info->loop_iterations)
3513 	    info->loop_iterations->stream_out (ob);
3514  	  else
3515 	    streamer_write_uhwi (ob, 0);
3516 	  if (info->loop_stride)
3517 	    info->loop_stride->stream_out (ob);
3518  	  else
3519 	    streamer_write_uhwi (ob, 0);
3520 	  if (info->array_index)
3521 	    info->array_index->stream_out (ob);
3522 	  else
3523 	    streamer_write_uhwi (ob, 0);
3524 	  for (edge = cnode->callees; edge; edge = edge->next_callee)
3525 	    write_ipa_call_summary (ob, edge);
3526 	  for (edge = cnode->indirect_calls; edge; edge = edge->next_callee)
3527 	    write_ipa_call_summary (ob, edge);
3528 	}
3529     }
3530   streamer_write_char_stream (ob->main_stream, 0);
3531   produce_asm (ob, NULL);
3532   destroy_output_block (ob);
3533 
3534   if (!flag_ipa_cp)
3535     ipa_prop_write_jump_functions ();
3536 }
3537 
3538 
3539 /* Release inline summary.  */
3540 
3541 void
ipa_free_fn_summary(void)3542 ipa_free_fn_summary (void)
3543 {
3544   struct cgraph_node *node;
3545   if (!ipa_call_summaries)
3546     return;
3547   FOR_EACH_DEFINED_FUNCTION (node)
3548     if (!node->alias)
3549       ipa_fn_summaries->remove (node);
3550   ipa_fn_summaries->release ();
3551   ipa_fn_summaries = NULL;
3552   ipa_call_summaries->release ();
3553   delete ipa_call_summaries;
3554   ipa_call_summaries = NULL;
3555   edge_predicate_pool.release ();
3556 }
3557 
3558 namespace {
3559 
3560 const pass_data pass_data_local_fn_summary =
3561 {
3562   GIMPLE_PASS, /* type */
3563   "local-fnsummary", /* name */
3564   OPTGROUP_INLINE, /* optinfo_flags */
3565   TV_INLINE_PARAMETERS, /* tv_id */
3566   0, /* properties_required */
3567   0, /* properties_provided */
3568   0, /* properties_destroyed */
3569   0, /* todo_flags_start */
3570   0, /* todo_flags_finish */
3571 };
3572 
3573 class pass_local_fn_summary : public gimple_opt_pass
3574 {
3575 public:
pass_local_fn_summary(gcc::context * ctxt)3576   pass_local_fn_summary (gcc::context *ctxt)
3577     : gimple_opt_pass (pass_data_local_fn_summary, ctxt)
3578   {}
3579 
3580   /* opt_pass methods: */
clone()3581   opt_pass * clone () { return new pass_local_fn_summary (m_ctxt); }
execute(function *)3582   virtual unsigned int execute (function *)
3583     {
3584       return compute_fn_summary_for_current ();
3585     }
3586 
3587 }; // class pass_local_fn_summary
3588 
3589 } // anon namespace
3590 
3591 gimple_opt_pass *
make_pass_local_fn_summary(gcc::context * ctxt)3592 make_pass_local_fn_summary (gcc::context *ctxt)
3593 {
3594   return new pass_local_fn_summary (ctxt);
3595 }
3596 
3597 
3598 /* Free inline summary.  */
3599 
3600 namespace {
3601 
3602 const pass_data pass_data_ipa_free_fn_summary =
3603 {
3604   SIMPLE_IPA_PASS, /* type */
3605   "free-fnsummary", /* name */
3606   OPTGROUP_NONE, /* optinfo_flags */
3607   TV_IPA_FREE_INLINE_SUMMARY, /* tv_id */
3608   0, /* properties_required */
3609   0, /* properties_provided */
3610   0, /* properties_destroyed */
3611   0, /* todo_flags_start */
3612   0, /* todo_flags_finish */
3613 };
3614 
3615 class pass_ipa_free_fn_summary : public simple_ipa_opt_pass
3616 {
3617 public:
pass_ipa_free_fn_summary(gcc::context * ctxt)3618   pass_ipa_free_fn_summary (gcc::context *ctxt)
3619     : simple_ipa_opt_pass (pass_data_ipa_free_fn_summary, ctxt),
3620       small_p (false)
3621   {}
3622 
3623   /* opt_pass methods: */
clone()3624   opt_pass *clone () { return new pass_ipa_free_fn_summary (m_ctxt); }
set_pass_param(unsigned int n,bool param)3625   void set_pass_param (unsigned int n, bool param)
3626     {
3627       gcc_assert (n == 0);
3628       small_p = param;
3629     }
gate(function *)3630   virtual bool gate (function *) { return small_p || !flag_wpa; }
execute(function *)3631   virtual unsigned int execute (function *)
3632     {
3633       ipa_free_fn_summary ();
3634       return 0;
3635     }
3636 
3637 private:
3638   bool small_p;
3639 }; // class pass_ipa_free_fn_summary
3640 
3641 } // anon namespace
3642 
3643 simple_ipa_opt_pass *
make_pass_ipa_free_fn_summary(gcc::context * ctxt)3644 make_pass_ipa_free_fn_summary (gcc::context *ctxt)
3645 {
3646   return new pass_ipa_free_fn_summary (ctxt);
3647 }
3648 
3649 namespace {
3650 
3651 const pass_data pass_data_ipa_fn_summary =
3652 {
3653   IPA_PASS, /* type */
3654   "fnsummary", /* name */
3655   OPTGROUP_INLINE, /* optinfo_flags */
3656   TV_IPA_FNSUMMARY, /* tv_id */
3657   0, /* properties_required */
3658   0, /* properties_provided */
3659   0, /* properties_destroyed */
3660   0, /* todo_flags_start */
3661   ( TODO_dump_symtab ), /* todo_flags_finish */
3662 };
3663 
3664 class pass_ipa_fn_summary : public ipa_opt_pass_d
3665 {
3666 public:
pass_ipa_fn_summary(gcc::context * ctxt)3667   pass_ipa_fn_summary (gcc::context *ctxt)
3668     : ipa_opt_pass_d (pass_data_ipa_fn_summary, ctxt,
3669 		      ipa_fn_summary_generate, /* generate_summary */
3670 		      ipa_fn_summary_write, /* write_summary */
3671 		      ipa_fn_summary_read, /* read_summary */
3672 		      NULL, /* write_optimization_summary */
3673 		      NULL, /* read_optimization_summary */
3674 		      NULL, /* stmt_fixup */
3675 		      0, /* function_transform_todo_flags_start */
3676 		      NULL, /* function_transform */
3677 		      NULL) /* variable_transform */
3678   {}
3679 
3680   /* opt_pass methods: */
execute(function *)3681   virtual unsigned int execute (function *) { return 0; }
3682 
3683 }; // class pass_ipa_fn_summary
3684 
3685 } // anon namespace
3686 
3687 ipa_opt_pass_d *
make_pass_ipa_fn_summary(gcc::context * ctxt)3688 make_pass_ipa_fn_summary (gcc::context *ctxt)
3689 {
3690   return new pass_ipa_fn_summary (ctxt);
3691 }
3692 
3693 /* Reset all state within ipa-fnsummary.c so that we can rerun the compiler
3694    within the same process.  For use by toplev::finalize.  */
3695 
3696 void
ipa_fnsummary_c_finalize(void)3697 ipa_fnsummary_c_finalize (void)
3698 {
3699   ipa_free_fn_summary ();
3700 }
3701