LCOV - code coverage report
Current view: top level - gcc - ipa-inline.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 91.0 % 1529 1391
Test Date: 2026-02-28 14:20:25 Functions: 98.2 % 56 55
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Inlining decision heuristics.
       2              :    Copyright (C) 2003-2026 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              : /*  Inlining decision heuristics
      22              : 
      23              :     The implementation of inliner is organized as follows:
      24              : 
      25              :     inlining heuristics limits
      26              : 
      27              :       can_inline_edge_p allow to check that particular inlining is allowed
      28              :       by the limits specified by user (allowed function growth, growth and so
      29              :       on).
      30              : 
      31              :       Functions are inlined when it is obvious the result is profitable (such
      32              :       as functions called once or when inlining reduce code size).
      33              :       In addition to that we perform inlining of small functions and recursive
      34              :       inlining.
      35              : 
      36              :     inlining heuristics
      37              : 
      38              :        The inliner itself is split into two passes:
      39              : 
      40              :        pass_early_inlining
      41              : 
      42              :          Simple local inlining pass inlining callees into current function.
      43              :          This pass makes no use of whole unit analysis and thus it can do only
      44              :          very simple decisions based on local properties.
      45              : 
      46              :          The strength of the pass is that it is run in topological order
      47              :          (reverse postorder) on the callgraph. Functions are converted into SSA
      48              :          form just before this pass and optimized subsequently. As a result, the
      49              :          callees of the function seen by the early inliner was already optimized
      50              :          and results of early inlining adds a lot of optimization opportunities
      51              :          for the local optimization.
      52              : 
      53              :          The pass handle the obvious inlining decisions within the compilation
      54              :          unit - inlining auto inline functions, inlining for size and
      55              :          flattening.
      56              : 
      57              :          main strength of the pass is the ability to eliminate abstraction
      58              :          penalty in C++ code (via combination of inlining and early
      59              :          optimization) and thus improve quality of analysis done by real IPA
      60              :          optimizers.
      61              : 
      62              :          Because of lack of whole unit knowledge, the pass cannot really make
      63              :          good code size/performance tradeoffs.  It however does very simple
      64              :          speculative inlining allowing code size to grow by
      65              :          EARLY_INLINING_INSNS when callee is leaf function.  In this case the
      66              :          optimizations performed later are very likely to eliminate the cost.
      67              : 
      68              :        pass_ipa_inline
      69              : 
      70              :          This is the real inliner able to handle inlining with whole program
      71              :          knowledge. It performs following steps:
      72              : 
      73              :          1) inlining of small functions.  This is implemented by greedy
      74              :          algorithm ordering all inlinable cgraph edges by their badness and
      75              :          inlining them in this order as long as inline limits allows doing so.
      76              : 
      77              :          This heuristics is not very good on inlining recursive calls. Recursive
      78              :          calls can be inlined with results similar to loop unrolling. To do so,
      79              :          special purpose recursive inliner is executed on function when
      80              :          recursive edge is met as viable candidate.
      81              : 
      82              :          2) Unreachable functions are removed from callgraph.  Inlining leads
      83              :          to devirtualization and other modification of callgraph so functions
      84              :          may become unreachable during the process. Also functions declared as
      85              :          extern inline or virtual functions are removed, since after inlining
      86              :          we no longer need the offline bodies.
      87              : 
      88              :          3) Functions called once and not exported from the unit are inlined.
      89              :          This should almost always lead to reduction of code size by eliminating
      90              :          the need for offline copy of the function.  */
      91              : 
      92              : #include "config.h"
      93              : #include "system.h"
      94              : #include "coretypes.h"
      95              : #include "backend.h"
      96              : #include "target.h"
      97              : #include "rtl.h"
      98              : #include "tree.h"
      99              : #include "gimple.h"
     100              : #include "alloc-pool.h"
     101              : #include "tree-pass.h"
     102              : #include "gimple-ssa.h"
     103              : #include "cgraph.h"
     104              : #include "lto-streamer.h"
     105              : #include "trans-mem.h"
     106              : #include "calls.h"
     107              : #include "tree-inline.h"
     108              : #include "profile.h"
     109              : #include "symbol-summary.h"
     110              : #include "tree-vrp.h"
     111              : #include "sreal.h"
     112              : #include "ipa-cp.h"
     113              : #include "ipa-prop.h"
     114              : #include "ipa-fnsummary.h"
     115              : #include "ipa-inline.h"
     116              : #include "ipa-utils.h"
     117              : #include "auto-profile.h"
     118              : #include "builtins.h"
     119              : #include "fibonacci_heap.h"
     120              : #include "stringpool.h"
     121              : #include "attribs.h"
     122              : #include "asan.h"
     123              : #include "ipa-strub.h"
     124              : #include "ipa-modref-tree.h"
     125              : #include "ipa-modref.h"
     126              : 
     127              : /* Inliner uses greedy algorithm to inline calls in a priority order.
     128              :    Badness is used as the key in a Fibonacci heap which roughly corresponds
     129              :    to negation of benefit to cost ratios.
     130              :    In case multiple calls has same priority we want to stabilize the outcomes
     131              :    for which we use ids.  */
     132              : class inline_badness
     133              : {
     134              : public:
     135              :   sreal badness;
     136              :   int uid;
     137      1223653 :   inline_badness ()
     138       993594 :   : badness (sreal::min ()), uid (0)
     139              :   {
     140              :   }
     141      3599120 :   inline_badness (cgraph_edge *e, sreal b)
     142        18009 :   : badness (b), uid (e->get_uid ())
     143              :   {
     144              :   }
     145       891882 :   bool operator<= (const inline_badness &other)
     146              :   {
     147       891882 :     if (badness != other.badness)
     148       891882 :       return badness <= other.badness;
     149            0 :     return uid <= other.uid;
     150              :   }
     151       993594 :   bool operator== (const inline_badness &other)
     152              :   {
     153      1842297 :     return badness == other.badness && uid == other.uid;
     154              :   }
     155            0 :   bool operator!= (const inline_badness &other)
     156              :   {
     157       993594 :     return badness != other.badness || uid != other.uid;
     158              :   }
     159     27993138 :   bool operator< (const inline_badness &other)
     160              :   {
     161     27993138 :     if (badness != other.badness)
     162     23236473 :       return badness < other.badness;
     163      4756665 :     return uid < other.uid;
     164              :   }
     165     12867727 :   bool operator> (const inline_badness &other)
     166              :   {
     167     12867727 :     if (badness != other.badness)
     168     10521008 :       return badness > other.badness;
     169      2346719 :     return uid > other.uid;
     170              :   }
     171              : };
     172              : 
     173              : typedef fibonacci_heap <inline_badness, cgraph_edge> edge_heap_t;
     174              : typedef fibonacci_node <inline_badness, cgraph_edge> edge_heap_node_t;
     175              : 
     176              : /* Statistics we collect about inlining algorithm.  */
     177              : static int overall_size;
     178              : static bool has_nonzero_ipa_profile;
     179              : static profile_count spec_rem;
     180              : 
     181              : /* Return false when inlining edge E would lead to violating
     182              :    limits on function unit growth or stack usage growth.
     183              : 
     184              :    The relative function body growth limit is present generally
     185              :    to avoid problems with non-linear behavior of the compiler.
     186              :    To allow inlining huge functions into tiny wrapper, the limit
     187              :    is always based on the bigger of the two functions considered.
     188              : 
     189              :    For stack growth limits we always base the growth in stack usage
     190              :    of the callers.  We want to prevent applications from segfaulting
     191              :    on stack overflow when functions with huge stack frames gets
     192              :    inlined. */
     193              : 
     194              : static bool
     195      6431814 : caller_growth_limits (struct cgraph_edge *e)
     196              : {
     197      6431814 :   struct cgraph_node *to = e->caller;
     198      6431814 :   struct cgraph_node *what = e->callee->ultimate_alias_target ();
     199      6431814 :   int newsize;
     200      6431814 :   int limit = 0;
     201      6431814 :   HOST_WIDE_INT stack_size_limit = 0, inlined_stack;
     202      6431814 :   ipa_size_summary *outer_info = ipa_size_summaries->get (to);
     203              : 
     204              :   /* Look for function e->caller is inlined to.  While doing
     205              :      so work out the largest function body on the way.  As
     206              :      described above, we want to base our function growth
     207              :      limits based on that.  Not on the self size of the
     208              :      outer function, not on the self size of inline code
     209              :      we immediately inline to.  This is the most relaxed
     210              :      interpretation of the rule "do not grow large functions
     211              :      too much in order to prevent compiler from exploding".  */
     212      9139484 :   while (true)
     213              :     {
     214      7785649 :       ipa_size_summary *size_info = ipa_size_summaries->get (to);
     215      7785649 :       if (limit < size_info->self_size)
     216              :         limit = size_info->self_size;
     217      7785649 :       if (stack_size_limit < size_info->estimated_self_stack_size)
     218              :         stack_size_limit = size_info->estimated_self_stack_size;
     219      7785649 :       if (to->inlined_to)
     220      1353835 :         to = to->callers->caller;
     221              :       else
     222              :         break;
     223      1353835 :     }
     224              : 
     225      6431814 :   ipa_fn_summary *what_info = ipa_fn_summaries->get (what);
     226      6431814 :   ipa_size_summary *what_size_info = ipa_size_summaries->get (what);
     227              : 
     228      6431814 :   if (limit < what_size_info->self_size)
     229              :     limit = what_size_info->self_size;
     230              : 
     231      6431814 :   limit += limit * opt_for_fn (to->decl, param_large_function_growth) / 100;
     232              : 
     233              :   /* Check the size after inlining against the function limits.  But allow
     234              :      the function to shrink if it went over the limits by forced inlining.  */
     235      6431814 :   newsize = estimate_size_after_inlining (to, e);
     236      6431814 :   if (newsize >= ipa_size_summaries->get (what)->size
     237      6254156 :       && newsize > opt_for_fn (to->decl, param_large_function_insns)
     238      6684355 :       && newsize > limit)
     239              :     {
     240         6046 :       e->inline_failed = CIF_LARGE_FUNCTION_GROWTH_LIMIT;
     241         6046 :       return false;
     242              :     }
     243              : 
     244      6425768 :   if (!what_info->estimated_stack_size)
     245              :     return true;
     246              : 
     247              :   /* FIXME: Stack size limit often prevents inlining in Fortran programs
     248              :      due to large i/o datastructures used by the Fortran front-end.
     249              :      We ought to ignore this limit when we know that the edge is executed
     250              :      on every invocation of the caller (i.e. its call statement dominates
     251              :      exit block).  We do not track this information, yet.  */
     252      2287700 :   stack_size_limit += ((gcov_type)stack_size_limit
     253      1143850 :                        * opt_for_fn (to->decl, param_stack_frame_growth)
     254      1143850 :                        / 100);
     255              : 
     256      1143850 :   inlined_stack = (ipa_get_stack_frame_offset (to)
     257      1143850 :                    + outer_info->estimated_self_stack_size
     258      1143850 :                    + what_info->estimated_stack_size);
     259              :   /* Check new stack consumption with stack consumption at the place
     260              :      stack is used.  */
     261      1143850 :   if (inlined_stack > stack_size_limit
     262              :       /* If function already has large stack usage from sibling
     263              :          inline call, we can inline, too.
     264              :          This bit overoptimistically assume that we are good at stack
     265              :          packing.  */
     266       334973 :       && inlined_stack > ipa_fn_summaries->get (to)->estimated_stack_size
     267      1465661 :       && inlined_stack > opt_for_fn (to->decl, param_large_stack_frame))
     268              :     {
     269        60871 :       e->inline_failed = CIF_LARGE_STACK_FRAME_GROWTH_LIMIT;
     270        60871 :       return false;
     271              :     }
     272              :   return true;
     273              : }
     274              : 
     275              : /* Dump info about why inlining has failed.  */
     276              : 
     277              : static void
     278      4966542 : report_inline_failed_reason (struct cgraph_edge *e)
     279              : {
     280      4966542 :   if (dump_enabled_p ())
     281              :     {
     282         2398 :       dump_printf_loc (MSG_MISSED_OPTIMIZATION, e->call_stmt,
     283              :                        "  not inlinable: %C -> %C, %s\n",
     284              :                        e->caller, e->callee,
     285              :                        cgraph_inline_failed_string (e->inline_failed));
     286         2398 :       if ((e->inline_failed == CIF_TARGET_OPTION_MISMATCH
     287         2398 :            || e->inline_failed == CIF_OPTIMIZATION_MISMATCH)
     288            2 :           && e->caller->lto_file_data
     289         2398 :           && e->callee->ultimate_alias_target ()->lto_file_data)
     290              :         {
     291            0 :           dump_printf_loc (MSG_MISSED_OPTIMIZATION, e->call_stmt,
     292              :                            "  LTO objects: %s, %s\n",
     293            0 :                            e->caller->lto_file_data->file_name,
     294            0 :                            e->callee->ultimate_alias_target ()->lto_file_data->file_name);
     295              :         }
     296         2398 :       if (e->inline_failed == CIF_TARGET_OPTION_MISMATCH)
     297            2 :         if (dump_file)
     298            0 :           cl_target_option_print_diff
     299            0 :             (dump_file, 2, target_opts_for_fn (e->caller->decl),
     300            0 :              target_opts_for_fn (e->callee->ultimate_alias_target ()->decl));
     301         2398 :       if (e->inline_failed == CIF_OPTIMIZATION_MISMATCH)
     302            0 :         if (dump_file)
     303            0 :           cl_optimization_print_diff
     304            0 :             (dump_file, 2, opts_for_fn (e->caller->decl),
     305            0 :              opts_for_fn (e->callee->ultimate_alias_target ()->decl));
     306              :     }
     307      4966542 : }
     308              : 
     309              :  /* Decide whether sanitizer-related attributes allow inlining. */
     310              : 
     311              : static bool
     312      9225576 : sanitize_attrs_match_for_inline_p (const_tree caller, const_tree callee)
     313              : {
     314      9225576 :   if (!caller || !callee)
     315              :     return true;
     316              : 
     317              :   /* Follow clang and allow inlining for always_inline functions.  */
     318      9225576 :   if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (callee)))
     319              :     return true;
     320              : 
     321      8669757 :   const sanitize_code codes[] =
     322              :     {
     323              :       SANITIZE_ADDRESS,
     324              :       SANITIZE_THREAD,
     325              :       SANITIZE_UNDEFINED,
     326              :       SANITIZE_UNDEFINED_NONDEFAULT,
     327              :       SANITIZE_POINTER_COMPARE,
     328              :       SANITIZE_POINTER_SUBTRACT
     329              :     };
     330              : 
     331     60687259 :   for (unsigned i = 0; i < ARRAY_SIZE (codes); i++)
     332    104035400 :     if (sanitize_flags_p (codes[i], caller)
     333     52017700 :         != sanitize_flags_p (codes[i], callee))
     334              :       return false;
     335              : 
     336      8669559 :   if (sanitize_coverage_p (caller) != sanitize_coverage_p (callee))
     337              :     return false;
     338              : 
     339              :   return true;
     340              : }
     341              : 
     342              : /* Used for flags where it is safe to inline when caller's value is
     343              :    grater than callee's.  */
     344              : #define check_maybe_up(flag) \
     345              :       (opts_for_fn (caller->decl)->x_##flag               \
     346              :        != opts_for_fn (callee->decl)->x_##flag            \
     347              :        && (!always_inline                               \
     348              :            || opts_for_fn (caller->decl)->x_##flag        \
     349              :               < opts_for_fn (callee->decl)->x_##flag))
     350              : /* Used for flags where it is safe to inline when caller's value is
     351              :    smaller than callee's.  */
     352              : #define check_maybe_down(flag) \
     353              :       (opts_for_fn (caller->decl)->x_##flag               \
     354              :        != opts_for_fn (callee->decl)->x_##flag            \
     355              :        && (!always_inline                               \
     356              :            || opts_for_fn (caller->decl)->x_##flag        \
     357              :               > opts_for_fn (callee->decl)->x_##flag))
     358              : /* Used for flags where exact match is needed for correctness.  */
     359              : #define check_match(flag) \
     360              :       (opts_for_fn (caller->decl)->x_##flag               \
     361              :        != opts_for_fn (callee->decl)->x_##flag)
     362              : 
     363              : /* Decide if we can inline the edge and possibly update
     364              :    inline_failed reason.
     365              :    We check whether inlining is possible at all and whether
     366              :    caller growth limits allow doing so.
     367              : 
     368              :    if REPORT is true, output reason to the dump file. */
     369              : 
     370              : static bool
     371     13367874 : can_inline_edge_p (struct cgraph_edge *e, bool report,
     372              :                    bool early = false)
     373              : {
     374     13367874 :   gcc_checking_assert (e->inline_failed);
     375              : 
     376     13367874 :   if (cgraph_inline_failed_type (e->inline_failed) == CIF_FINAL_ERROR)
     377              :     {
     378      3651932 :       if (report)
     379      3619906 :         report_inline_failed_reason (e);
     380      3651932 :       return false;
     381              :     }
     382              : 
     383      9715942 :   bool inlinable = true;
     384      9715942 :   enum availability avail;
     385      8483394 :   cgraph_node *caller = (e->caller->inlined_to
     386      9715942 :                          ? e->caller->inlined_to : e->caller);
     387      9715942 :   cgraph_node *callee = e->callee->ultimate_alias_target (&avail, caller);
     388              : 
     389      9715942 :   if (!callee->definition)
     390              :     {
     391         1187 :       e->inline_failed = CIF_BODY_NOT_AVAILABLE;
     392         1187 :       inlinable = false;
     393              :     }
     394      9715942 :   if (!early && (!opt_for_fn (callee->decl, optimize)
     395      5584044 :                  || !opt_for_fn (caller->decl, optimize)))
     396              :     {
     397          305 :       e->inline_failed = CIF_FUNCTION_NOT_OPTIMIZED;
     398          305 :       inlinable = false;
     399              :     }
     400      9715637 :   else if (callee->calls_comdat_local)
     401              :     {
     402        20382 :       e->inline_failed = CIF_USES_COMDAT_LOCAL;
     403        20382 :       inlinable = false;
     404              :     }
     405      9695255 :   else if (avail <= AVAIL_INTERPOSABLE)
     406              :     {
     407       129746 :       e->inline_failed = CIF_OVERWRITABLE;
     408       129746 :       inlinable = false;
     409              :     }
     410              :   /* All edges with call_stmt_cannot_inline_p should have inline_failed
     411              :      initialized to one of FINAL_ERROR reasons.  */
     412      9565509 :   else if (e->call_stmt_cannot_inline_p)
     413            0 :     gcc_unreachable ();
     414              :   /* Don't inline if the functions have different EH personalities.  */
     415      9565509 :   else if (DECL_FUNCTION_PERSONALITY (caller->decl)
     416      2652716 :            && DECL_FUNCTION_PERSONALITY (callee->decl)
     417      9565509 :            && (DECL_FUNCTION_PERSONALITY (caller->decl)
     418       220289 :                != DECL_FUNCTION_PERSONALITY (callee->decl)))
     419              :     {
     420            0 :       e->inline_failed = CIF_EH_PERSONALITY;
     421            0 :       inlinable = false;
     422              :     }
     423              :   /* TM pure functions should not be inlined into non-TM_pure
     424              :      functions.  */
     425      9565509 :   else if (is_tm_pure (callee->decl) && !is_tm_pure (caller->decl))
     426              :     {
     427           30 :       e->inline_failed = CIF_UNSPECIFIED;
     428           30 :       inlinable = false;
     429              :     }
     430              :   /* Check compatibility of target optimization options.  */
     431      9565479 :   else if (!targetm.target_option.can_inline_p (caller->decl,
     432              :                                                 callee->decl))
     433              :     {
     434          468 :       e->inline_failed = CIF_TARGET_OPTION_MISMATCH;
     435          468 :       inlinable = false;
     436              :     }
     437      9565011 :   else if (ipa_fn_summaries->get (callee) == NULL
     438      9565009 :            || !ipa_fn_summaries->get (callee)->inlinable)
     439              :     {
     440       339435 :       e->inline_failed = CIF_FUNCTION_NOT_INLINABLE;
     441       339435 :       inlinable = false;
     442              :     }
     443              :   /* Don't inline a function with mismatched sanitization attributes. */
     444      9225576 :   else if (!sanitize_attrs_match_for_inline_p (caller->decl, callee->decl))
     445              :     {
     446          198 :       e->inline_failed = CIF_SANITIZE_ATTRIBUTE_MISMATCH;
     447          198 :       inlinable = false;
     448              :     }
     449              : 
     450      9715942 :   if (inlinable && !strub_inlinable_to_p (callee, caller))
     451              :     {
     452         1101 :       e->inline_failed = CIF_UNSPECIFIED;
     453         1101 :       inlinable = false;
     454              :     }
     455      9715942 :   if (inlinable && callee->must_remain_in_tu_body
     456            9 :       && caller->lto_file_data != callee->lto_file_data)
     457              :     {
     458            9 :       e->inline_failed = CIF_MUST_REMAIN_IN_TU;
     459            9 :       inlinable = false;
     460              :     }
     461      9715942 :   if (!inlinable && report)
     462       484413 :     report_inline_failed_reason (e);
     463              :   return inlinable;
     464              : }
     465              : 
     466              : /* Return inlining_insns_single limit for function N.  If HINT or HINT2 is true
     467              :    scale up the bound.  */
     468              : 
     469              : static int
     470      8314791 : inline_insns_single (cgraph_node *n, bool hint, bool hint2)
     471              : {
     472      8314791 :   if (hint && hint2)
     473              :     {
     474      2883591 :       int64_t spd = opt_for_fn (n->decl, param_inline_heuristics_hint_percent);
     475      2883591 :       spd = spd * spd;
     476      2883591 :       if (spd > 1000000)
     477              :         spd = 1000000;
     478      2883591 :       return opt_for_fn (n->decl, param_max_inline_insns_single) * spd / 100;
     479              :     }
     480      5431200 :   if (hint || hint2)
     481       495129 :     return opt_for_fn (n->decl, param_max_inline_insns_single)
     482       495129 :            * opt_for_fn (n->decl, param_inline_heuristics_hint_percent) / 100;
     483      4936071 :   return opt_for_fn (n->decl, param_max_inline_insns_single);
     484              : }
     485              : 
     486              : /* Return inlining_insns_auto limit for function N.  If HINT or HINT2 is true
     487              :    scale up the bound.   */
     488              : 
     489              : static int
     490      5429174 : inline_insns_auto (cgraph_node *n, bool hint, bool hint2)
     491              : {
     492      5429174 :   int max_inline_insns_auto = opt_for_fn (n->decl, param_max_inline_insns_auto);
     493      5429174 :   if (hint && hint2)
     494              :     {
     495      1988913 :       int64_t spd = opt_for_fn (n->decl, param_inline_heuristics_hint_percent);
     496      1988913 :       spd = spd * spd;
     497      1988913 :       if (spd > 1000000)
     498              :         spd = 1000000;
     499      1988913 :       return max_inline_insns_auto * spd / 100;
     500              :     }
     501      3440261 :   if (hint || hint2)
     502      1449314 :     return max_inline_insns_auto
     503      1449314 :            * opt_for_fn (n->decl, param_inline_heuristics_hint_percent) / 100;
     504              :   return max_inline_insns_auto;
     505              : }
     506              : 
     507              : enum can_inline_edge_by_limits_flags
     508              : {
     509              :   /* True if we are early inlining.  */
     510              :   CAN_INLINE_EARLY = 1,
     511              :   /* Ignore size limits.  */
     512              :   CAN_INLINE_DISREGARD_LIMITS = 2,
     513              :   /* Force size limits (ignore always_inline).  This is used for
     514              :      recrusive inlining where always_inline may lead to inline bombs
     515              :      and technically it is non-sential anyway.  */
     516              :   CAN_INLINE_FORCE_LIMITS = 4,
     517              :   /* Report decision to dump file.  */
     518              :   CAN_INLINE_REPORT = 8,
     519              : };
     520              : 
     521              : /* Decide if we can inline the edge and possibly update
     522              :    inline_failed reason.
     523              :    We check whether inlining is possible at all and whether
     524              :    caller growth limits allow doing so.  */
     525              : 
     526              : static bool
     527      7000376 : can_inline_edge_by_limits_p (struct cgraph_edge *e, int flags)
     528              : {
     529      7000376 :   gcc_checking_assert (e->inline_failed);
     530              : 
     531      7000376 :   if (cgraph_inline_failed_type (e->inline_failed) == CIF_FINAL_ERROR)
     532              :     {
     533          210 :       if (flags & CAN_INLINE_REPORT)
     534          210 :         report_inline_failed_reason (e);
     535          210 :       return false;
     536              :     }
     537              : 
     538      7000166 :   bool inlinable = true;
     539      7000166 :   enum availability avail;
     540      6290633 :   cgraph_node *caller = (e->caller->inlined_to
     541      7000166 :                          ? e->caller->inlined_to : e->caller);
     542      7000166 :   cgraph_node *callee = e->callee->ultimate_alias_target (&avail, caller);
     543      7000166 :   tree caller_tree = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (caller->decl);
     544      7000166 :   tree callee_tree
     545      7000166 :     = callee ? DECL_FUNCTION_SPECIFIC_OPTIMIZATION (callee->decl) : NULL;
     546              :   /* Check if caller growth allows the inlining.  */
     547      7000166 :   if (!(flags & CAN_INLINE_DISREGARD_LIMITS)
     548      6989886 :       && ((flags & CAN_INLINE_FORCE_LIMITS)
     549      6955406 :           || (!DECL_DISREGARD_INLINE_LIMITS (callee->decl)
     550      6397482 :               && !lookup_attribute ("flatten",
     551      6397482 :                          DECL_ATTRIBUTES (caller->decl))))
     552     13431980 :       && !caller_growth_limits (e))
     553              :     inlinable = false;
     554      6933249 :   else if (callee->externally_visible
     555      5143527 :            && !DECL_DISREGARD_INLINE_LIMITS (callee->decl)
     556     11634975 :            && flag_live_patching == LIVE_PATCHING_INLINE_ONLY_STATIC)
     557              :     {
     558            2 :       e->inline_failed = CIF_EXTERN_LIVE_ONLY_STATIC;
     559            2 :       inlinable = false;
     560              :     }
     561              :   /* Don't inline a function with a higher optimization level than the
     562              :      caller.  FIXME: this is really just tip of iceberg of handling
     563              :      optimization attribute.  */
     564      6933247 :   else if (caller_tree != callee_tree)
     565              :     {
     566         9651 :       bool always_inline =
     567         9651 :              (DECL_DISREGARD_INLINE_LIMITS (callee->decl)
     568        12081 :               && lookup_attribute ("always_inline",
     569         2430 :                                    DECL_ATTRIBUTES (callee->decl)));
     570         9651 :       ipa_fn_summary *caller_info = ipa_fn_summaries->get (caller);
     571         9651 :       ipa_fn_summary *callee_info = ipa_fn_summaries->get (callee);
     572              : 
     573              :      /* Until GCC 4.9 we did not check the semantics-altering flags
     574              :         below and inlined across optimization boundaries.
     575              :         Enabling checks below breaks several packages by refusing
     576              :         to inline library always_inline functions. See PR65873.
     577              :         Disable the check for early inlining for now until better solution
     578              :         is found.  */
     579         9651 :      if (always_inline && (flags & CAN_INLINE_EARLY))
     580              :         ;
     581              :       /* There are some options that change IL semantics which means
     582              :          we cannot inline in these cases for correctness reason.
     583              :          Not even for always_inline declared functions.  */
     584         7221 :      else if (check_match (flag_wrapv)
     585         7221 :               || check_match (flag_trapv)
     586         7221 :               || check_match (flag_pcc_struct_return)
     587         7221 :               || check_maybe_down (optimize_debug)
     588              :               /* When caller or callee does FP math, be sure FP codegen flags
     589              :                  compatible.  */
     590         7215 :               || ((caller_info->fp_expressions && callee_info->fp_expressions)
     591         1273 :                   && (check_maybe_up (flag_rounding_math)
     592         1273 :                       || check_maybe_up (flag_trapping_math)
     593         1271 :                       || check_maybe_down (flag_unsafe_math_optimizations)
     594         1271 :                       || check_maybe_down (flag_finite_math_only)
     595         1270 :                       || check_maybe_up (flag_signaling_nans)
     596         1270 :                       || check_maybe_up (flag_complex_method)
     597         1269 :                       || check_maybe_up (flag_signed_zeros)
     598         1269 :                       || check_maybe_down (flag_associative_math)
     599         1253 :                       || check_maybe_down (flag_reciprocal_math)
     600         1253 :                       || check_maybe_down (flag_fp_int_builtin_inexact)
     601              :                       /* Strictly speaking only when the callee contains function
     602              :                          calls that may end up setting errno.  */
     603         1253 :                       || check_maybe_up (flag_errno_math)))
     604              :               /* We do not want to make code compiled with exceptions to be
     605              :                  brought into a non-EH function unless we know that the callee
     606              :                  does not throw.
     607              :                  This is tracked by DECL_FUNCTION_PERSONALITY.  */
     608         7195 :               || (check_maybe_up (flag_non_call_exceptions)
     609            0 :                   && DECL_FUNCTION_PERSONALITY (callee->decl))
     610         7195 :               || (check_maybe_up (flag_exceptions)
     611           16 :                   && DECL_FUNCTION_PERSONALITY (callee->decl))
     612              :               /* When devirtualization is disabled for callee, it is not safe
     613              :                  to inline it as we possibly mangled the type info.
     614              :                  Allow early inlining of always inlines.  */
     615        14416 :               || (!(flags & CAN_INLINE_EARLY) && check_maybe_down (flag_devirtualize)))
     616              :         {
     617           34 :           e->inline_failed = CIF_OPTIMIZATION_MISMATCH;
     618           34 :           inlinable = false;
     619              :         }
     620              :       /* gcc.dg/pr43564.c.  Apply user-forced inline even at -O0.  */
     621         7187 :       else if (always_inline)
     622              :         ;
     623              :       /* When user added an attribute to the callee honor it.  */
     624         7187 :       else if (lookup_attribute ("optimize", DECL_ATTRIBUTES (callee->decl))
     625         7187 :                && opts_for_fn (caller->decl) != opts_for_fn (callee->decl))
     626              :         {
     627         2456 :           e->inline_failed = CIF_OPTIMIZATION_MISMATCH;
     628         2456 :           inlinable = false;
     629              :         }
     630              :       /* If explicit optimize attribute are not used, the mismatch is caused
     631              :          by different command line options used to build different units.
     632              :          Do not care about COMDAT functions - those are intended to be
     633              :          optimized with the optimization flags of module they are used in.
     634              :          Also do not care about mixing up size/speed optimization when
     635              :          DECL_DISREGARD_INLINE_LIMITS is set.  */
     636         4731 :       else if ((callee->merged_comdat
     637            0 :                 && !lookup_attribute ("optimize",
     638            0 :                                       DECL_ATTRIBUTES (caller->decl)))
     639         4731 :                || DECL_DISREGARD_INLINE_LIMITS (callee->decl))
     640              :         ;
     641              :       /* If mismatch is caused by merging two LTO units with different
     642              :          optimization flags we want to be bit nicer.  However never inline
     643              :          if one of functions is not optimized at all.  */
     644         4731 :       else if (!opt_for_fn (callee->decl, optimize)
     645         4731 :                || !opt_for_fn (caller->decl, optimize))
     646              :         {
     647            0 :           e->inline_failed = CIF_OPTIMIZATION_MISMATCH;
     648            0 :           inlinable = false;
     649              :         }
     650              :       /* If callee is optimized for size and caller is not, allow inlining if
     651              :          code shrinks or we are in param_max_inline_insns_single limit and
     652              :          callee is inline (and thus likely an unified comdat).
     653              :          This will allow caller to run faster.  */
     654         4731 :       else if (opt_for_fn (callee->decl, optimize_size)
     655         4731 :                > opt_for_fn (caller->decl, optimize_size))
     656              :         {
     657          118 :           int growth = estimate_edge_growth (e);
     658          118 :           if (growth > opt_for_fn (caller->decl, param_max_inline_insns_size)
     659          118 :               && (!DECL_DECLARED_INLINE_P (callee->decl)
     660           65 :                   && growth >= MAX (inline_insns_single (caller, false, false),
     661              :                                     inline_insns_auto (caller, false, false))))
     662              :             {
     663            0 :               e->inline_failed = CIF_OPTIMIZATION_MISMATCH;
     664            0 :               inlinable = false;
     665              :             }
     666              :         }
     667              :       /* If callee is more aggressively optimized for performance than caller,
     668              :          we generally want to inline only cheap (runtime wise) functions.  */
     669         4613 :       else if (opt_for_fn (callee->decl, optimize_size)
     670              :                < opt_for_fn (caller->decl, optimize_size)
     671         4613 :                || (opt_for_fn (callee->decl, optimize)
     672              :                    > opt_for_fn (caller->decl, optimize)))
     673              :         {
     674        12675 :           if (estimate_edge_time (e)
     675         4225 :               >= 20 + ipa_call_summaries->get (e)->call_stmt_time)
     676              :             {
     677         1514 :               e->inline_failed = CIF_OPTIMIZATION_MISMATCH;
     678         1514 :               inlinable = false;
     679              :             }
     680              :         }
     681              : 
     682              :     }
     683              : 
     684        70923 :   if (!inlinable && (flags & CAN_INLINE_REPORT))
     685        65111 :     report_inline_failed_reason (e);
     686              :   return inlinable;
     687              : }
     688              : 
     689              : 
     690              : /* Return true if the edge E is inlinable during early inlining.  */
     691              : 
     692              : static bool
     693      4131957 : can_early_inline_edge_p (struct cgraph_edge *e)
     694              : {
     695      4130394 :   cgraph_node *caller = (e->caller->inlined_to
     696      4131957 :                          ? e->caller->inlined_to : e->caller);
     697      4131957 :   struct cgraph_node *callee = e->callee->ultimate_alias_target ();
     698              :   /* Early inliner might get called at WPA stage when IPA pass adds new
     699              :      function.  In this case we cannot really do any of early inlining
     700              :      because function bodies are missing.  */
     701      4131957 :   if (cgraph_inline_failed_type (e->inline_failed) == CIF_FINAL_ERROR)
     702              :     return false;
     703      4131652 :   if (!gimple_has_body_p (callee->decl))
     704              :     {
     705            0 :       e->inline_failed = CIF_BODY_NOT_AVAILABLE;
     706            0 :       return false;
     707              :     }
     708      8263304 :   gcc_assert (gimple_in_ssa_p (DECL_STRUCT_FUNCTION (e->caller->decl))
     709              :               && gimple_in_ssa_p (DECL_STRUCT_FUNCTION (callee->decl)));
     710      4131652 :   if (coverage_instrumentation_p ()
     711      4133266 :       && ((lookup_attribute ("no_profile_instrument_function",
     712         1614 :                             DECL_ATTRIBUTES (caller->decl)) == NULL_TREE)
     713         1614 :           != (lookup_attribute ("no_profile_instrument_function",
     714         3228 :                                 DECL_ATTRIBUTES (callee->decl)) == NULL_TREE)))
     715              :     return false;
     716              : 
     717      4131650 :   if (!can_inline_edge_p (e, true, true)
     718      4131650 :       || !can_inline_edge_by_limits_p (e, CAN_INLINE_EARLY | CAN_INLINE_REPORT))
     719        87055 :     return false;
     720              :   /* When inlining regular functions into always-inline functions
     721              :      during early inlining watch for possible inline cycles.  */
     722      4044595 :   if (DECL_DISREGARD_INLINE_LIMITS (caller->decl)
     723       219645 :       && lookup_attribute ("always_inline", DECL_ATTRIBUTES (caller->decl))
     724      4263661 :       && (!DECL_DISREGARD_INLINE_LIMITS (callee->decl)
     725       133669 :           || !lookup_attribute ("always_inline", DECL_ATTRIBUTES (callee->decl))))
     726              :     {
     727              :       /* If there are indirect calls, inlining may produce direct call.
     728              :          TODO: We may lift this restriction if we avoid errors on formely
     729              :          indirect calls to always_inline functions.  Taking address
     730              :          of always_inline function is generally bad idea and should
     731              :          have been declared as undefined, but sadly we allow this.  */
     732        85398 :       if (caller->indirect_calls || e->callee->indirect_calls)
     733              :         return false;
     734        84216 :       ipa_fn_summary *callee_info = ipa_fn_summaries->get (callee);
     735        84216 :       if (callee_info->safe_to_inline_to_always_inline)
     736        19882 :         return callee_info->safe_to_inline_to_always_inline - 1;
     737       141658 :       for (cgraph_edge *e2 = callee->callees; e2; e2 = e2->next_callee)
     738              :         {
     739        77357 :           struct cgraph_node *callee2 = e2->callee->ultimate_alias_target ();
     740              :           /* As early inliner runs in RPO order, we will see uninlined
     741              :              always_inline calls only in the case of cyclic graphs.  */
     742        77357 :           if (DECL_DISREGARD_INLINE_LIMITS (callee2->decl)
     743        77357 :               || lookup_attribute ("always_inline", DECL_ATTRIBUTES (callee2->decl)))
     744              :             {
     745            0 :               callee_info->safe_to_inline_to_always_inline = 1;
     746            0 :               return false;
     747              :             }
     748              :           /* With LTO watch for case where function is later replaced
     749              :              by always_inline definition.
     750              :              TODO: We may either stop treating noninlined cross-module always
     751              :              inlines as errors, or we can extend decl merging to produce
     752              :              syntacic alias and honor always inline only in units it has
     753              :              been declared as such.  */
     754        77357 :           if (flag_lto && callee2->externally_visible)
     755              :             {
     756           33 :               callee_info->safe_to_inline_to_always_inline = 1;
     757           33 :               return false;
     758              :             }
     759              :         }
     760        64301 :       callee_info->safe_to_inline_to_always_inline = 2;
     761              :     }
     762              :   return true;
     763              : }
     764              : 
     765              : 
     766              : /* Return number of calls in N.  Ignore cheap builtins.  */
     767              : 
     768              : static int
     769       844810 : num_calls (struct cgraph_node *n)
     770              : {
     771       844810 :   struct cgraph_edge *e;
     772       844810 :   int num = 0;
     773              : 
     774      1706774 :   for (e = n->callees; e; e = e->next_callee)
     775       861964 :     if (!is_inexpensive_builtin (e->callee->decl))
     776       770405 :       num++;
     777       844810 :   return num;
     778              : }
     779              : 
     780              : 
     781              : /* Return true if we are interested in inlining small function.  */
     782              : 
     783              : static bool
     784      3482634 : want_early_inline_function_p (struct cgraph_edge *e)
     785              : {
     786      3482634 :   bool want_inline = true;
     787      3482634 :   struct cgraph_node *callee = e->callee->ultimate_alias_target ();
     788              : 
     789      3482634 :   if (DECL_DISREGARD_INLINE_LIMITS (callee->decl))
     790              :     ;
     791      3482627 :   else if (!DECL_DECLARED_INLINE_P (callee->decl)
     792      3482627 :            && !opt_for_fn (e->caller->decl, flag_inline_small_functions))
     793              :     {
     794           62 :       e->inline_failed = CIF_FUNCTION_NOT_INLINE_CANDIDATE;
     795           62 :       report_inline_failed_reason (e);
     796           62 :       want_inline = false;
     797              :     }
     798              :   else
     799              :     {
     800              :       /* First take care of very large functions.  */
     801      3482565 :       int min_growth = estimate_min_edge_growth (e), growth = 0;
     802      3482565 :       int n;
     803      3482565 :       int early_inlining_insns = param_early_inlining_insns;
     804              : 
     805      3482565 :       if (min_growth > early_inlining_insns)
     806              :         {
     807       407167 :           if (dump_enabled_p ())
     808           40 :             dump_printf_loc (MSG_MISSED_OPTIMIZATION, e->call_stmt,
     809              :                              "  will not early inline: %C->%C, "
     810              :                              "call is cold and code would grow "
     811              :                              "at least by %i\n",
     812              :                              e->caller, callee,
     813              :                              min_growth);
     814              :           want_inline = false;
     815              :         }
     816              :       else
     817      3075398 :         growth = estimate_edge_growth (e);
     818              : 
     819              : 
     820      3075398 :       if (!want_inline || growth <= param_max_inline_insns_size)
     821              :         ;
     822      1232243 :       else if (!e->maybe_hot_p ())
     823              :         {
     824        21183 :           if (dump_enabled_p ())
     825            0 :             dump_printf_loc (MSG_MISSED_OPTIMIZATION, e->call_stmt,
     826              :                              "  will not early inline: %C->%C, "
     827              :                              "call is cold and code would grow by %i\n",
     828              :                              e->caller, callee,
     829              :                              growth);
     830              :           want_inline = false;
     831              :         }
     832      1211060 :       else if (growth > early_inlining_insns)
     833              :         {
     834       366250 :           if (dump_enabled_p ())
     835            0 :             dump_printf_loc (MSG_MISSED_OPTIMIZATION, e->call_stmt,
     836              :                              "  will not early inline: %C->%C, "
     837              :                              "growth %i exceeds --param early-inlining-insns\n",
     838              :                              e->caller, callee, growth);
     839              :           want_inline = false;
     840              :         }
     841       844810 :       else if ((n = num_calls (callee)) != 0
     842       844810 :                && growth * (n + 1) > early_inlining_insns)
     843              :         {
     844       248116 :           if (dump_enabled_p ())
     845           11 :             dump_printf_loc (MSG_MISSED_OPTIMIZATION, e->call_stmt,
     846              :                              "  will not early inline: %C->%C, "
     847              :                              "growth %i exceeds --param early-inlining-insns "
     848              :                              "divided by number of calls\n",
     849              :                              e->caller, callee, growth);
     850              :           want_inline = false;
     851              :         }
     852              :     }
     853      3482634 :   return want_inline;
     854              : }
     855              : 
     856              : /* Compute time of the edge->caller + edge->callee execution when inlining
     857              :    does not happen.  */
     858              : 
     859              : inline sreal
     860       452373 : compute_uninlined_call_time (struct cgraph_edge *edge,
     861              :                              sreal uninlined_call_time,
     862              :                              sreal freq)
     863              : {
     864       313859 :   cgraph_node *caller = (edge->caller->inlined_to
     865       452373 :                          ? edge->caller->inlined_to
     866              :                          : edge->caller);
     867              : 
     868       452373 :   if (freq > 0)
     869       438591 :     uninlined_call_time *= freq;
     870              :   else
     871        13782 :     uninlined_call_time = uninlined_call_time >> 11;
     872              : 
     873       452373 :   sreal caller_time = ipa_fn_summaries->get (caller)->time;
     874       452373 :   return uninlined_call_time + caller_time;
     875              : }
     876              : 
     877              : /* Same as compute_uinlined_call_time but compute time when inlining
     878              :    does happen.  */
     879              : 
     880              : inline sreal
     881       452373 : compute_inlined_call_time (struct cgraph_edge *edge,
     882              :                            sreal time,
     883              :                            sreal freq)
     884              : {
     885       313859 :   cgraph_node *caller = (edge->caller->inlined_to
     886       452373 :                          ? edge->caller->inlined_to
     887              :                          : edge->caller);
     888       452373 :   sreal caller_time = ipa_fn_summaries->get (caller)->time;
     889              : 
     890       452373 :   if (freq > 0)
     891       438591 :     time *= freq;
     892              :   else
     893        13782 :     time = time >> 11;
     894              : 
     895              :   /* This calculation should match one in ipa-inline-analysis.cc
     896              :      (estimate_edge_size_and_time).  */
     897       452373 :   time -= (sreal)ipa_call_summaries->get (edge)->call_stmt_time * freq;
     898       452373 :   time += caller_time;
     899       452373 :   if (time <= 0)
     900            0 :     time = ((sreal) 1) >> 8;
     901       452373 :   gcc_checking_assert (time >= 0);
     902       452373 :   return time;
     903              : }
     904              : 
     905              : /* Determine time saved by inlining EDGE of frequency FREQ
     906              :    where callee's runtime w/o inlining is UNINLINED_TYPE
     907              :    and with inlined is INLINED_TYPE.  */
     908              : 
     909              : inline sreal
     910      9697221 : inlining_speedup (struct cgraph_edge *edge,
     911              :                   sreal freq,
     912              :                   sreal uninlined_time,
     913              :                   sreal inlined_time)
     914              : {
     915      9697221 :   sreal speedup = uninlined_time - inlined_time;
     916              :   /* Handling of call_time should match one in ipa-inline-fnsummary.c
     917              :      (estimate_edge_size_and_time).  */
     918      9697221 :   sreal call_time = ipa_call_summaries->get (edge)->call_stmt_time;
     919              : 
     920      9697221 :   if (freq > 0)
     921              :     {
     922      9661532 :       speedup = (speedup + call_time);
     923     11960753 :       if (freq != 1)
     924      7362311 :        speedup = speedup * freq;
     925              :     }
     926        35689 :   else if (freq == 0)
     927        35689 :     speedup = speedup >> 11;
     928      9697221 :   gcc_checking_assert (speedup >= 0);
     929      9697221 :   return speedup;
     930              : }
     931              : 
     932              : /* Return expected speedup of the callee function alone
     933              :    (i.e. not estimate of call overhead and also no scalling
     934              :     by call frequency.  */
     935              : 
     936              : static sreal
     937      3089458 : callee_speedup (struct cgraph_edge *e)
     938              : {
     939      3089458 :   sreal unspec_time;
     940      3089458 :   sreal spec_time = estimate_edge_time (e, &unspec_time);
     941      3089458 :   return unspec_time - spec_time;
     942              : }
     943              : 
     944              : /* Return true if the speedup for inlining E is bigger than
     945              :    param_inline_min_speedup.  */
     946              : 
     947              : static bool
     948       452373 : big_speedup_p (struct cgraph_edge *e)
     949              : {
     950       452373 :   sreal unspec_time;
     951       452373 :   sreal spec_time = estimate_edge_time (e, &unspec_time);
     952       452373 :   sreal freq = e->sreal_frequency ();
     953       452373 :   sreal time = compute_uninlined_call_time (e, unspec_time, freq);
     954       452373 :   sreal inlined_time = compute_inlined_call_time (e, spec_time, freq);
     955       313859 :   cgraph_node *caller = (e->caller->inlined_to
     956       452373 :                          ? e->caller->inlined_to
     957              :                          : e->caller);
     958       452373 :   int limit = opt_for_fn (caller->decl, param_inline_min_speedup);
     959              : 
     960       452373 :   if ((time - inlined_time) * 100 > time * limit)
     961              :     return true;
     962              :   return false;
     963              : }
     964              : 
     965              : /* Return true if we are interested in inlining small function.
     966              :    When REPORT is true, report reason to dump file.  */
     967              : 
     968              : static bool
     969      4929764 : want_inline_small_function_p (struct cgraph_edge *e, bool report)
     970              : {
     971      4929764 :   bool want_inline = true;
     972      4929764 :   struct cgraph_node *callee = e->callee->ultimate_alias_target ();
     973      3772810 :   cgraph_node *to  = (e->caller->inlined_to
     974      4929764 :                       ? e->caller->inlined_to : e->caller);
     975              : 
     976              :   /* Allow this function to be called before can_inline_edge_p,
     977              :      since it's usually cheaper.  */
     978      4929764 :   if (cgraph_inline_failed_type (e->inline_failed) == CIF_FINAL_ERROR)
     979              :     want_inline = false;
     980      4929764 :   else if (DECL_DISREGARD_INLINE_LIMITS (callee->decl))
     981              :     return true;
     982      4923945 :   else if (!DECL_DECLARED_INLINE_P (callee->decl)
     983      4923945 :            && !opt_for_fn (e->caller->decl, flag_inline_small_functions))
     984              :     {
     985        51465 :       e->inline_failed = CIF_FUNCTION_NOT_INLINE_CANDIDATE;
     986        51465 :       want_inline = false;
     987              :     }
     988              : 
     989              :   /* Early return before lookup of summaries.  */
     990        51465 :   if (!want_inline)
     991              :     {
     992        51465 :       if (report)
     993        47441 :         report_inline_failed_reason (e);
     994        51465 :       return false;
     995              :     }
     996              : 
     997      4872480 :   ipa_fn_summary *callee_info = ipa_fn_summaries->get (callee);
     998      4872480 :   ipa_call_summary *call_info = ipa_call_summaries->get (e);
     999              : 
    1000              :   /* Do fast and conservative check if the function can be good
    1001              :      inline candidate.  */
    1002      4872480 :   if ((!DECL_DECLARED_INLINE_P (callee->decl)
    1003      1989143 :       && (!e->count.ipa ().initialized_p ()
    1004        39720 :           || !e->maybe_hot_p (callee_info->time)))
    1005      6861393 :       && callee_info->min_size - call_info->call_stmt_size
    1006      1988913 :          > inline_insns_auto (e->caller, true, true))
    1007              :     {
    1008         2293 :       e->inline_failed = CIF_MAX_INLINE_INSNS_AUTO_LIMIT;
    1009         2293 :       want_inline = false;
    1010              :     }
    1011      4870187 :   else if ((DECL_DECLARED_INLINE_P (callee->decl)
    1012      1986850 :             || e->count.ipa ().nonzero_p ())
    1013      7753778 :            && callee_info->min_size - call_info->call_stmt_size
    1014      2883591 :               > inline_insns_single (e->caller, true, true))
    1015              :     {
    1016            0 :       e->inline_failed = (DECL_DECLARED_INLINE_P (callee->decl)
    1017            0 :                           ? CIF_MAX_INLINE_INSNS_SINGLE_LIMIT
    1018              :                           : CIF_MAX_INLINE_INSNS_AUTO_LIMIT);
    1019            0 :       want_inline = false;
    1020              :     }
    1021              :   else
    1022              :     {
    1023      4870187 :       int growth = estimate_edge_growth (e);
    1024      4870187 :       ipa_hints hints = estimate_edge_hints (e);
    1025              :       /* We have two independent groups of hints.  If one matches in each
    1026              :          of groups the limits are inreased.  If both groups matches, limit
    1027              :          is increased even more.  */
    1028      4870187 :       bool apply_hints = (hints & (INLINE_HINT_indirect_call
    1029              :                                    | INLINE_HINT_known_hot
    1030              :                                    | INLINE_HINT_loop_iterations
    1031              :                                    | INLINE_HINT_loop_stride));
    1032      4870187 :       bool apply_hints2 = (hints & INLINE_HINT_builtin_constant_p);
    1033              : 
    1034      4870187 :       if (growth <= opt_for_fn (to->decl,
    1035              :                                 param_max_inline_insns_size))
    1036              :         ;
    1037              :       /* Apply param_max_inline_insns_single limit.  Do not do so when
    1038              :          hints suggests that inlining given function is very profitable.
    1039              :          Avoid computation of big_speedup_p when not necessary to change
    1040              :          outcome of decision.  */
    1041      4744462 :       else if (DECL_DECLARED_INLINE_P (callee->decl)
    1042      2832758 :                && growth >= inline_insns_single (e->caller, apply_hints,
    1043              :                                                  apply_hints2)
    1044      5221683 :                && (apply_hints || apply_hints2
    1045       474665 :                    || growth >= inline_insns_single (e->caller, true,
    1046              :                                                      apply_hints2)
    1047       241554 :                    || !big_speedup_p (e)))
    1048              :         {
    1049       475956 :           e->inline_failed = CIF_MAX_INLINE_INSNS_SINGLE_LIMIT;
    1050       475956 :           want_inline = false;
    1051              :         }
    1052      4268506 :       else if (!DECL_DECLARED_INLINE_P (callee->decl)
    1053      1911704 :                && !opt_for_fn (e->caller->decl, flag_inline_functions)
    1054      4273866 :                && growth >= opt_for_fn (to->decl,
    1055              :                                         param_max_inline_insns_small))
    1056              :         {
    1057              :           /* growth_positive_p is expensive, always test it last.  */
    1058         5360 :           if (growth >= inline_insns_single (e->caller, false, false)
    1059         5360 :               || growth_positive_p (callee, e, growth))
    1060              :             {
    1061         4973 :               e->inline_failed = CIF_NOT_DECLARED_INLINED;
    1062         4973 :               want_inline = false;
    1063              :             }
    1064              :         }
    1065              :       /* Apply param_max_inline_insns_auto limit for functions not declared
    1066              :          inline.  Bypass the limit when speedup seems big.  */
    1067      4263146 :       else if (!DECL_DECLARED_INLINE_P (callee->decl)
    1068      1906344 :                && growth >= inline_insns_auto (e->caller, apply_hints,
    1069              :                                                apply_hints2)
    1070      5447809 :                && (apply_hints || apply_hints2
    1071      1170293 :                    || growth >= inline_insns_auto (e->caller, true,
    1072              :                                                    apply_hints2)
    1073       210634 :                    || !big_speedup_p (e)))
    1074              :         {
    1075              :           /* growth_positive_p is expensive, always test it last.  */
    1076      1173688 :           if (growth >= inline_insns_single (e->caller, false, false)
    1077      1173688 :               || growth_positive_p (callee, e, growth))
    1078              :             {
    1079      1093632 :               e->inline_failed = CIF_MAX_INLINE_INSNS_AUTO_LIMIT;
    1080      1093632 :               want_inline = false;
    1081              :             }
    1082              :         }
    1083              :       /* If call is cold, do not inline when function body would grow. */
    1084      3089458 :       else if (!e->maybe_hot_p (callee_speedup (e))
    1085      3089458 :                && (growth >= inline_insns_single (e->caller, false, false)
    1086       688918 :                    || growth_positive_p (callee, e, growth)))
    1087              :         {
    1088       617582 :           e->inline_failed = CIF_UNLIKELY_CALL;
    1089       617582 :           want_inline = false;
    1090              :         }
    1091              :     }
    1092      4872480 :   if (!want_inline && report)
    1093       574393 :     report_inline_failed_reason (e);
    1094              :   return want_inline;
    1095              : }
    1096              : 
    1097              : /* EDGE is self recursive edge.
    1098              :    We handle two cases - when function A is inlining into itself
    1099              :    or when function A is being inlined into another inliner copy of function
    1100              :    A within function B.
    1101              : 
    1102              :    In first case OUTER_NODE points to the toplevel copy of A, while
    1103              :    in the second case OUTER_NODE points to the outermost copy of A in B.
    1104              : 
    1105              :    In both cases we want to be extra selective since
    1106              :    inlining the call will just introduce new recursive calls to appear.  */
    1107              : 
    1108              : static bool
    1109        19673 : want_inline_self_recursive_call_p (struct cgraph_edge *edge,
    1110              :                                    struct cgraph_node *outer_node,
    1111              :                                    bool peeling,
    1112              :                                    int depth)
    1113              : {
    1114        19673 :   char const *reason = NULL;
    1115        19673 :   bool want_inline = true;
    1116        19673 :   sreal caller_freq = 1;
    1117        19673 :   int max_depth = opt_for_fn (outer_node->decl,
    1118              :                               param_max_inline_recursive_depth_auto);
    1119              : 
    1120        19673 :   if (DECL_DECLARED_INLINE_P (edge->caller->decl))
    1121         2885 :     max_depth = opt_for_fn (outer_node->decl,
    1122              :                             param_max_inline_recursive_depth);
    1123              : 
    1124        19673 :   if (!edge->maybe_hot_p ())
    1125              :     {
    1126              :       reason = "recursive call is cold";
    1127              :       want_inline = false;
    1128              :     }
    1129        19198 :   else if (depth > max_depth)
    1130              :     {
    1131              :       reason = "--param max-inline-recursive-depth exceeded.";
    1132              :       want_inline = false;
    1133              :     }
    1134        17019 :   else if (outer_node->inlined_to
    1135        21494 :            && (caller_freq = outer_node->callers->sreal_frequency ()) == 0)
    1136              :     {
    1137            0 :       reason = "caller frequency is 0";
    1138            0 :       want_inline = false;
    1139              :     }
    1140              : 
    1141            0 :   if (!want_inline)
    1142              :     ;
    1143              :   /* Inlining of self recursive function into copy of itself within other
    1144              :      function is transformation similar to loop peeling.
    1145              : 
    1146              :      Peeling is profitable if we can inline enough copies to make probability
    1147              :      of actual call to the self recursive function very small.  Be sure that
    1148              :      the probability of recursion is small.
    1149              : 
    1150              :      We ensure that the frequency of recursing is at most 1 - (1/max_depth).
    1151              :      This way the expected number of recursion is at most max_depth.  */
    1152        17019 :   else if (peeling)
    1153              :     {
    1154         4475 :       sreal max_prob = (sreal)1 - ((sreal)1 / (sreal)max_depth);
    1155         4475 :       int i;
    1156         9928 :       for (i = 1; i < depth; i++)
    1157         5453 :         max_prob = max_prob * max_prob;
    1158         4475 :       if (edge->sreal_frequency () >= max_prob * caller_freq)
    1159              :         {
    1160         1559 :           reason = "frequency of recursive call is too large";
    1161         1559 :           want_inline = false;
    1162              :         }
    1163              :     }
    1164              :   /* Recursive inlining, i.e. equivalent of unrolling, is profitable if
    1165              :      recursion depth is large.  We reduce function call overhead and increase
    1166              :      chances that things fit in hardware return predictor.
    1167              : 
    1168              :      Recursive inlining might however increase cost of stack frame setup
    1169              :      actually slowing down functions whose recursion tree is wide rather than
    1170              :      deep.
    1171              : 
    1172              :      Deciding reliably on when to do recursive inlining without profile feedback
    1173              :      is tricky.  For now we disable recursive inlining when probability of self
    1174              :      recursion is low.
    1175              : 
    1176              :      Recursive inlining of self recursive call within loop also results in
    1177              :      large loop depths that generally optimize badly.  We may want to throttle
    1178              :      down inlining in those cases.  In particular this seems to happen in one
    1179              :      of libstdc++ rb tree methods.  */
    1180              :   else
    1181              :     {
    1182        12544 :       if (edge->sreal_frequency () * 100
    1183        12544 :           <= caller_freq
    1184        25088 :              * opt_for_fn (outer_node->decl,
    1185              :                            param_min_inline_recursive_probability))
    1186              :         {
    1187          794 :           reason = "frequency of recursive call is too small";
    1188          794 :           want_inline = false;
    1189              :         }
    1190              :     }
    1191        19673 :   if (!can_inline_edge_by_limits_p (edge, CAN_INLINE_FORCE_LIMITS | CAN_INLINE_REPORT))
    1192              :     {
    1193              :       reason = "inline limits exceeded for always_inline function";
    1194              :       want_inline = false;
    1195              :     }
    1196        19673 :   if (!want_inline && dump_enabled_p ())
    1197            7 :     dump_printf_loc (MSG_MISSED_OPTIMIZATION, edge->call_stmt,
    1198              :                      "   not inlining recursively: %s\n", reason);
    1199        19673 :   return want_inline;
    1200              : }
    1201              : 
    1202              : /* Return true when NODE has uninlinable caller;
    1203              :    set HAS_HOT_CALL if it has hot call.
    1204              :    Worker for cgraph_for_node_and_aliases.  */
    1205              : 
    1206              : static bool
    1207        73655 : check_callers (struct cgraph_node *node, void *has_hot_call)
    1208              : {
    1209        73655 :   struct cgraph_edge *e;
    1210       129572 :   for (e = node->callers; e; e = e->next_caller)
    1211              :     {
    1212        82521 :       if (!opt_for_fn (e->caller->decl, flag_inline_functions_called_once)
    1213        82521 :           || !opt_for_fn (e->caller->decl, optimize))
    1214              :         return true;
    1215        82521 :       if (!can_inline_edge_p (e, true))
    1216              :         return true;
    1217        82494 :       if (e->recursive_p ())
    1218              :         return true;
    1219        82494 :       if (!can_inline_edge_by_limits_p (e, CAN_INLINE_REPORT))
    1220              :         return true;
    1221              :       /* Inlining large functions to large loop depth is often harmful because
    1222              :          of register pressure it implies.  */
    1223        55969 :       if ((int)ipa_call_summaries->get (e)->loop_depth
    1224        55969 :           > param_inline_functions_called_once_loop_depth)
    1225              :         return true;
    1226              :       /* Do not produce gigantic functions.  */
    1227       102643 :       if (estimate_size_after_inlining (e->caller->inlined_to ?
    1228              :                                         e->caller->inlined_to : e->caller, e)
    1229        55969 :           > param_inline_functions_called_once_insns)
    1230              :         return true;
    1231        55917 :       if (!(*(bool *)has_hot_call) && e->maybe_hot_p ())
    1232        10702 :         *(bool *)has_hot_call = true;
    1233              :     }
    1234              :   return false;
    1235              : }
    1236              : 
    1237              : /* If NODE has a caller, return true.  */
    1238              : 
    1239              : static bool
    1240      2159110 : has_caller_p (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
    1241              : {
    1242      2159110 :   if (node->callers)
    1243       676963 :     return true;
    1244              :   return false;
    1245              : }
    1246              : 
    1247              : /* Decide if inlining NODE would reduce unit size by eliminating
    1248              :    the offline copy of function.
    1249              :    When COLD is true the cold calls are considered, too.  */
    1250              : 
    1251              : static bool
    1252      4782128 : want_inline_function_to_all_callers_p (struct cgraph_node *node, bool cold)
    1253              : {
    1254      4782128 :   bool has_hot_call = false;
    1255              : 
    1256              :   /* Aliases gets inlined along with the function they alias.  */
    1257      4782128 :   if (node->alias)
    1258              :     return false;
    1259              :   /* Already inlined?  */
    1260      4704819 :   if (node->inlined_to)
    1261              :     return false;
    1262              :   /* Does it have callers?  */
    1263      2109389 :   if (!node->call_for_symbol_and_aliases (has_caller_p, NULL, true))
    1264              :     return false;
    1265              :   /* Inlining into all callers would increase size?  */
    1266       676963 :   if (growth_positive_p (node, NULL, INT_MIN) > 0)
    1267              :     return false;
    1268              :   /* All inlines must be possible.  */
    1269        68969 :   if (node->call_for_symbol_and_aliases (check_callers, &has_hot_call,
    1270              :                                          true))
    1271              :     return false;
    1272        42365 :   if (!cold && !has_hot_call)
    1273              :     return false;
    1274              :   return true;
    1275              : }
    1276              : 
    1277              : /* Return true if WHERE of SIZE is a possible candidate for wrapper heuristics
    1278              :    in estimate_edge_badness.  */
    1279              : 
    1280              : static bool
    1281       619177 : wrapper_heuristics_may_apply (struct cgraph_node *where, int size)
    1282              : {
    1283       619177 :   return size < (DECL_DECLARED_INLINE_P (where->decl)
    1284       619177 :                  ? inline_insns_single (where, false, false)
    1285       363559 :                  : inline_insns_auto (where, false, false));
    1286              : }
    1287              : 
    1288              : /* A cost model driving the inlining heuristics in a way so the edges with
    1289              :    smallest badness are inlined first.  After each inlining is performed
    1290              :    the costs of all caller edges of nodes affected are recomputed so the
    1291              :    metrics may accurately depend on values such as number of inlinable callers
    1292              :    of the function or function body size.  */
    1293              : 
    1294              : static sreal
    1295     10227748 : edge_badness (struct cgraph_edge *edge, bool dump)
    1296              : {
    1297     10227748 :   sreal badness;
    1298     10227748 :   int growth;
    1299     10227748 :   sreal edge_time, unspec_edge_time;
    1300     10227748 :   struct cgraph_node *callee = edge->callee->ultimate_alias_target ();
    1301     10227748 :   class ipa_fn_summary *callee_info = ipa_fn_summaries->get (callee);
    1302     10227748 :   ipa_hints hints;
    1303      8180002 :   cgraph_node *caller = (edge->caller->inlined_to
    1304     10227748 :                          ? edge->caller->inlined_to
    1305              :                          : edge->caller);
    1306              : 
    1307     10227748 :   growth = estimate_edge_growth (edge);
    1308     10227748 :   edge_time = estimate_edge_time (edge, &unspec_edge_time);
    1309     10227748 :   hints = estimate_edge_hints (edge);
    1310     10227748 :   gcc_checking_assert (edge_time >= 0);
    1311              :   /* Check that inlined time is better, but tolerate some roundoff issues.
    1312              :      FIXME: When callee profile drops to 0 we account calls more.  This
    1313              :      should be fixed by never doing that.  */
    1314     10227748 :   gcc_checking_assert ((edge_time * 100
    1315              :                         - callee_info->time * 101).to_int () <= 0
    1316              :                         || callee->count.ipa ().initialized_p ());
    1317     10227748 :   gcc_checking_assert (growth <= ipa_size_summaries->get (callee)->size);
    1318              : 
    1319     10227748 :   if (dump)
    1320              :     {
    1321          185 :       fprintf (dump_file, "    Badness calculation for %s -> %s\n",
    1322          185 :                edge->caller->dump_name (),
    1323          185 :                edge->callee->dump_name ());
    1324          185 :       fprintf (dump_file, "      size growth %i, time %f unspec %f ",
    1325              :                growth,
    1326              :                edge_time.to_double (),
    1327              :                unspec_edge_time.to_double ());
    1328          185 :       ipa_dump_hints (dump_file, hints);
    1329          185 :       if (big_speedup_p (edge))
    1330          151 :         fprintf (dump_file, " big_speedup");
    1331          185 :       fprintf (dump_file, "\n");
    1332              :     }
    1333              : 
    1334              :   /* Always prefer inlining saving code size.  */
    1335     10227748 :   if (growth <= 0)
    1336              :     {
    1337       504834 :       badness = (sreal) (-SREAL_MIN_SIG + growth) << (SREAL_MAX_EXP / 256);
    1338       504834 :       if (dump)
    1339          108 :         fprintf (dump_file, "      %f: Growth %d <= 0\n", badness.to_double (),
    1340              :                  growth);
    1341              :     }
    1342              :    /* Inlining into EXTERNAL functions is not going to change anything unless
    1343              :       they are themselves inlined.  */
    1344      9722914 :    else if (DECL_EXTERNAL (caller->decl))
    1345              :     {
    1346        24448 :       if (dump)
    1347            0 :         fprintf (dump_file, "      max: function is external\n");
    1348        24448 :       return sreal::max ();
    1349              :     }
    1350              :   /* When profile is available. Compute badness as:
    1351              : 
    1352              :                  time_saved * caller_count
    1353              :      goodness =  -------------------------------------------------
    1354              :                  growth_of_caller * overall_growth * combined_size
    1355              : 
    1356              :      badness = - goodness
    1357              : 
    1358              :      Again use negative value to make calls with profile appear hotter
    1359              :      then calls without.
    1360              :   */
    1361      9698466 :   else if (opt_for_fn (caller->decl, flag_guess_branch_prob)
    1362      9698466 :            || caller->count.ipa ().nonzero_p ())
    1363              :     {
    1364      9697144 :       sreal numerator, denominator;
    1365      9697144 :       int overall_growth;
    1366      9697144 :       sreal freq = edge->sreal_frequency ();
    1367              : 
    1368      9697144 :       numerator = inlining_speedup (edge, freq, unspec_edge_time, edge_time);
    1369      9697144 :       if (numerator <= 0)
    1370         4839 :         numerator = ((sreal) 1 >> 8);
    1371      9697144 :       if (caller->count.ipa ().nonzero_p ())
    1372          179 :         numerator *= caller->count.ipa ().to_gcov_type ();
    1373      9696965 :       else if (caller->count.ipa ().initialized_p ())
    1374          757 :         numerator = numerator >> 11;
    1375      9697144 :       denominator = growth;
    1376              : 
    1377      9697144 :       overall_growth = callee_info->growth;
    1378              : 
    1379              :       /* Look for inliner wrappers of the form:
    1380              : 
    1381              :          inline_caller ()
    1382              :            {
    1383              :              do_fast_job...
    1384              :              if (need_more_work)
    1385              :                noninline_callee ();
    1386              :            }
    1387              :          Without penalizing this case, we usually inline noninline_callee
    1388              :          into the inline_caller because overall_growth is small preventing
    1389              :          further inlining of inline_caller.
    1390              : 
    1391              :          Penalize only callgraph edges to functions with small overall
    1392              :          growth ...
    1393              :         */
    1394      9697144 :       if (growth > overall_growth
    1395              :           /* ... and having only one caller which is not inlined ... */
    1396      2097544 :           && callee_info->single_caller
    1397      1167901 :           && !edge->caller->inlined_to
    1398              :           /* ... and edges executed only conditionally ... */
    1399       815669 :           && freq < 1
    1400              :           /* ... consider case where callee is not inline but caller is ... */
    1401     10065342 :           && ((!DECL_DECLARED_INLINE_P (edge->callee->decl)
    1402        94672 :                && DECL_DECLARED_INLINE_P (caller->decl))
    1403              :               /* ... or when early optimizers decided to split and edge
    1404              :                  frequency still indicates splitting is a win ... */
    1405       360778 :               || (callee->split_part && !caller->split_part
    1406        89897 :                   && freq * 100
    1407      9780876 :                          < opt_for_fn (caller->decl,
    1408              :                                        param_partial_inlining_entry_probability)
    1409              :                   /* ... and do not overwrite user specified hints.   */
    1410        89432 :                   && (!DECL_DECLARED_INLINE_P (edge->callee->decl)
    1411        66385 :                       || DECL_DECLARED_INLINE_P (caller->decl)))))
    1412              :         {
    1413        95597 :           ipa_fn_summary *caller_info = ipa_fn_summaries->get (caller);
    1414        95597 :           int caller_growth = caller_info->growth;
    1415              : 
    1416              :           /* Only apply the penalty when caller looks like inline candidate,
    1417              :              and it is not called once.  */
    1418        52749 :           if (!caller_info->single_caller && overall_growth < caller_growth
    1419        50521 :               && caller_info->inlinable
    1420       146064 :               && wrapper_heuristics_may_apply
    1421        50467 :                  (caller, ipa_size_summaries->get (caller)->size))
    1422              :             {
    1423        40821 :               if (dump)
    1424            1 :                 fprintf (dump_file,
    1425              :                          "     Wrapper penalty. Increasing growth %i to %i\n",
    1426              :                          overall_growth, caller_growth);
    1427              :               overall_growth = caller_growth;
    1428              :             }
    1429              :         }
    1430      9697144 :       if (overall_growth > 0)
    1431              :         {
    1432              :           /* Strongly prefer functions with few callers that can be inlined
    1433              :              fully.  The square root here leads to smaller binaries at average.
    1434              :              Watch however for extreme cases and return to linear function
    1435              :              when growth is large.  */
    1436      8323658 :           if (overall_growth < 256)
    1437      4319235 :             overall_growth *= overall_growth;
    1438              :           else
    1439      4004423 :             overall_growth += 256 * 256 - 256;
    1440      8323658 :           denominator *= overall_growth;
    1441              :         }
    1442      9697144 :       denominator *= ipa_size_summaries->get (caller)->size + growth;
    1443              : 
    1444      9697144 :       badness = - numerator / denominator;
    1445              : 
    1446      9697144 :       if (dump)
    1447              :         {
    1448          308 :           fprintf (dump_file,
    1449              :                    "      %f: guessed profile. frequency %f, count %" PRId64
    1450              :                    " caller count %" PRId64
    1451              :                    " time saved %f"
    1452              :                    " overall growth %i (current) %i (original)"
    1453              :                    " %i (compensated)\n",
    1454              :                    badness.to_double (),
    1455              :                    freq.to_double (),
    1456           77 :                    edge->count.ipa ().initialized_p ()
    1457            0 :                    ? edge->count.ipa ().to_gcov_type () : -1,
    1458           77 :                    caller->count.ipa ().initialized_p ()
    1459            0 :                    ? caller->count.ipa ().to_gcov_type () : -1,
    1460          154 :                    inlining_speedup (edge, freq, unspec_edge_time,
    1461              :                                      edge_time).to_double (),
    1462              :                    estimate_growth (callee),
    1463              :                    callee_info->growth, overall_growth);
    1464              :         }
    1465              :     }
    1466              :   /* When function local profile is not available or it does not give
    1467              :      useful information (i.e. frequency is zero), base the cost on
    1468              :      loop nest and overall size growth, so we optimize for overall number
    1469              :      of functions fully inlined in program.  */
    1470              :   else
    1471              :     {
    1472         1322 :       int nest = MIN (ipa_call_summaries->get (edge)->loop_depth, 8);
    1473         1322 :       badness = growth;
    1474              : 
    1475              :       /* Decrease badness if call is nested.  */
    1476         1322 :       if (badness > 0)
    1477         1322 :         badness = badness >> nest;
    1478              :       else
    1479            0 :         badness = badness << nest;
    1480         1322 :       if (dump)
    1481            0 :         fprintf (dump_file, "      %f: no profile. nest %i\n",
    1482              :                  badness.to_double (), nest);
    1483              :     }
    1484     10203300 :   gcc_checking_assert (badness != 0);
    1485              : 
    1486     10203300 :   if (edge->recursive_p ())
    1487        18729 :     badness = badness.shift (badness > 0 ? 4 : -4);
    1488     10203300 :   if ((hints & (INLINE_HINT_indirect_call
    1489              :                 | INLINE_HINT_loop_iterations
    1490              :                 | INLINE_HINT_loop_stride))
    1491      9382948 :       || callee_info->growth <= 0)
    1492      4709440 :     badness = badness.shift (badness > 0 ? -2 : 2);
    1493     10203300 :   if (hints & INLINE_HINT_builtin_constant_p)
    1494        20986 :     badness = badness.shift (badness > 0 ? -4 : 4);
    1495     10203300 :   if (hints & (INLINE_HINT_same_scc))
    1496        60344 :     badness = badness.shift (badness > 0 ? 3 : -3);
    1497     10173127 :   else if (hints & (INLINE_HINT_in_scc))
    1498       113944 :     badness = badness.shift (badness > 0 ? 2 : -2);
    1499     10116155 :   else if (hints & (INLINE_HINT_cross_module))
    1500         3582 :     badness = badness.shift (badness > 0 ? 1 : -1);
    1501     10203300 :   if (DECL_DISREGARD_INLINE_LIMITS (callee->decl))
    1502        17448 :     badness = badness.shift (badness > 0 ? -4 : 4);
    1503     10194576 :   else if ((hints & INLINE_HINT_declared_inline))
    1504     15492071 :     badness = badness.shift (badness > 0 ? -3 : 3);
    1505     10203300 :   if (dump)
    1506          185 :     fprintf (dump_file, "      Adjusted by hints %f\n", badness.to_double ());
    1507     10203300 :   return badness;
    1508              : }
    1509              : 
    1510              : /* Recompute badness of EDGE and update its key in HEAP if needed.  */
    1511              : static inline void
    1512      5220578 : update_edge_key (edge_heap_t *heap, struct cgraph_edge *edge)
    1513              : {
    1514      5220578 :   sreal badness = edge_badness (edge, false);
    1515      5220578 :   if (edge->aux)
    1516              :     {
    1517      4170963 :       edge_heap_node_t *n = (edge_heap_node_t *) edge->aux;
    1518      4170963 :       gcc_checking_assert (n->get_data () == edge);
    1519              : 
    1520              :       /* fibonacci_heap::replace_key does busy updating of the
    1521              :          heap that is unnecessarily expensive.
    1522              :          We do lazy increases: after extracting minimum if the key
    1523              :          turns out to be out of date, it is re-inserted into heap
    1524              :          with correct value.  */
    1525      4170963 :       if (badness < n->get_key ().badness)
    1526              :         {
    1527       891882 :           if (dump_file && (dump_flags & TDF_DETAILS))
    1528              :             {
    1529           90 :               fprintf (dump_file,
    1530              :                        "  decreasing badness %s -> %s, %f to %f\n",
    1531           45 :                        edge->caller->dump_name (),
    1532           45 :                        edge->callee->dump_name (),
    1533           90 :                        n->get_key ().badness.to_double (),
    1534              :                        badness.to_double ());
    1535              :             }
    1536       891882 :           inline_badness b (edge, badness);
    1537       891882 :           heap->decrease_key (n, b);
    1538              :         }
    1539              :     }
    1540              :   else
    1541              :     {
    1542      1049615 :        if (dump_file && (dump_flags & TDF_DETAILS))
    1543              :          {
    1544          338 :            fprintf (dump_file,
    1545              :                     "  enqueuing call %s -> %s, badness %f\n",
    1546          169 :                     edge->caller->dump_name (),
    1547          169 :                     edge->callee->dump_name (),
    1548              :                     badness.to_double ());
    1549              :          }
    1550      1049615 :       inline_badness b (edge, badness);
    1551      1049615 :       edge->aux = heap->insert (b, edge);
    1552              :     }
    1553      5220578 : }
    1554              : 
    1555              : 
    1556              : /* NODE was inlined.
    1557              :    All caller edges needs to be reset because
    1558              :    size estimates change. Similarly callees needs reset
    1559              :    because better context may be known.  */
    1560              : 
    1561              : static void
    1562       923057 : reset_edge_caches (struct cgraph_node *node)
    1563              : {
    1564       923057 :   struct cgraph_edge *edge;
    1565       923057 :   struct cgraph_edge *e = node->callees;
    1566       923057 :   struct cgraph_node *where = node;
    1567       923057 :   struct ipa_ref *ref;
    1568              : 
    1569       923057 :   if (where->inlined_to)
    1570       861621 :     where = where->inlined_to;
    1571              : 
    1572       923057 :   reset_node_cache (where);
    1573              : 
    1574       923057 :   if (edge_growth_cache != NULL)
    1575      3063434 :     for (edge = where->callers; edge; edge = edge->next_caller)
    1576      2141858 :       if (edge->inline_failed)
    1577      2141858 :         edge_growth_cache->remove (edge);
    1578              : 
    1579       979464 :   FOR_EACH_ALIAS (where, ref)
    1580       112814 :     reset_edge_caches (dyn_cast <cgraph_node *> (ref->referring));
    1581              : 
    1582       923057 :   if (!e)
    1583              :     return;
    1584              : 
    1585      2946087 :   while (true)
    1586      2946087 :     if (!e->inline_failed && e->callee->callees)
    1587              :       e = e->callee->callees;
    1588              :     else
    1589              :       {
    1590      2396143 :         if (edge_growth_cache != NULL && e->inline_failed)
    1591      2196114 :           edge_growth_cache->remove (e);
    1592      2396143 :         if (e->next_callee)
    1593              :           e = e->next_callee;
    1594              :         else
    1595              :           {
    1596      1317106 :             do
    1597              :               {
    1598      1317106 :                 if (e->caller == node)
    1599              :                   return;
    1600       549944 :                 e = e->caller->callers;
    1601              :               }
    1602       549944 :             while (!e->next_callee);
    1603              :             e = e->next_callee;
    1604              :           }
    1605              :       }
    1606              : }
    1607              : 
    1608              : /* Recompute HEAP nodes for each of caller of NODE.
    1609              :    UPDATED_NODES track nodes we already visited, to avoid redundant work.
    1610              :    When CHECK_INLINABLITY_FOR is set, re-check for specified edge that
    1611              :    it is inlinable. Otherwise check all edges.  */
    1612              : 
    1613              : static void
    1614       921270 : update_caller_keys (edge_heap_t *heap, struct cgraph_node *node,
    1615              :                     bitmap updated_nodes,
    1616              :                     struct cgraph_edge *check_inlinablity_for)
    1617              : {
    1618       921270 :   struct cgraph_edge *edge;
    1619       921270 :   struct ipa_ref *ref;
    1620              : 
    1621       921270 :   if ((!node->alias && !ipa_fn_summaries->get (node)->inlinable)
    1622       908723 :       || node->inlined_to)
    1623        12547 :     return;
    1624       908723 :   if (!bitmap_set_bit (updated_nodes, node->get_summary_id ()))
    1625              :     return;
    1626              : 
    1627       964629 :   FOR_EACH_ALIAS (node, ref)
    1628              :     {
    1629        55906 :       struct cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
    1630        55906 :       update_caller_keys (heap, alias, updated_nodes, check_inlinablity_for);
    1631              :     }
    1632              : 
    1633      2941192 :   for (edge = node->callers; edge; edge = edge->next_caller)
    1634      2032469 :     if (edge->inline_failed)
    1635              :       {
    1636      2032469 :         if (!check_inlinablity_for
    1637      2032469 :             || check_inlinablity_for == edge)
    1638              :           {
    1639      2032469 :             if (can_inline_edge_p (edge, false)
    1640      1998355 :                 && want_inline_small_function_p (edge, false)
    1641      2622209 :                 && can_inline_edge_by_limits_p (edge, 0))
    1642       584585 :               update_edge_key (heap, edge);
    1643      1447884 :             else if (edge->aux)
    1644              :               {
    1645        91937 :                 report_inline_failed_reason (edge);
    1646        91937 :                 heap->delete_node ((edge_heap_node_t *) edge->aux);
    1647        91937 :                 edge->aux = NULL;
    1648              :               }
    1649              :           }
    1650            0 :         else if (edge->aux)
    1651            0 :           update_edge_key (heap, edge);
    1652              :       }
    1653              : }
    1654              : 
    1655              : /* Recompute HEAP nodes for each uninlined call in NODE
    1656              :    If UPDATE_SINCE is non-NULL check if edges called within that function
    1657              :    are inlinable (typically UPDATE_SINCE is the inline clone we introduced
    1658              :    where all edges have new context).
    1659              : 
    1660              :    This is used when we know that edge badnesses are going only to increase
    1661              :    (we introduced new call site) and thus all we need is to insert newly
    1662              :    created edges into heap.  */
    1663              : 
    1664              : static void
    1665       865421 : update_callee_keys (edge_heap_t *heap, struct cgraph_node *node,
    1666              :                     struct cgraph_node *update_since,
    1667              :                     bitmap updated_nodes)
    1668              : {
    1669       865421 :   struct cgraph_edge *e = node->callees;
    1670       865421 :   bool check_inlinability = update_since == node;
    1671              : 
    1672       865421 :   if (!e)
    1673              :     return;
    1674     25631198 :   while (true)
    1675     25631198 :     if (!e->inline_failed && e->callee->callees)
    1676              :       {
    1677      3985607 :         if (e->callee == update_since)
    1678       398478 :           check_inlinability = true;
    1679              :         e = e->callee->callees;
    1680              :       }
    1681              :     else
    1682              :       {
    1683     21645591 :         enum availability avail;
    1684     21645591 :         struct cgraph_node *callee;
    1685     21645591 :         if (!check_inlinability)
    1686              :           {
    1687     19428709 :             if (e->aux
    1688     22844960 :                 && !bitmap_bit_p (updated_nodes,
    1689      3416251 :                                   e->callee->ultimate_alias_target
    1690      3416251 :                                     (&avail, e->caller)->get_summary_id ()))
    1691      3416244 :               update_edge_key (heap, e);
    1692              :           }
    1693              :         /* We do not reset callee growth cache here.  Since we added a new call,
    1694              :            growth should have just increased and consequently badness metric
    1695              :            don't need updating.  */
    1696      2216882 :         else if (e->inline_failed
    1697      2114410 :                  && (callee = e->callee->ultimate_alias_target (&avail,
    1698      2114410 :                                                                 e->caller))
    1699      2114410 :                  && avail >= AVAIL_AVAILABLE
    1700       536340 :                  && ipa_fn_summaries->get (callee) != NULL
    1701       536335 :                  && ipa_fn_summaries->get (callee)->inlinable
    1702      2738956 :                  && !bitmap_bit_p (updated_nodes, callee->get_summary_id ()))
    1703              :           {
    1704       522074 :             if (can_inline_edge_p (e, false)
    1705       516907 :                 && want_inline_small_function_p (e, false)
    1706       823529 :                 && can_inline_edge_by_limits_p (e, 0))
    1707              :               {
    1708       300798 :                 gcc_checking_assert (check_inlinability || can_inline_edge_p (e, false));
    1709       300798 :                 gcc_checking_assert (check_inlinability || e->aux);
    1710       300798 :                 update_edge_key (heap, e);
    1711              :               }
    1712       221276 :             else if (e->aux)
    1713              :               {
    1714         6649 :                 report_inline_failed_reason (e);
    1715         6649 :                 heap->delete_node ((edge_heap_node_t *) e->aux);
    1716         6649 :                 e->aux = NULL;
    1717              :               }
    1718              :           }
    1719              :         /* In case we redirected to unreachable node we only need to remove the
    1720              :            fibheap entry.  */
    1721      1694808 :         else if (e->aux)
    1722              :           {
    1723         3028 :             heap->delete_node ((edge_heap_node_t *) e->aux);
    1724         3028 :             e->aux = NULL;
    1725              :           }
    1726     21645591 :         if (e->next_callee)
    1727              :           e = e->next_callee;
    1728              :         else
    1729              :           {
    1730      4815998 :             do
    1731              :               {
    1732      4815998 :                 if (e->caller == node)
    1733       830391 :                   return;
    1734      3985607 :                 if (e->caller == update_since)
    1735       398478 :                   check_inlinability = false;
    1736      3985607 :                 e = e->caller->callers;
    1737              :               }
    1738      3985607 :             while (!e->next_callee);
    1739              :             e = e->next_callee;
    1740              :           }
    1741              :       }
    1742              : }
    1743              : 
    1744              : /* Enqueue all recursive calls from NODE into priority queue depending on
    1745              :    how likely we want to recursively inline the call.  */
    1746              : 
    1747              : static void
    1748        21289 : lookup_recursive_calls (struct cgraph_node *node, struct cgraph_node *where,
    1749              :                         edge_heap_t *heap)
    1750              : {
    1751        21289 :   struct cgraph_edge *e;
    1752        21289 :   enum availability avail;
    1753              : 
    1754        59805 :   for (e = where->callees; e; e = e->next_callee)
    1755        38516 :     if (e->callee == node
    1756        38516 :         || (e->callee->ultimate_alias_target (&avail, e->caller) == node
    1757         1142 :             && avail > AVAIL_INTERPOSABLE))
    1758              :     {
    1759        16048 :       inline_badness b (e, -e->sreal_frequency ());
    1760        16048 :       heap->insert (b, e);
    1761              :     }
    1762        59805 :   for (e = where->callees; e; e = e->next_callee)
    1763        38516 :     if (!e->inline_failed)
    1764         7578 :       lookup_recursive_calls (node, e->callee, heap);
    1765        21289 : }
    1766              : 
    1767              : /* Decide on recursive inlining: in the case function has recursive calls,
    1768              :    inline until body size reaches given argument.  If any new indirect edges
    1769              :    are discovered in the process, add them to *NEW_EDGES, unless NEW_EDGES
    1770              :    is NULL.  */
    1771              : 
    1772              : static bool
    1773         1961 : recursive_inlining (struct cgraph_edge *edge,
    1774              :                     vec<cgraph_edge *> *new_edges)
    1775              : {
    1776         1402 :   cgraph_node *to  = (edge->caller->inlined_to
    1777         1961 :                       ? edge->caller->inlined_to : edge->caller);
    1778         1961 :   int limit = opt_for_fn (to->decl,
    1779              :                           param_max_inline_insns_recursive_auto);
    1780         1961 :   inline_badness b (edge, sreal::min ());
    1781         1961 :   edge_heap_t heap (b);
    1782         1961 :   struct cgraph_node *node;
    1783         1961 :   struct cgraph_edge *e;
    1784         1961 :   struct cgraph_node *master_clone = NULL, *next;
    1785         1961 :   int depth = 0;
    1786         1961 :   int n = 0;
    1787              : 
    1788         1961 :   node = edge->caller;
    1789         1961 :   if (node->inlined_to)
    1790          559 :     node = node->inlined_to;
    1791              : 
    1792         1961 :   if (DECL_DECLARED_INLINE_P (node->decl))
    1793          417 :     limit = opt_for_fn (to->decl, param_max_inline_insns_recursive);
    1794              : 
    1795              :   /* Make sure that function is small enough to be considered for inlining.  */
    1796         1961 :   if (estimate_size_after_inlining (node, edge)  >= limit)
    1797              :     return false;
    1798         1961 :   lookup_recursive_calls (node, node, &heap);
    1799         1961 :   if (heap.empty ())
    1800              :     return false;
    1801              : 
    1802         1961 :   if (dump_file)
    1803            4 :     fprintf (dump_file,
    1804              :              "  Performing recursive inlining on %s\n", node->dump_name ());
    1805              : 
    1806              :   /* Do the inlining and update list of recursive call during process.  */
    1807        16745 :   while (!heap.empty ())
    1808              :     {
    1809        14807 :       struct cgraph_edge *curr = heap.extract_min ();
    1810        14807 :       struct cgraph_node *cnode, *dest = curr->callee;
    1811              : 
    1812        14807 :       if (!can_inline_edge_p (curr, true)
    1813        14807 :           || !can_inline_edge_by_limits_p (curr, CAN_INLINE_REPORT | CAN_INLINE_FORCE_LIMITS))
    1814            0 :         continue;
    1815              : 
    1816              :       /* MASTER_CLONE is produced in the case we already started modified
    1817              :          the function. Be sure to redirect edge to the original body before
    1818              :          estimating growths otherwise we will be seeing growths after inlining
    1819              :          the already modified body.  */
    1820        14807 :       if (master_clone)
    1821              :         {
    1822        12740 :           curr->redirect_callee (master_clone);
    1823        12740 :           if (edge_growth_cache != NULL)
    1824        12740 :             edge_growth_cache->remove (curr);
    1825              :         }
    1826              : 
    1827        14807 :       if (estimate_size_after_inlining (node, curr) > limit)
    1828              :         {
    1829           23 :           curr->redirect_callee (dest);
    1830           23 :           if (edge_growth_cache != NULL)
    1831           23 :             edge_growth_cache->remove (curr);
    1832              :           break;
    1833              :         }
    1834              : 
    1835        14784 :       depth = 1;
    1836        14784 :       for (cnode = curr->caller;
    1837        77024 :            cnode->inlined_to; cnode = cnode->callers->caller)
    1838       124480 :         if (node->decl
    1839        62240 :             == curr->callee->ultimate_alias_target ()->decl)
    1840        62240 :           depth++;
    1841              : 
    1842        14784 :       if (!want_inline_self_recursive_call_p (curr, node, false, depth))
    1843              :         {
    1844         3034 :           curr->redirect_callee (dest);
    1845         3034 :           if (edge_growth_cache != NULL)
    1846         3034 :             edge_growth_cache->remove (curr);
    1847         3034 :           continue;
    1848              :         }
    1849              : 
    1850        11750 :       if (dump_file)
    1851              :         {
    1852           14 :           fprintf (dump_file,
    1853              :                    "   Inlining call of depth %i", depth);
    1854           28 :           if (node->count.nonzero_p () && curr->count.initialized_p ())
    1855              :             {
    1856            2 :               fprintf (dump_file, " called approx. %.2f times per call",
    1857            2 :                        (double)curr->count.to_gcov_type ()
    1858            2 :                        / node->count.to_gcov_type ());
    1859              :             }
    1860           14 :           fprintf (dump_file, "\n");
    1861              :         }
    1862        11750 :       if (!master_clone)
    1863              :         {
    1864              :           /* We need original clone to copy around.  */
    1865         1609 :           master_clone = node->create_clone (node->decl, node->count,
    1866         1609 :             false, vNULL, true, NULL, NULL, NULL);
    1867         4587 :           for (e = master_clone->callees; e; e = e->next_callee)
    1868         2978 :             if (!e->inline_failed)
    1869          488 :               clone_inlined_nodes (e, true, true, false, NULL);
    1870         1609 :           curr->redirect_callee (master_clone);
    1871         1609 :           if (edge_growth_cache != NULL)
    1872         1609 :             edge_growth_cache->remove (curr);
    1873              :         }
    1874              : 
    1875        11750 :       inline_call (curr, false, new_edges, &overall_size, true);
    1876        11750 :       reset_node_cache (node);
    1877        11750 :       lookup_recursive_calls (node, curr->callee, &heap);
    1878        11750 :       n++;
    1879              :     }
    1880              : 
    1881         1961 :   if (!heap.empty () && dump_file)
    1882            0 :     fprintf (dump_file, "    Recursive inlining growth limit met.\n");
    1883              : 
    1884         1961 :   if (!master_clone)
    1885              :     return false;
    1886              : 
    1887         1609 :   if (dump_enabled_p ())
    1888            4 :     dump_printf_loc (MSG_NOTE, edge->call_stmt,
    1889              :                      "\n   Inlined %i times, "
    1890              :                      "body grown from size %i to %i, time %f to %f\n", n,
    1891            4 :                      ipa_size_summaries->get (master_clone)->size,
    1892            4 :                      ipa_size_summaries->get (node)->size,
    1893            4 :                      ipa_fn_summaries->get (master_clone)->time.to_double (),
    1894            4 :                      ipa_fn_summaries->get (node)->time.to_double ());
    1895              : 
    1896              :   /* Remove master clone we used for inlining.  We rely that clones inlined
    1897              :      into master clone gets queued just before master clone so we don't
    1898              :      need recursion.  */
    1899        18672 :   for (node = symtab->first_function (); node != master_clone;
    1900              :        node = next)
    1901              :     {
    1902        17063 :       next = symtab->next_function (node);
    1903        17063 :       if (node->inlined_to == master_clone)
    1904          865 :         node->remove ();
    1905              :     }
    1906         1609 :   master_clone->remove ();
    1907         1609 :   return true;
    1908         1961 : }
    1909              : 
    1910              : 
    1911              : /* Given whole compilation unit estimate of INSNS, compute how large we can
    1912              :    allow the unit to grow.  */
    1913              : 
    1914              : static int64_t
    1915       944136 : compute_max_insns (cgraph_node *node, int insns)
    1916              : {
    1917       944136 :   int max_insns = insns;
    1918       944136 :   if (max_insns < opt_for_fn (node->decl, param_large_unit_insns))
    1919              :     max_insns = opt_for_fn (node->decl, param_large_unit_insns);
    1920              : 
    1921       944136 :   return ((int64_t) max_insns
    1922       944136 :           * (100 + opt_for_fn (node->decl, param_inline_unit_growth)) / 100);
    1923              : }
    1924              : 
    1925              : 
    1926              : /* Compute badness of all edges in NEW_EDGES and add them to the HEAP.  */
    1927              : 
    1928              : static void
    1929       863205 : add_new_edges_to_heap (edge_heap_t *heap, vec<cgraph_edge *> &new_edges)
    1930              : {
    1931      1729015 :   while (new_edges.length () > 0)
    1932              :     {
    1933         2605 :       struct cgraph_edge *edge = new_edges.pop ();
    1934              : 
    1935         2605 :       gcc_assert (!edge->aux);
    1936         2605 :       gcc_assert (edge->callee);
    1937         2605 :       if (edge->inline_failed
    1938         2605 :           && can_inline_edge_p (edge, true)
    1939         1148 :           && want_inline_small_function_p (edge, true)
    1940         3423 :           && can_inline_edge_by_limits_p (edge, CAN_INLINE_REPORT))
    1941              :         {
    1942          818 :           inline_badness b (edge, edge_badness (edge, false));
    1943          818 :           edge->aux = heap->insert (b, edge);
    1944              :         }
    1945              :     }
    1946       863205 : }
    1947              : 
    1948              : /* Remove EDGE from the fibheap.  */
    1949              : 
    1950              : static void
    1951         9014 : heap_edge_removal_hook (struct cgraph_edge *e, void *data)
    1952              : {
    1953         9014 :   if (e->aux)
    1954              :     {
    1955           98 :       ((edge_heap_t *)data)->delete_node ((edge_heap_node_t *)e->aux);
    1956           98 :       e->aux = NULL;
    1957              :     }
    1958         9014 : }
    1959              : 
    1960              : /* Return true if speculation of edge E seems useful.
    1961              :    If ANTICIPATE_INLINING is true, be conservative and hope that E
    1962              :    may get inlined.  */
    1963              : 
    1964              : bool
    1965       118594 : speculation_useful_p (struct cgraph_edge *e, bool anticipate_inlining)
    1966              : {
    1967              :   /* If we have already decided to inline the edge, it seems useful.
    1968              :      Also if ipa-cp or other pass worked hard enough to produce a clone,
    1969              :      we already decided this is a good idea.  */
    1970       118594 :   if (!e->inline_failed
    1971        34229 :       || e->callee->clone_of)
    1972              :     return true;
    1973              : 
    1974        32181 :   enum availability avail;
    1975        32181 :   struct cgraph_node *target = e->callee->ultimate_alias_target (&avail,
    1976              :                                                                  e->callee);
    1977              : 
    1978        32181 :   gcc_assert (e->speculative && !e->indirect_unknown_callee);
    1979              : 
    1980              :   /* Even if call statement is not hot, we can still have useful speculation
    1981              :      in cases where a lot of time is spent is callee.
    1982              :      Do not check maybe_hot_p.  */
    1983        36663 :   if (!e->count.nonzero_p ())
    1984              :     return false;
    1985              : 
    1986              :   /* See if IP optimizations found something potentially useful about the
    1987              :      function.  Do this only if the call seems hot since this is about
    1988              :      optimizing the code surrounding call site rahter than improving
    1989              :      callee.  */
    1990        32142 :   if (avail >= AVAIL_AVAILABLE && e->maybe_hot_p ())
    1991              :     {
    1992        31176 :       int ecf_flags = flags_from_decl_or_type (target->decl);
    1993        31176 :       if (ecf_flags & ECF_CONST)
    1994              :         {
    1995          469 :           if (!(e->speculative_call_indirect_edge ()->indirect_info
    1996          469 :                 ->ecf_flags & ECF_CONST))
    1997              :             return true;
    1998              :         }
    1999        30707 :       else if (ecf_flags & ECF_PURE)
    2000              :         {
    2001         2775 :           if (!(e->speculative_call_indirect_edge ()->indirect_info
    2002         2775 :                 ->ecf_flags & ECF_PURE))
    2003              :             return true;
    2004              :         }
    2005        27932 :       else if (get_modref_function_summary (target))
    2006              :         return true;
    2007              :     }
    2008              :   /* If we did not managed to inline the function nor redirect
    2009              :      to an ipa-cp clone (that are seen by having local flag set),
    2010              :      it is probably pointless to inline it unless hardware is missing
    2011              :      indirect call predictor.
    2012              : 
    2013              :      At this point we know we will not dispatch into faster version of
    2014              :      callee, so if call itself is not hot, we definitely can give up
    2015              :      speculating.  */
    2016        14761 :   if (!anticipate_inlining && (!target->local || !e->maybe_hot_p ()))
    2017         4475 :     return false;
    2018              :   /* For overwritable targets there is not much to do.  */
    2019        10286 :   if (!can_inline_edge_p (e, false)
    2020        10286 :       || !can_inline_edge_by_limits_p (e, CAN_INLINE_DISREGARD_LIMITS))
    2021            6 :     return false;
    2022              :   /* OK, speculation seems interesting.  */
    2023              :   return true;
    2024              : }
    2025              : 
    2026              : /* We know that EDGE is not going to be inlined.
    2027              :    See if we can remove speculation.  */
    2028              : 
    2029              : static void
    2030        85404 : resolve_noninline_speculation (edge_heap_t *edge_heap, struct cgraph_edge *edge)
    2031              : {
    2032        85404 :   if (edge->speculative && !speculation_useful_p (edge, false))
    2033              :     {
    2034         1759 :       struct cgraph_node *node = edge->caller;
    2035         1753 :       struct cgraph_node *where = node->inlined_to
    2036         1759 :                                   ? node->inlined_to : node;
    2037         1759 :       auto_bitmap updated_nodes;
    2038              : 
    2039         1759 :       if (edge->count.ipa ().initialized_p ())
    2040            0 :         spec_rem += edge->count.ipa ();
    2041         1759 :       cgraph_edge::resolve_speculation (edge);
    2042         1759 :       reset_edge_caches (where);
    2043         1759 :       ipa_update_overall_fn_summary (where);
    2044         1759 :       update_caller_keys (edge_heap, where,
    2045              :                           updated_nodes, NULL);
    2046         1759 :       update_callee_keys (edge_heap, where, NULL,
    2047              :                           updated_nodes);
    2048         1759 :     }
    2049        85404 : }
    2050              : 
    2051              : /* Return true if NODE should be accounted for overall size estimate.
    2052              :    Skip all nodes optimized for size so we can measure the growth of hot
    2053              :    part of program no matter of the padding.  */
    2054              : 
    2055              : bool
    2056      3639514 : inline_account_function_p (struct cgraph_node *node)
    2057              : {
    2058      3639514 :    return (!DECL_EXTERNAL (node->decl)
    2059      3531060 :            && !opt_for_fn (node->decl, optimize_size)
    2060      7077527 :            && node->frequency != NODE_FREQUENCY_UNLIKELY_EXECUTED);
    2061              : }
    2062              : 
    2063              : /* Count number of callers of NODE and store it into DATA (that
    2064              :    points to int.  Worker for cgraph_for_node_and_aliases.  */
    2065              : 
    2066              : static bool
    2067      1459853 : sum_callers (struct cgraph_node *node, void *data)
    2068              : {
    2069      1459853 :   struct cgraph_edge *e;
    2070      1459853 :   int *num_calls = (int *)data;
    2071              : 
    2072      3468394 :   for (e = node->callers; e; e = e->next_caller)
    2073      2008541 :     (*num_calls)++;
    2074      1459853 :   return false;
    2075              : }
    2076              : 
    2077              : /* We only propagate across edges with non-interposable callee.  */
    2078              : 
    2079              : inline bool
    2080      6978631 : ignore_edge_p (struct cgraph_edge *e)
    2081              : {
    2082      6978631 :   enum availability avail;
    2083      6978631 :   e->callee->function_or_virtual_thunk_symbol (&avail, e->caller);
    2084      6978631 :   return (avail <= AVAIL_INTERPOSABLE);
    2085              : }
    2086              : 
    2087              : /* We use greedy algorithm for inlining of small functions:
    2088              :    All inline candidates are put into prioritized heap ordered in
    2089              :    increasing badness.
    2090              : 
    2091              :    The inlining of small functions is bounded by unit growth parameters.  */
    2092              : 
    2093              : static void
    2094       230059 : inline_small_functions (void)
    2095              : {
    2096       230059 :   struct cgraph_node *node;
    2097       230059 :   struct cgraph_edge *edge;
    2098       230059 :   inline_badness b;
    2099       230059 :   edge_heap_t edge_heap (b);
    2100       230059 :   auto_bitmap updated_nodes;
    2101       230059 :   int min_size;
    2102       230059 :   auto_vec<cgraph_edge *> new_indirect_edges;
    2103       230059 :   int initial_size = 0;
    2104       230059 :   struct cgraph_node **order = XCNEWVEC (cgraph_node *, symtab->cgraph_count);
    2105       230059 :   struct cgraph_edge_hook_list *edge_removal_hook_holder;
    2106       230059 :   new_indirect_edges.create (8);
    2107              : 
    2108       230059 :   edge_removal_hook_holder
    2109       230059 :     = symtab->add_edge_removal_hook (&heap_edge_removal_hook, &edge_heap);
    2110              : 
    2111              :   /* Compute overall unit size and other global parameters used by badness
    2112              :      metrics.  */
    2113              : 
    2114       230059 :   has_nonzero_ipa_profile = false;
    2115       230059 :   ipa_reduced_postorder (order, true, ignore_edge_p);
    2116       230059 :   free (order);
    2117              : 
    2118      2113732 :   FOR_EACH_DEFINED_FUNCTION (node)
    2119      1883673 :     if (!node->inlined_to)
    2120              :       {
    2121      1784654 :         if (!node->alias && node->analyzed
    2122      1784654 :             && (node->has_gimple_body_p () || node->thunk)
    2123      3668296 :             && opt_for_fn (node->decl, optimize))
    2124              :           {
    2125      1357337 :             class ipa_fn_summary *info = ipa_fn_summaries->get (node);
    2126      1357337 :             struct ipa_dfs_info *dfs = (struct ipa_dfs_info *) node->aux;
    2127              : 
    2128              :             /* Do not account external functions, they will be optimized out
    2129              :                if not inlined.  Also only count the non-cold portion of program.  */
    2130      1357337 :             if (inline_account_function_p (node))
    2131      1260957 :               initial_size += ipa_size_summaries->get (node)->size;
    2132      1357337 :             info->growth = estimate_growth (node);
    2133              : 
    2134      1357337 :             int num_calls = 0;
    2135      1357337 :             node->call_for_symbol_and_aliases (sum_callers, &num_calls,
    2136              :                                                true);
    2137      1357337 :             if (num_calls == 1)
    2138       450269 :               info->single_caller = true;
    2139      1357337 :             if (dfs && dfs->next_cycle)
    2140              :               {
    2141         4585 :                 struct cgraph_node *n2;
    2142         4585 :                 int id = dfs->scc_no + 1;
    2143        10473 :                 for (n2 = node; n2;
    2144         5888 :                      n2 = ((struct ipa_dfs_info *) n2->aux)->next_cycle)
    2145         9171 :                   if (opt_for_fn (n2->decl, optimize))
    2146              :                     {
    2147         9163 :                       ipa_fn_summary *info2 = ipa_fn_summaries->get
    2148         9163 :                          (n2->inlined_to ? n2->inlined_to : n2);
    2149         9163 :                       if (info2->scc_no)
    2150              :                         break;
    2151         5880 :                       info2->scc_no = id;
    2152              :                     }
    2153              :               }
    2154              :           }
    2155              : 
    2156      4273605 :         for (edge = node->callers; edge; edge = edge->next_caller)
    2157      2389963 :           if (edge->count.ipa ().initialized_p ()
    2158      2509228 :               && edge->count.ipa ().nonzero_p ())
    2159          400 :           has_nonzero_ipa_profile = true;
    2160              :       }
    2161       230059 :   ipa_free_postorder_info ();
    2162       230059 :   initialize_growth_caches ();
    2163              : 
    2164       230059 :   if (dump_file)
    2165          178 :     fprintf (dump_file,
    2166              :              "\nDeciding on inlining of small functions.  Starting with size %i.\n",
    2167              :              initial_size);
    2168              : 
    2169       230059 :   overall_size = initial_size;
    2170       230059 :   min_size = overall_size;
    2171              : 
    2172              :   /* Populate the heap with all edges we might inline.  */
    2173              : 
    2174      2113732 :   FOR_EACH_DEFINED_FUNCTION (node)
    2175              :     {
    2176      1883673 :       bool update = false;
    2177      1883673 :       struct cgraph_edge *next = NULL;
    2178      1883673 :       bool has_speculative = false;
    2179              : 
    2180      1883673 :       if (!opt_for_fn (node->decl, optimize)
    2181              :           /* With -Og we do not want to perform IPA inlining of small
    2182              :              functions since there are no scalar cleanups after it
    2183              :              that would realize the anticipated win.  All abstraction
    2184              :              is removed during early inlining.  */
    2185      1883673 :           || opt_for_fn (node->decl, optimize_debug))
    2186       455086 :         continue;
    2187              : 
    2188      1428587 :       if (dump_file)
    2189          807 :         fprintf (dump_file, "Enqueueing calls in %s.\n", node->dump_name ());
    2190              : 
    2191      7016693 :       for (edge = node->callees; edge; edge = edge->next_callee)
    2192              :         {
    2193      5588106 :           if (edge->inline_failed
    2194      5588075 :               && !edge->aux
    2195      5587952 :               && can_inline_edge_p (edge, true)
    2196      1545638 :               && want_inline_small_function_p (edge, true)
    2197       926295 :               && can_inline_edge_by_limits_p (edge, CAN_INLINE_REPORT)
    2198      6507057 :               && edge->inline_failed)
    2199              :             {
    2200       918951 :               gcc_assert (!edge->aux);
    2201       918951 :               update_edge_key (&edge_heap, edge);
    2202              :             }
    2203      5588106 :           if (edge->speculative)
    2204        17395 :             has_speculative = true;
    2205              :         }
    2206      1428587 :       if (has_speculative)
    2207        51910 :         for (edge = node->callees; edge; edge = next)
    2208              :           {
    2209        43911 :             next = edge->next_callee;
    2210        43911 :             if (edge->speculative
    2211        43911 :                 && !speculation_useful_p (edge, edge->aux != NULL))
    2212              :               {
    2213          449 :                 cgraph_edge::resolve_speculation (edge);
    2214          449 :                 update = true;
    2215              :               }
    2216              :           }
    2217         7999 :       if (update)
    2218              :         {
    2219            0 :           struct cgraph_node *where = node->inlined_to
    2220          375 :                                       ? node->inlined_to : node;
    2221          375 :           ipa_update_overall_fn_summary (where);
    2222          375 :           reset_edge_caches (where);
    2223          375 :           update_caller_keys (&edge_heap, where,
    2224              :                               updated_nodes, NULL);
    2225          375 :           update_callee_keys (&edge_heap, where, NULL,
    2226              :                               updated_nodes);
    2227          375 :           bitmap_clear (updated_nodes);
    2228              :         }
    2229              :     }
    2230              : 
    2231       230059 :   gcc_assert (in_lto_p
    2232              :               || !has_nonzero_ipa_profile
    2233              :               || flag_auto_profile
    2234              :               || (profile_info && flag_branch_probabilities));
    2235              : 
    2236      2817576 :   while (!edge_heap.empty ())
    2237              :     {
    2238      2587517 :       int old_size = overall_size;
    2239      2587517 :       struct cgraph_node *where, *callee;
    2240      2587517 :       sreal badness = edge_heap.min_key ().badness;
    2241      2587517 :       sreal current_badness;
    2242      2587517 :       int growth;
    2243              : 
    2244      2587517 :       edge = edge_heap.extract_min ();
    2245      2587517 :       gcc_assert (edge->aux);
    2246      2587517 :       edge->aux = NULL;
    2247      2587517 :       if (!edge->inline_failed || !edge->callee->analyzed)
    2248      1724287 :         continue;
    2249              : 
    2250              :       /* Be sure that caches are maintained consistent.
    2251              :          This check is affected by scaling roundoff errors when compiling for
    2252              :          IPA this we skip it in that case.  */
    2253      2587427 :       if (flag_checking && !edge->callee->count.ipa_p ()
    2254      5006167 :           && !has_nonzero_ipa_profile)
    2255              :         {
    2256      2418737 :           sreal cached_badness = edge_badness (edge, false);
    2257              : 
    2258      2418737 :           int old_size_est = estimate_edge_size (edge);
    2259      2418737 :           sreal old_time_est = estimate_edge_time (edge);
    2260      2418737 :           int old_hints_est = estimate_edge_hints (edge);
    2261              : 
    2262      2418737 :           if (edge_growth_cache != NULL)
    2263      2418737 :             edge_growth_cache->remove (edge);
    2264      4325661 :           reset_node_cache (edge->caller->inlined_to
    2265              :                             ? edge->caller->inlined_to
    2266              :                             : edge->caller);
    2267      2418737 :           gcc_assert (old_size_est == estimate_edge_size (edge));
    2268      2418737 :           gcc_assert (old_time_est == estimate_edge_time (edge));
    2269              :           /* FIXME:
    2270              : 
    2271              :              gcc_assert (old_hints_est == estimate_edge_hints (edge));
    2272              : 
    2273              :              fails with profile feedback because some hints depends on
    2274              :              maybe_hot_edge_p predicate and because callee gets inlined to other
    2275              :              calls, the edge may become cold.
    2276              :              This ought to be fixed by computing relative probabilities
    2277              :              for given invocation but that will be better done once whole
    2278              :              code is converted to sreals.  Disable for now and revert to "wrong"
    2279              :              value so enable/disable checking paths agree.  */
    2280      2418737 :           edge_growth_cache->get (edge)->hints = old_hints_est + 1;
    2281              : 
    2282              :           /* When updating the edge costs, we only decrease badness in the keys.
    2283              :              Increases of badness are handled lazily; when we see key with out
    2284              :              of date value on it, we re-insert it now.  */
    2285      2418737 :           current_badness = edge_badness (edge, false);
    2286      2418737 :           gcc_assert (cached_badness == current_badness);
    2287      2418737 :           gcc_assert (current_badness >= badness);
    2288              :         }
    2289              :       else
    2290       168693 :         current_badness = edge_badness (edge, false);
    2291      2587430 :       if (current_badness != badness)
    2292              :         {
    2293      1800187 :           if (edge_heap.min () && current_badness > edge_heap.min_key ().badness)
    2294              :             {
    2295      1638796 :               inline_badness b (edge, current_badness);
    2296      1638796 :               edge->aux = edge_heap.insert (b, edge);
    2297      1638796 :               continue;
    2298      1638796 :             }
    2299              :           else
    2300       161391 :             badness = current_badness;
    2301              :         }
    2302              : 
    2303       948634 :       if (!can_inline_edge_p (edge, true)
    2304       948634 :           || !can_inline_edge_by_limits_p (edge, CAN_INLINE_REPORT))
    2305              :         {
    2306         4498 :           resolve_noninline_speculation (&edge_heap, edge);
    2307         4498 :           continue;
    2308              :         }
    2309              : 
    2310       944136 :       callee = edge->callee->ultimate_alias_target ();
    2311       944136 :       growth = estimate_edge_growth (edge);
    2312       944136 :       if (dump_file)
    2313              :         {
    2314          528 :           fprintf (dump_file,
    2315              :                    "\nConsidering %s with %i size\n",
    2316              :                    callee->dump_name (),
    2317          528 :                    ipa_size_summaries->get (callee)->size);
    2318         1056 :           fprintf (dump_file,
    2319              :                    " to be inlined into %s in %s:%i\n"
    2320              :                    " Estimated badness is %f, frequency %.2f.\n",
    2321          528 :                    edge->caller->dump_name (),
    2322          528 :                    edge->call_stmt
    2323          500 :                    && (LOCATION_LOCUS (gimple_location ((const gimple *)
    2324              :                                                         edge->call_stmt))
    2325              :                        > BUILTINS_LOCATION)
    2326          491 :                    ? gimple_filename ((const gimple *) edge->call_stmt)
    2327              :                    : "unknown",
    2328          528 :                    edge->call_stmt
    2329          500 :                    ? gimple_lineno ((const gimple *) edge->call_stmt)
    2330              :                    : -1,
    2331              :                    badness.to_double (),
    2332          528 :                    edge->sreal_frequency ().to_double ());
    2333          528 :           if (edge->count.ipa ().initialized_p ())
    2334              :             {
    2335            0 :               fprintf (dump_file, " Called ");
    2336            0 :               edge->count.ipa ().dump (dump_file);
    2337            0 :               fprintf (dump_file, " times\n");
    2338              :             }
    2339          528 :           if (dump_flags & TDF_DETAILS)
    2340          185 :             edge_badness (edge, true);
    2341              :         }
    2342              : 
    2343       944136 :       where = edge->caller;
    2344              : 
    2345       944136 :       if (overall_size + growth > compute_max_insns (where, min_size)
    2346       944136 :           && !DECL_DISREGARD_INLINE_LIMITS (callee->decl))
    2347              :         {
    2348        76420 :           edge->inline_failed = CIF_INLINE_UNIT_GROWTH_LIMIT;
    2349        76420 :           report_inline_failed_reason (edge);
    2350        76420 :           resolve_noninline_speculation (&edge_heap, edge);
    2351        76420 :           continue;
    2352              :         }
    2353              : 
    2354       867716 :       if (!want_inline_small_function_p (edge, true))
    2355              :         {
    2356         2161 :           resolve_noninline_speculation (&edge_heap, edge);
    2357         2161 :           continue;
    2358              :         }
    2359              : 
    2360       865555 :       profile_count old_count = callee->count;
    2361              : 
    2362              :       /* Heuristics for inlining small functions work poorly for
    2363              :          recursive calls where we do effects similar to loop unrolling.
    2364              :          When inlining such edge seems profitable, leave decision on
    2365              :          specific inliner.  */
    2366       865555 :       if (edge->recursive_p ())
    2367              :         {
    2368         1961 :           if (where->inlined_to)
    2369          559 :             where = where->inlined_to;
    2370              : 
    2371              :           /* Disable always_inline on self recursive functions.
    2372              :              This prevents some inlining bombs such as one in PR113291
    2373              :              from exploding.
    2374              :              It is not enough to stop inlining in self recursive always_inlines
    2375              :              since they may grow large enough so always inlining them even
    2376              :              with recursin depth 0 is too much.
    2377              : 
    2378              :              All sane uses of always_inline should be handled during
    2379              :              early optimizations.  */
    2380         1961 :           DECL_DISREGARD_INLINE_LIMITS (where->decl) = false;
    2381              : 
    2382         1961 :           if (!recursive_inlining (edge,
    2383         1961 :                                    opt_for_fn (edge->caller->decl,
    2384              :                                                flag_indirect_inlining)
    2385              :                                    ? &new_indirect_edges : NULL))
    2386              :             {
    2387          352 :               edge->inline_failed = CIF_RECURSIVE_INLINING;
    2388          352 :               resolve_noninline_speculation (&edge_heap, edge);
    2389          352 :               continue;
    2390              :             }
    2391         1609 :           reset_edge_caches (where);
    2392              :           /* Recursive inliner inlines all recursive calls of the function
    2393              :              at once. Consequently we need to update all callee keys.  */
    2394         1609 :           if (opt_for_fn (edge->caller->decl, flag_indirect_inlining))
    2395         1584 :             add_new_edges_to_heap (&edge_heap, new_indirect_edges);
    2396         1609 :           update_callee_keys (&edge_heap, where, where, updated_nodes);
    2397         1609 :           bitmap_clear (updated_nodes);
    2398              :         }
    2399              :       else
    2400              :         {
    2401       863594 :           struct cgraph_node *outer_node = NULL;
    2402       863594 :           int depth = 0;
    2403              : 
    2404              :           /* Consider the case where self recursive function A is inlined
    2405              :              into B.  This is desired optimization in some cases, since it
    2406              :              leads to effect similar of loop peeling and we might completely
    2407              :              optimize out the recursive call.  However we must be extra
    2408              :              selective.  */
    2409              : 
    2410       863594 :           where = edge->caller;
    2411      1281799 :           while (where->inlined_to)
    2412              :             {
    2413       418205 :               if (where->decl == callee->decl)
    2414        11121 :                 outer_node = where, depth++;
    2415       418205 :               where = where->callers->caller;
    2416              :             }
    2417       865567 :           if (outer_node
    2418       863594 :               && !want_inline_self_recursive_call_p (edge, outer_node,
    2419              :                                                      true, depth))
    2420              :             {
    2421         1973 :               edge->inline_failed
    2422         1973 :                 = (DECL_DISREGARD_INLINE_LIMITS (edge->callee->decl)
    2423         1973 :                    ? CIF_RECURSIVE_INLINING : CIF_UNSPECIFIED);
    2424         1973 :               resolve_noninline_speculation (&edge_heap, edge);
    2425         1973 :               continue;
    2426              :             }
    2427       861621 :           else if (depth && dump_file)
    2428            6 :             fprintf (dump_file, " Peeling recursion with depth %i\n", depth);
    2429              : 
    2430       861621 :           gcc_checking_assert (!callee->inlined_to);
    2431              : 
    2432       861621 :           int old_size = ipa_size_summaries->get (where)->size;
    2433       861621 :           sreal old_time = ipa_fn_summaries->get (where)->time;
    2434              : 
    2435       861621 :           inline_call (edge, true, &new_indirect_edges, &overall_size, true);
    2436       861621 :           reset_edge_caches (edge->callee);
    2437       861621 :           add_new_edges_to_heap (&edge_heap, new_indirect_edges);
    2438              : 
    2439              :           /* If caller's size and time increased we do not need to update
    2440              :              all edges because badness is not going to decrease.  */
    2441       861621 :           if (old_size <= ipa_size_summaries->get (where)->size
    2442       810329 :               && old_time <= ipa_fn_summaries->get (where)->time
    2443              :               /* Wrapper penalty may be non-monotonous in this respect.
    2444              :                  Fortunately it only affects small functions.  */
    2445      1430331 :               && !wrapper_heuristics_may_apply (where, old_size))
    2446       398657 :             update_callee_keys (&edge_heap, edge->callee, edge->callee,
    2447              :                                 updated_nodes);
    2448              :           else
    2449       462964 :             update_callee_keys (&edge_heap, where,
    2450              :                                 edge->callee,
    2451              :                                 updated_nodes);
    2452              :         }
    2453       863230 :       where = edge->caller;
    2454       863230 :       if (where->inlined_to)
    2455       218389 :         where = where->inlined_to;
    2456              : 
    2457              :       /* Our profitability metric can depend on local properties
    2458              :          such as number of inlinable calls and size of the function body.
    2459              :          After inlining these properties might change for the function we
    2460              :          inlined into (since it's body size changed) and for the functions
    2461              :          called by function we inlined (since number of it inlinable callers
    2462              :          might change).  */
    2463       863230 :       update_caller_keys (&edge_heap, where, updated_nodes, NULL);
    2464              :       /* Offline copy count has possibly changed, recompute if profile is
    2465              :          available.  */
    2466       863230 :       struct cgraph_node *n
    2467       863230 :               = cgraph_node::get (edge->callee->decl)->ultimate_alias_target ();
    2468       581268 :       if (n != edge->callee && n->analyzed && !(n->count == old_count)
    2469       863287 :           && n->count.ipa_p ())
    2470           57 :         update_callee_keys (&edge_heap, n, NULL, updated_nodes);
    2471       863230 :       bitmap_clear (updated_nodes);
    2472              : 
    2473       863230 :       if (dump_enabled_p ())
    2474              :         {
    2475          537 :           ipa_fn_summary *s = ipa_fn_summaries->get (where);
    2476              : 
    2477              :           /* dump_printf can't handle %+i.  */
    2478          537 :           char buf_net_change[100];
    2479          537 :           snprintf (buf_net_change, sizeof buf_net_change, "%+i",
    2480              :                     overall_size - old_size);
    2481              : 
    2482         1074 :           dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, edge->call_stmt,
    2483              :                            " Inlined %C into %C which now has time %f and "
    2484              :                            "size %i, net change of %s%s.\n",
    2485              :                            edge->callee, edge->caller,
    2486              :                            s->time.to_double (),
    2487          537 :                            ipa_size_summaries->get (edge->caller)->size,
    2488              :                            buf_net_change,
    2489          537 :                            cross_module_call_p (edge)
    2490              :                            ? " (cross module)" : "");
    2491              :         }
    2492       863230 :       if (min_size > overall_size)
    2493              :         {
    2494       215309 :           min_size = overall_size;
    2495              : 
    2496       215309 :           if (dump_file)
    2497          401 :             fprintf (dump_file, "New minimal size reached: %i\n", min_size);
    2498              :         }
    2499              :     }
    2500              : 
    2501       230059 :   free_growth_caches ();
    2502       230059 :   if (dump_enabled_p ())
    2503          436 :     dump_printf (MSG_NOTE,
    2504              :                  "Unit growth for small function inlining: %i->%i (%i%%)\n",
    2505              :                  initial_size, overall_size,
    2506          194 :                  initial_size ? overall_size * 100 / (initial_size) - 100 : 0);
    2507       230059 :   symtab->remove_edge_removal_hook (edge_removal_hook_holder);
    2508       230059 : }
    2509              : 
    2510              : /* Flatten NODE.  Performed both during early inlining and
    2511              :    at IPA inlining time.  */
    2512              : 
    2513              : static void
    2514          713 : flatten_function (struct cgraph_node *node, bool early, bool update)
    2515              : {
    2516          713 :   struct cgraph_edge *e;
    2517              : 
    2518              :   /* We shouldn't be called recursively when we are being processed.  */
    2519          713 :   gcc_assert (node->aux == NULL);
    2520              : 
    2521          713 :   node->aux = (void *) node;
    2522              : 
    2523         1644 :   for (e = node->callees; e; e = e->next_callee)
    2524              :     {
    2525          931 :       struct cgraph_node *orig_callee;
    2526          931 :       struct cgraph_node *callee = e->callee->ultimate_alias_target ();
    2527              : 
    2528              :       /* We've hit cycle?  It is time to give up.  */
    2529          931 :       if (callee->aux)
    2530              :         {
    2531           15 :           if (dump_enabled_p ())
    2532            0 :             dump_printf_loc (MSG_MISSED_OPTIMIZATION, e->call_stmt,
    2533              :                              "Not inlining %C into %C to avoid cycle.\n",
    2534              :                              callee, e->caller);
    2535           15 :           if (cgraph_inline_failed_type (e->inline_failed) != CIF_FINAL_ERROR)
    2536           15 :             e->inline_failed = CIF_RECURSIVE_INLINING;
    2537           15 :           continue;
    2538              :         }
    2539              : 
    2540              :       /* When the edge is already inlined, we just need to recurse into
    2541              :          it in order to fully flatten the leaves.  */
    2542          916 :       if (!e->inline_failed)
    2543              :         {
    2544          350 :           flatten_function (callee, early, false);
    2545          350 :           continue;
    2546              :         }
    2547              : 
    2548              :       /* Flatten attribute needs to be processed during late inlining. For
    2549              :          extra code quality we however do flattening during early optimization,
    2550              :          too.  */
    2551          321 :       if (!early
    2552          566 :           ? !can_inline_edge_p (e, true)
    2553          245 :             && !can_inline_edge_by_limits_p (e, CAN_INLINE_REPORT)
    2554          321 :           : !can_early_inline_edge_p (e))
    2555          419 :         continue;
    2556              : 
    2557          147 :       if (e->recursive_p ())
    2558              :         {
    2559            0 :           if (dump_enabled_p ())
    2560            0 :             dump_printf_loc (MSG_MISSED_OPTIMIZATION, e->call_stmt,
    2561              :                              "Not inlining: recursive call.\n");
    2562            0 :           continue;
    2563              :         }
    2564              : 
    2565          147 :       if (gimple_in_ssa_p (DECL_STRUCT_FUNCTION (node->decl))
    2566          294 :           != gimple_in_ssa_p (DECL_STRUCT_FUNCTION (callee->decl)))
    2567              :         {
    2568            4 :           if (dump_enabled_p ())
    2569            4 :             dump_printf_loc (MSG_MISSED_OPTIMIZATION, e->call_stmt,
    2570              :                              "Not inlining: SSA form does not match.\n");
    2571            4 :           continue;
    2572              :         }
    2573              : 
    2574              :       /* Inline the edge and flatten the inline clone.  Avoid
    2575              :          recursing through the original node if the node was cloned.  */
    2576          143 :       if (dump_enabled_p ())
    2577            3 :         dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, e->call_stmt,
    2578              :                          " Inlining %C into %C.\n",
    2579              :                          callee, e->caller);
    2580          143 :       orig_callee = callee;
    2581          143 :       inline_call (e, true, NULL, NULL, false);
    2582          143 :       if (e->callee != orig_callee)
    2583          106 :         orig_callee->aux = (void *) node;
    2584          143 :       flatten_function (e->callee, early, false);
    2585          143 :       if (e->callee != orig_callee)
    2586          106 :         orig_callee->aux = NULL;
    2587              :     }
    2588              : 
    2589          713 :   node->aux = NULL;
    2590          713 :   cgraph_node *where = node->inlined_to ? node->inlined_to : node;
    2591          713 :   if (update && opt_for_fn (where->decl, optimize))
    2592          209 :     ipa_update_overall_fn_summary (where);
    2593          713 : }
    2594              : 
    2595              : /* Inline NODE to all callers.  Worker for cgraph_for_node_and_aliases.
    2596              :    DATA points to number of calls originally found so we avoid infinite
    2597              :    recursion.  */
    2598              : 
    2599              : static bool
    2600        29723 : inline_to_all_callers_1 (struct cgraph_node *node, void *data,
    2601              :                          hash_set<cgraph_node *> *callers)
    2602              : {
    2603        29723 :   int *num_calls = (int *)data;
    2604        29723 :   bool callee_removed = false;
    2605              : 
    2606        63191 :   while (node->callers && !node->inlined_to)
    2607              :     {
    2608        34631 :       struct cgraph_node *caller = node->callers->caller;
    2609              : 
    2610        34631 :       if (!can_inline_edge_p (node->callers, true)
    2611        34631 :           || !can_inline_edge_by_limits_p (node->callers, CAN_INLINE_REPORT)
    2612        69262 :           || node->callers->recursive_p ())
    2613              :         {
    2614            0 :           if (dump_file)
    2615            0 :             fprintf (dump_file, "Uninlinable call found; giving up.\n");
    2616            0 :           *num_calls = 0;
    2617            0 :           return false;
    2618              :         }
    2619              : 
    2620        34631 :       if (dump_file)
    2621              :         {
    2622            3 :           cgraph_node *ultimate = node->ultimate_alias_target ();
    2623            3 :           fprintf (dump_file,
    2624              :                    "\nInlining %s size %i.\n",
    2625              :                    ultimate->dump_name (),
    2626            3 :                    ipa_size_summaries->get (ultimate)->size);
    2627            3 :           fprintf (dump_file,
    2628              :                    " Called once from %s %i insns.\n",
    2629              :                    node->callers->caller->dump_name (),
    2630            3 :                    ipa_size_summaries->get (node->callers->caller)->size);
    2631              :         }
    2632              : 
    2633              :       /* Remember which callers we inlined to, delaying updating the
    2634              :          overall summary.  */
    2635        34631 :       callers->add (node->callers->caller);
    2636        34631 :       inline_call (node->callers, true, NULL, NULL, false, &callee_removed);
    2637        34631 :       if (dump_file)
    2638            3 :         fprintf (dump_file,
    2639              :                  " Inlined into %s which now has %i size\n",
    2640              :                  caller->dump_name (),
    2641            3 :                  ipa_size_summaries->get (caller)->size);
    2642        34631 :       if (!(*num_calls)--)
    2643              :         {
    2644            0 :           if (dump_file)
    2645            0 :             fprintf (dump_file, "New calls found; giving up.\n");
    2646            0 :           return callee_removed;
    2647              :         }
    2648        34631 :       if (callee_removed)
    2649              :         return true;
    2650              :     }
    2651              :   return false;
    2652              : }
    2653              : 
    2654              : /* Wrapper around inline_to_all_callers_1 doing delayed overall summary
    2655              :    update.  */
    2656              : 
    2657              : static bool
    2658        29723 : inline_to_all_callers (struct cgraph_node *node, void *data)
    2659              : {
    2660        29723 :   hash_set<cgraph_node *> callers;
    2661        29723 :   bool res = inline_to_all_callers_1 (node, data, &callers);
    2662              :   /* Perform the delayed update of the overall summary of all callers
    2663              :      processed.  This avoids quadratic behavior in the cases where
    2664              :      we have a lot of calls to the same function.  */
    2665        58469 :   for (hash_set<cgraph_node *>::iterator i = callers.begin ();
    2666        87215 :        i != callers.end (); ++i)
    2667        28746 :     ipa_update_overall_fn_summary ((*i)->inlined_to ? (*i)->inlined_to : *i);
    2668        29723 :   return res;
    2669        29723 : }
    2670              : 
    2671              : /* Output overall time estimate.  */
    2672              : static void
    2673          356 : dump_overall_stats (void)
    2674              : {
    2675          356 :   sreal sum_weighted = 0, sum = 0;
    2676          356 :   struct cgraph_node *node;
    2677              : 
    2678         2296 :   FOR_EACH_DEFINED_FUNCTION (node)
    2679         1940 :     if (!node->inlined_to
    2680         1383 :         && !node->alias)
    2681              :       {
    2682         1284 :         ipa_fn_summary *s = ipa_fn_summaries->get (node);
    2683         1284 :         if (s != NULL)
    2684              :           {
    2685         1180 :           sum += s->time;
    2686         1180 :           if (node->count.ipa ().initialized_p ())
    2687           14 :             sum_weighted += s->time * node->count.ipa ().to_gcov_type ();
    2688              :           }
    2689              :       }
    2690          356 :   fprintf (dump_file, "Overall time estimate: "
    2691              :            "%f weighted by profile: "
    2692              :            "%f\n", sum.to_double (), sum_weighted.to_double ());
    2693          356 : }
    2694              : 
    2695              : /* Output some useful stats about inlining.  */
    2696              : 
    2697              : static void
    2698          178 : dump_inline_stats (void)
    2699              : {
    2700          178 :   int64_t inlined_cnt = 0, inlined_indir_cnt = 0;
    2701          178 :   int64_t inlined_virt_cnt = 0, inlined_virt_indir_cnt = 0;
    2702          178 :   int64_t noninlined_cnt = 0, noninlined_indir_cnt = 0;
    2703          178 :   int64_t noninlined_virt_cnt = 0, noninlined_virt_indir_cnt = 0;
    2704          178 :   int64_t  inlined_speculative = 0, inlined_speculative_ply = 0;
    2705          178 :   int64_t indirect_poly_cnt = 0, indirect_cnt = 0;
    2706          178 :   int64_t reason[CIF_N_REASONS][2];
    2707         5874 :   sreal reason_freq[CIF_N_REASONS];
    2708          178 :   int i;
    2709          178 :   struct cgraph_node *node;
    2710              : 
    2711          178 :   memset (reason, 0, sizeof (reason));
    2712         5874 :   for (i=0; i < CIF_N_REASONS; i++)
    2713         5696 :     reason_freq[i] = 0;
    2714         1246 :   FOR_EACH_DEFINED_FUNCTION (node)
    2715              :   {
    2716         1068 :     struct cgraph_edge *e;
    2717         5962 :     for (e = node->callees; e; e = e->next_callee)
    2718              :       {
    2719         4894 :         if (e->inline_failed)
    2720              :           {
    2721         4340 :             if (e->count.ipa ().initialized_p ())
    2722         2611 :               reason[(int) e->inline_failed][0] += e->count.ipa ().to_gcov_type ();
    2723         4340 :             reason_freq[(int) e->inline_failed] += e->sreal_frequency ();
    2724         4340 :             reason[(int) e->inline_failed][1] ++;
    2725         4340 :             if (DECL_VIRTUAL_P (e->callee->decl)
    2726         4340 :                 && e->count.ipa ().initialized_p ())
    2727              :               {
    2728            0 :                 if (e->indirect_inlining_edge)
    2729            0 :                   noninlined_virt_indir_cnt += e->count.ipa ().to_gcov_type ();
    2730              :                 else
    2731            0 :                   noninlined_virt_cnt += e->count.ipa ().to_gcov_type ();
    2732              :               }
    2733         4340 :             else if (e->count.ipa ().initialized_p ())
    2734              :               {
    2735         2611 :                 if (e->indirect_inlining_edge)
    2736            0 :                   noninlined_indir_cnt += e->count.ipa ().to_gcov_type ();
    2737              :                 else
    2738         2611 :                   noninlined_cnt += e->count.ipa ().to_gcov_type ();
    2739              :               }
    2740              :           }
    2741          554 :         else if (e->count.ipa ().initialized_p ())
    2742              :           {
    2743            0 :             if (e->speculative)
    2744              :               {
    2745            0 :                 if (DECL_VIRTUAL_P (e->callee->decl))
    2746            0 :                   inlined_speculative_ply += e->count.ipa ().to_gcov_type ();
    2747              :                 else
    2748            0 :                   inlined_speculative += e->count.ipa ().to_gcov_type ();
    2749              :               }
    2750            0 :             else if (DECL_VIRTUAL_P (e->callee->decl))
    2751              :               {
    2752            0 :                 if (e->indirect_inlining_edge)
    2753            0 :                   inlined_virt_indir_cnt += e->count.ipa ().to_gcov_type ();
    2754              :                 else
    2755            0 :                   inlined_virt_cnt += e->count.ipa ().to_gcov_type ();
    2756              :               }
    2757              :             else
    2758              :               {
    2759            0 :                 if (e->indirect_inlining_edge)
    2760            0 :                   inlined_indir_cnt += e->count.ipa ().to_gcov_type ();
    2761              :                 else
    2762            0 :                   inlined_cnt += e->count.ipa ().to_gcov_type ();
    2763              :               }
    2764              :           }
    2765              :       }
    2766         1167 :     for (e = node->indirect_calls; e; e = e->next_callee)
    2767          198 :       if (is_a <cgraph_polymorphic_indirect_info *> (e->indirect_info)
    2768           99 :           & e->count.ipa ().initialized_p ())
    2769            0 :         indirect_poly_cnt += e->count.ipa ().to_gcov_type ();
    2770           99 :       else if (e->count.ipa ().initialized_p ())
    2771            0 :         indirect_cnt += e->count.ipa ().to_gcov_type ();
    2772              :   }
    2773          178 :   if (has_nonzero_ipa_profile)
    2774              :     {
    2775            0 :       fprintf (dump_file,
    2776              :                "Inlined %" PRId64 " + speculative "
    2777              :                "%" PRId64 " + speculative polymorphic "
    2778              :                "%" PRId64 " + previously indirect "
    2779              :                "%" PRId64 " + virtual "
    2780              :                "%" PRId64 " + virtual and previously indirect "
    2781              :                "%" PRId64 "\n" "Not inlined "
    2782              :                "%" PRId64 " + previously indirect "
    2783              :                "%" PRId64 " + virtual "
    2784              :                "%" PRId64 " + virtual and previously indirect "
    2785              :                "%" PRId64 " + still indirect "
    2786              :                "%" PRId64 " + still indirect polymorphic "
    2787              :                "%" PRId64 "\n", inlined_cnt,
    2788              :                inlined_speculative, inlined_speculative_ply,
    2789              :                inlined_indir_cnt, inlined_virt_cnt, inlined_virt_indir_cnt,
    2790              :                noninlined_cnt, noninlined_indir_cnt, noninlined_virt_cnt,
    2791              :                noninlined_virt_indir_cnt, indirect_cnt, indirect_poly_cnt);
    2792            0 :       fprintf (dump_file, "Removed speculations ");
    2793            0 :       spec_rem.dump (dump_file);
    2794            0 :       fprintf (dump_file, "\n");
    2795              :     }
    2796          178 :   dump_overall_stats ();
    2797          178 :   fprintf (dump_file, "\nWhy inlining failed?\n");
    2798         6052 :   for (i = 0; i < CIF_N_REASONS; i++)
    2799         5696 :     if (reason[i][1])
    2800          149 :       fprintf (dump_file, "%-50s: %8i calls, %8f freq, %" PRId64" count\n",
    2801              :                cgraph_inline_failed_string ((cgraph_inline_failed_t) i),
    2802              :                (int) reason[i][1], reason_freq[i].to_double (), reason[i][0]);
    2803          178 : }
    2804              : 
    2805              : /* Called when node is removed.  */
    2806              : 
    2807              : static void
    2808            0 : flatten_remove_node_hook (struct cgraph_node *node, void *data)
    2809              : {
    2810            0 :   if (lookup_attribute ("flatten", DECL_ATTRIBUTES (node->decl)) == NULL)
    2811              :     return;
    2812              : 
    2813            0 :   hash_set<struct cgraph_node *> *removed
    2814              :     = (hash_set<struct cgraph_node *> *) data;
    2815            0 :   removed->add (node);
    2816              : }
    2817              : 
    2818              : /* Decide on the inlining.  We do so in the topological order to avoid
    2819              :    expenses on updating data structures.  */
    2820              : 
    2821              : static unsigned int
    2822       230059 : ipa_inline (void)
    2823              : {
    2824       230059 :   struct cgraph_node *node;
    2825       230059 :   int nnodes;
    2826       230059 :   struct cgraph_node **order;
    2827       230059 :   int i, j;
    2828       230059 :   int cold;
    2829       230059 :   bool remove_functions = false;
    2830              : 
    2831       230059 :   order = XCNEWVEC (struct cgraph_node *, symtab->cgraph_count);
    2832              : 
    2833       230059 :   if (dump_file)
    2834          178 :     ipa_dump_fn_summaries (dump_file);
    2835              : 
    2836       230059 :   nnodes = ipa_reverse_postorder (order);
    2837       230059 :   spec_rem = profile_count::zero ();
    2838              : 
    2839      3881171 :   FOR_EACH_FUNCTION (node)
    2840              :     {
    2841      3651112 :       node->aux = 0;
    2842              : 
    2843              :       /* Recompute the default reasons for inlining because they may have
    2844              :          changed during merging.  */
    2845      3651112 :       if (in_lto_p)
    2846              :         {
    2847       435886 :           for (cgraph_edge *e = node->callees; e; e = e->next_callee)
    2848              :             {
    2849       330484 :               gcc_assert (e->inline_failed);
    2850       330484 :               initialize_inline_failed (e);
    2851              :             }
    2852       106664 :           for (cgraph_edge *e = node->indirect_calls; e; e = e->next_callee)
    2853         1262 :             initialize_inline_failed (e);
    2854              :         }
    2855              :     }
    2856              : 
    2857       230059 :   if (dump_file)
    2858          178 :     fprintf (dump_file, "\nFlattening functions:\n");
    2859              : 
    2860              :   /* First shrink order array, so that it only contains nodes with
    2861              :      flatten attribute.  */
    2862      3881171 :   for (i = nnodes - 1, j = i; i >= 0; i--)
    2863              :     {
    2864      3651112 :       node = order[i];
    2865      3651112 :       if (node->definition
    2866              :           /* Do not try to flatten aliases.  These may happen for example when
    2867              :              creating local aliases.  */
    2868      1883655 :           && !node->alias
    2869      5435779 :           && lookup_attribute ("flatten",
    2870      1784667 :                                DECL_ATTRIBUTES (node->decl)) != NULL)
    2871           85 :         order[j--] = order[i];
    2872              :     }
    2873              : 
    2874              :   /* After the above loop, order[j + 1] ... order[nnodes - 1] contain
    2875              :      nodes with flatten attribute.  If there is more than one such
    2876              :      node, we need to register a node removal hook, as flatten_function
    2877              :      could remove other nodes with flatten attribute.  See PR82801.  */
    2878       230059 :   struct cgraph_node_hook_list *node_removal_hook_holder = NULL;
    2879       230059 :   hash_set<struct cgraph_node *> *flatten_removed_nodes = NULL;
    2880       230059 :   if (j < nnodes - 2)
    2881              :     {
    2882           15 :       flatten_removed_nodes = new hash_set<struct cgraph_node *>;
    2883           15 :       node_removal_hook_holder
    2884           15 :         = symtab->add_cgraph_removal_hook (&flatten_remove_node_hook,
    2885              :                                            flatten_removed_nodes);
    2886              :     }
    2887              : 
    2888              :   /* In the first pass handle functions to be flattened.  Do this with
    2889              :      a priority so none of our later choices will make this impossible.  */
    2890       230144 :   for (i = nnodes - 1; i > j; i--)
    2891              :     {
    2892           85 :       node = order[i];
    2893           85 :       if (flatten_removed_nodes
    2894           85 :           && flatten_removed_nodes->contains (node))
    2895            0 :         continue;
    2896              : 
    2897              :       /* Handle nodes to be flattened.
    2898              :          Ideally when processing callees we stop inlining at the
    2899              :          entry of cycles, possibly cloning that entry point and
    2900              :          try to flatten itself turning it into a self-recursive
    2901              :          function.  */
    2902           85 :       if (dump_file)
    2903            4 :         fprintf (dump_file, "Flattening %s\n", node->dump_name ());
    2904           85 :       flatten_function (node, false, true);
    2905              :     }
    2906              : 
    2907       230059 :   if (j < nnodes - 2)
    2908              :     {
    2909           15 :       symtab->remove_cgraph_removal_hook (node_removal_hook_holder);
    2910           30 :       delete flatten_removed_nodes;
    2911              :     }
    2912       230059 :   free (order);
    2913              : 
    2914       230059 :   if (dump_file)
    2915          178 :     dump_overall_stats ();
    2916              : 
    2917       230059 :   inline_small_functions ();
    2918              : 
    2919       230059 :   gcc_assert (symtab->state == IPA_SSA);
    2920       230059 :   symtab->state = IPA_SSA_AFTER_INLINING;
    2921              :   /* Do first after-inlining removal.  We want to remove all "stale" extern
    2922              :      inline functions and virtual functions so we really know what is called
    2923              :      once.  */
    2924       230059 :   symtab->remove_unreachable_nodes (dump_file);
    2925              : 
    2926              :   /* Inline functions with a property that after inlining into all callers the
    2927              :      code size will shrink because the out-of-line copy is eliminated.
    2928              :      We do this regardless on the callee size as long as function growth limits
    2929              :      are met.  */
    2930       230059 :   if (dump_file)
    2931          178 :     fprintf (dump_file,
    2932              :              "\nDeciding on functions to be inlined into all callers and "
    2933              :              "removing useless speculations:\n");
    2934              : 
    2935              :   /* Inlining one function called once has good chance of preventing
    2936              :      inlining other function into the same callee.  Ideally we should
    2937              :      work in priority order, but probably inlining hot functions first
    2938              :      is good cut without the extra pain of maintaining the queue.
    2939              : 
    2940              :      ??? this is not really fitting the bill perfectly: inlining function
    2941              :      into callee often leads to better optimization of callee due to
    2942              :      increased context for optimization.
    2943              :      For example if main() function calls a function that outputs help
    2944              :      and then function that does the main optimization, we should inline
    2945              :      the second with priority even if both calls are cold by themselves.
    2946              : 
    2947              :      We probably want to implement new predicate replacing our use of
    2948              :      maybe_hot_edge interpreted as maybe_hot_edge || callee is known
    2949              :      to be hot.  */
    2950       690177 :   for (cold = 0; cold <= 1; cold ++)
    2951              :     {
    2952      6152330 :       FOR_EACH_DEFINED_FUNCTION (node)
    2953              :         {
    2954      5692212 :           struct cgraph_edge *edge, *next;
    2955      5692212 :           bool update=false;
    2956              : 
    2957      5692212 :           if (!opt_for_fn (node->decl, optimize)
    2958      5692212 :               || !opt_for_fn (node->decl, flag_inline_functions_called_once))
    2959       910084 :             continue;
    2960              : 
    2961     19409465 :           for (edge = node->callees; edge; edge = next)
    2962              :             {
    2963     14627337 :               next = edge->next_callee;
    2964     14627337 :               if (edge->speculative && !speculation_useful_p (edge, false))
    2965              :                 {
    2966         2267 :                   if (edge->count.ipa ().initialized_p ())
    2967            0 :                     spec_rem += edge->count.ipa ();
    2968         2267 :                   cgraph_edge::resolve_speculation (edge);
    2969         2267 :                   update = true;
    2970         2267 :                   remove_functions = true;
    2971              :                 }
    2972              :             }
    2973      4782128 :           if (update)
    2974              :             {
    2975          120 :               struct cgraph_node *where = node->inlined_to
    2976         1286 :                                           ? node->inlined_to : node;
    2977         1286 :               reset_edge_caches (where);
    2978         1286 :               ipa_update_overall_fn_summary (where);
    2979              :             }
    2980      4782128 :           if (want_inline_function_to_all_callers_p (node, cold))
    2981              :             {
    2982        26164 :               int num_calls = 0;
    2983        26164 :               node->call_for_symbol_and_aliases (sum_callers, &num_calls,
    2984              :                                                  true);
    2985        26164 :               while (node->call_for_symbol_and_aliases
    2986        27327 :                        (inline_to_all_callers, &num_calls, true))
    2987              :                 ;
    2988        26164 :               remove_functions = true;
    2989              :             }
    2990              :         }
    2991              :     }
    2992              : 
    2993       230059 :   if (dump_enabled_p ())
    2994          242 :     dump_printf (MSG_NOTE,
    2995              :                  "\nInlined %i calls, eliminated %i functions\n\n",
    2996              :                  ncalls_inlined, nfunctions_inlined);
    2997       230059 :   if (dump_file)
    2998          178 :     dump_inline_stats ();
    2999              : 
    3000       230059 :   if (dump_file)
    3001          178 :     ipa_dump_fn_summaries (dump_file);
    3002       230059 :   return remove_functions ? TODO_remove_functions : 0;
    3003              : }
    3004              : 
    3005              : /* Inline always-inline function calls in NODE
    3006              :    (which itself is possibly inline).  */
    3007              : 
    3008              : static bool
    3009      3400410 : inline_always_inline_functions (struct cgraph_node *node)
    3010              : {
    3011      3400410 :   struct cgraph_edge *e;
    3012      3400410 :   bool inlined = false;
    3013              : 
    3014     13218181 :   for (e = node->callees; e; e = e->next_callee)
    3015              :     {
    3016      9817771 :       struct cgraph_node *callee = e->callee->ultimate_alias_target ();
    3017      9817771 :       gcc_checking_assert (!callee->aux || callee->aux == (void *)(size_t)1);
    3018      9817771 :       if (!DECL_DISREGARD_INLINE_LIMITS (callee->decl)
    3019              :           /* Watch for self-recursive cycles.  */
    3020      9817771 :           || callee->aux)
    3021      9265535 :         continue;
    3022              : 
    3023       552236 :       if (e->recursive_p ())
    3024              :         {
    3025            6 :           if (dump_enabled_p ())
    3026            0 :             dump_printf_loc (MSG_MISSED_OPTIMIZATION, e->call_stmt,
    3027              :                              "  Not inlining recursive call to %C.\n",
    3028              :                              e->callee);
    3029            6 :           e->inline_failed = CIF_RECURSIVE_INLINING;
    3030            6 :           continue;
    3031              :         }
    3032       552230 :       if (callee->definition
    3033       552135 :           && !ipa_fn_summaries->get (callee))
    3034          221 :         compute_fn_summary (callee, true);
    3035              : 
    3036       552230 :       if (!can_early_inline_edge_p (e))
    3037              :         {
    3038              :           /* Set inlined to true if the callee is marked "always_inline" but
    3039              :              is not inlinable.  This will allow flagging an error later in
    3040              :              expand_call_inline in tree-inline.cc.  */
    3041          137 :           if (lookup_attribute ("always_inline",
    3042          137 :                                  DECL_ATTRIBUTES (callee->decl)) != NULL)
    3043           28 :             inlined = true;
    3044          137 :           continue;
    3045              :         }
    3046              : 
    3047       552093 :       if (dump_enabled_p ())
    3048           18 :         dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, e->call_stmt,
    3049              :                          "  Inlining %C into %C (always_inline).\n",
    3050              :                          e->callee, e->caller);
    3051       552093 :       inline_call (e, true, NULL, NULL, false);
    3052       552093 :       callee->aux = (void *)(size_t)1;
    3053              :       /* Inline recursively to handle the case where always_inline function was
    3054              :          not optimized yet since it is a part of a cycle in callgraph.  */
    3055       552093 :       inline_always_inline_functions (e->callee);
    3056       552093 :       callee->aux = NULL;
    3057       552093 :       inlined = true;
    3058              :     }
    3059      3400410 :   return inlined;
    3060              : }
    3061              : 
    3062              : /* Decide on the inlining.  We do so in the topological order to avoid
    3063              :    expenses on updating data structures.  */
    3064              : 
    3065              : static bool
    3066      2379346 : early_inline_small_functions (struct cgraph_node *node)
    3067              : {
    3068      2379346 :   struct cgraph_edge *e;
    3069      2379346 :   bool inlined = false;
    3070              : 
    3071     10199812 :   for (e = node->callees; e; e = e->next_callee)
    3072              :     {
    3073      7820466 :       struct cgraph_node *callee = e->callee->ultimate_alias_target ();
    3074              : 
    3075              :       /* We can encounter not-yet-analyzed function during
    3076              :          early inlining on callgraphs with strongly
    3077              :          connected components.  */
    3078      7820466 :       ipa_fn_summary *s = ipa_fn_summaries->get (callee);
    3079      7820466 :       if (s == NULL || !s->inlinable || !e->inline_failed)
    3080      4188893 :         continue;
    3081              : 
    3082              :       /* Do not consider functions not declared inline.  */
    3083      3631573 :       if (!DECL_DECLARED_INLINE_P (callee->decl)
    3084       859981 :           && !opt_for_fn (node->decl, flag_inline_small_functions)
    3085      3683805 :           && !opt_for_fn (node->decl, flag_inline_functions))
    3086        52167 :         continue;
    3087              : 
    3088      3579406 :       if (dump_enabled_p ())
    3089          155 :         dump_printf_loc (MSG_NOTE, e->call_stmt,
    3090              :                          "Considering inline candidate %C.\n",
    3091              :                          callee);
    3092              : 
    3093      3579406 :       if (!can_early_inline_edge_p (e))
    3094        88255 :         continue;
    3095              : 
    3096      3491151 :       if (e->recursive_p ())
    3097              :         {
    3098         8517 :           if (dump_enabled_p ())
    3099            0 :             dump_printf_loc (MSG_MISSED_OPTIMIZATION, e->call_stmt,
    3100              :                              "  Not inlining: recursive call.\n");
    3101         8517 :           continue;
    3102              :         }
    3103              : 
    3104      3482634 :       if (!want_early_inline_function_p (e))
    3105      1042778 :         continue;
    3106              : 
    3107      2439856 :       if (dump_enabled_p ())
    3108          102 :         dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, e->call_stmt,
    3109              :                          " Inlining %C into %C.\n",
    3110              :                          callee, e->caller);
    3111      2439856 :       inline_call (e, true, NULL, NULL, false);
    3112      2439856 :       inlined = true;
    3113              :     }
    3114              : 
    3115      2379346 :   if (inlined)
    3116       824752 :     ipa_update_overall_fn_summary (node);
    3117              : 
    3118      2379346 :   return inlined;
    3119              : }
    3120              : 
    3121              : /* With auto-fdo inline all functions that was inlined in the train run
    3122              :    and inlining seems useful.  That is there are enough samples in the callee
    3123              :    function.
    3124              : 
    3125              :    Unlike early inlining, we inline recursively.  Profile data is also used
    3126              :    to produce speculative calls which we then inline.  In the case some
    3127              :    speculatin was introduced, set SPECULATIVE_CALLS.  */
    3128              : 
    3129              : static bool
    3130      2380871 : inline_functions_by_afdo (struct cgraph_node *node, bool *speculative_calls)
    3131              : {
    3132      2380871 :   if (!flag_auto_profile || !flag_auto_profile_inlining)
    3133              :     return false;
    3134            0 :   struct cgraph_edge *e;
    3135            0 :   bool inlined = false;
    3136              : 
    3137            0 :   *speculative_calls |= afdo_vpt_for_early_inline (node);
    3138              : 
    3139            0 :   cgraph_edge *next;
    3140            0 :   for (e = node->callees; e; e = next)
    3141              :     {
    3142            0 :       next = e->next_callee;
    3143              : 
    3144            0 :       if (!e->inline_failed)
    3145              :         {
    3146            0 :           inlined |= inline_functions_by_afdo (e->callee, speculative_calls);
    3147            0 :           continue;
    3148              :         }
    3149            0 :       if (!afdo_callsite_hot_enough_for_early_inline (e))
    3150              :         {
    3151              :           /* If we do not want to inline, remove the speculation.  */
    3152            0 :           if (e->speculative)
    3153            0 :             cgraph_edge::resolve_speculation (e);
    3154            0 :           continue;
    3155              :         }
    3156              : 
    3157            0 :       struct cgraph_node *callee = e->callee->ultimate_alias_target ();
    3158            0 :       if (callee->definition
    3159            0 :           && !ipa_fn_summaries->get (callee))
    3160            0 :         compute_fn_summary (callee, true);
    3161              : 
    3162            0 :       if (!can_early_inline_edge_p (e))
    3163              :         {
    3164            0 :           if (dump_enabled_p ())
    3165            0 :             dump_printf_loc (MSG_MISSED_OPTIMIZATION, e->call_stmt,
    3166              :                              "Not inlining %C -> %C using auto-profile, %s.",
    3167              :                              e->caller, e->callee,
    3168              :                              cgraph_inline_failed_string (e->inline_failed));
    3169              :           /* If we do not want to inline, remove the speculation.  */
    3170            0 :           if (e->speculative)
    3171            0 :             cgraph_edge::resolve_speculation (e);
    3172            0 :           continue;
    3173              :         }
    3174              :       /* We can handle recursive inlining by first producing
    3175              :          inline clone.  */
    3176            0 :       if (e->recursive_p ())
    3177              :         {
    3178            0 :           if (dump_enabled_p ())
    3179            0 :             dump_printf_loc (MSG_MISSED_OPTIMIZATION, e->call_stmt,
    3180              :                              "Not inlining %C recursively"
    3181              :                              " using auto-profile.\n",
    3182              :                              e->callee);
    3183              :           /* If we do not want to inline, remove the speculation.  */
    3184            0 :           if (e->speculative)
    3185            0 :             cgraph_edge::resolve_speculation (e);
    3186            0 :           continue;
    3187              :         }
    3188              : 
    3189            0 :       if (dump_enabled_p ())
    3190              :         {
    3191            0 :           if (e->caller->inlined_to)
    3192            0 :             dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, e->call_stmt,
    3193              :                              "Inlining using auto-profile %C into %C "
    3194              :                              "which is transitively inlined to %C.\n",
    3195              :                              callee, e->caller, e->caller->inlined_to);
    3196              :           else
    3197            0 :             dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, e->call_stmt,
    3198              :                              "Inlining using auto-profile %C into %C.\n",
    3199              :                              callee, e->caller);
    3200              :         }
    3201            0 :       if (e->speculative)
    3202            0 :         remove_afdo_speculative_target (e);
    3203            0 :       inline_call (e, true, NULL, NULL, false);
    3204            0 :       inlined |= inline_functions_by_afdo (e->callee, speculative_calls);
    3205            0 :       inlined = true;
    3206              :     }
    3207              : 
    3208            0 :   if (inlined && !node->inlined_to)
    3209            0 :     ipa_update_overall_fn_summary (node);
    3210              : 
    3211              :   return inlined;
    3212              : }
    3213              : 
    3214              : unsigned int
    3215      2848331 : early_inliner (function *fun)
    3216              : {
    3217      2848331 :   struct cgraph_node *node = cgraph_node::get (current_function_decl);
    3218      2848331 :   struct cgraph_edge *edge;
    3219      2848331 :   unsigned int todo = 0;
    3220      2848331 :   int iterations = 0;
    3221      2848331 :   bool inlined = false;
    3222              : 
    3223      2848331 :   if (seen_error ())
    3224              :     return 0;
    3225              : 
    3226              :   /* Do nothing if datastructures for ipa-inliner are already computed.  This
    3227              :      happens when some pass decides to construct new function and
    3228              :      cgraph_add_new_function calls lowering passes and early optimization on
    3229              :      it.  This may confuse ourself when early inliner decide to inline call to
    3230              :      function clone, because function clones don't have parameter list in
    3231              :      ipa-prop matching their signature.  */
    3232      2848325 :   if (ipa_node_params_sum)
    3233              :     return 0;
    3234              : 
    3235      2848317 :   if (flag_checking)
    3236      2848287 :     node->verify ();
    3237      2848317 :   node->remove_all_references ();
    3238              : 
    3239              :   /* Even when not optimizing or not inlining inline always-inline
    3240              :      functions.  */
    3241      2848317 :   inlined = inline_always_inline_functions (node);
    3242              : 
    3243      2848317 :   if (!optimize
    3244      2412294 :       || flag_no_inline
    3245      2380912 :       || !flag_early_inlining)
    3246              :     ;
    3247      2379387 :   else if (lookup_attribute ("flatten",
    3248      2379387 :                              DECL_ATTRIBUTES (node->decl)) != NULL)
    3249              :     {
    3250              :       /* When the function is marked to be flattened, recursively inline
    3251              :          all calls in it.  */
    3252          135 :       if (dump_enabled_p ())
    3253            0 :         dump_printf (MSG_OPTIMIZED_LOCATIONS,
    3254              :                      "Flattening %C\n", node);
    3255          135 :       flatten_function (node, true, true);
    3256          135 :       inlined = true;
    3257              :     }
    3258              :   else
    3259              :     {
    3260              :       /* If some always_inline functions was inlined, apply the changes.
    3261              :          This way we will not account always inline into growth limits and
    3262              :          moreover we will inline calls from always inlines that we skipped
    3263              :          previously because of conditional in can_early_inline_edge_p
    3264              :          which prevents some inlining to always_inline.  */
    3265      2379252 :       if (inlined)
    3266              :         {
    3267       290981 :           timevar_push (TV_INTEGRATION);
    3268       290981 :           todo |= optimize_inline_calls (current_function_decl);
    3269              :           /* optimize_inline_calls call above might have introduced new
    3270              :              statements that don't have inline parameters computed.  */
    3271      1456179 :           for (edge = node->callees; edge; edge = edge->next_callee)
    3272              :             {
    3273              :               /* We can enounter not-yet-analyzed function during
    3274              :                  early inlining on callgraphs with strongly
    3275              :                  connected components.  */
    3276      1165198 :               ipa_call_summary *es = ipa_call_summaries->get_create (edge);
    3277      1165198 :               es->call_stmt_size
    3278      1165198 :                 = estimate_num_insns (edge->call_stmt, &eni_size_weights);
    3279      1165198 :               es->call_stmt_time
    3280      1165198 :                 = estimate_num_insns (edge->call_stmt, &eni_time_weights);
    3281              :             }
    3282       290981 :           ipa_update_overall_fn_summary (node);
    3283       290981 :           inlined = false;
    3284       290981 :           timevar_pop (TV_INTEGRATION);
    3285              :         }
    3286              :       /* We iterate incremental inlining to get trivial cases of indirect
    3287              :          inlining.  */
    3288      3204004 :       while (iterations < opt_for_fn (node->decl,
    3289              :                                       param_early_inliner_max_iterations))
    3290              :         {
    3291      2379346 :           bool inlined = early_inline_small_functions (node);
    3292      2379346 :           bool speculative_calls = false;
    3293      2379346 :           inlined |= inline_functions_by_afdo (node, &speculative_calls);
    3294      2379346 :           if (!inlined)
    3295              :             break;
    3296       824752 :           timevar_push (TV_INTEGRATION);
    3297       824752 :           if (speculative_calls)
    3298              :             {
    3299            0 :               cgraph_edge *next;
    3300            0 :               for (cgraph_edge *e = node->callees; e; e = next)
    3301              :                 {
    3302            0 :                   next = e->next_callee;
    3303            0 :                   cgraph_edge::redirect_call_stmt_to_callee (e);
    3304              :                 }
    3305              :             }
    3306       824752 :           todo |= optimize_inline_calls (current_function_decl);
    3307              : 
    3308              :           /* Technically we ought to recompute inline parameters so the new
    3309              :              iteration of early inliner works as expected.  We however have
    3310              :              values approximately right and thus we only need to update edge
    3311              :              info that might be cleared out for newly discovered edges.  */
    3312      3406874 :           for (edge = node->callees; edge; edge = edge->next_callee)
    3313              :             {
    3314              :               /* We have no summary for new bound store calls yet.  */
    3315      2582122 :               ipa_call_summary *es = ipa_call_summaries->get_create (edge);
    3316      2582122 :               es->call_stmt_size
    3317      2582122 :                 = estimate_num_insns (edge->call_stmt, &eni_size_weights);
    3318      2582122 :               es->call_stmt_time
    3319      2582122 :                 = estimate_num_insns (edge->call_stmt, &eni_time_weights);
    3320              :             }
    3321       824752 :           if (iterations < opt_for_fn (node->decl,
    3322       824752 :                                        param_early_inliner_max_iterations) - 1)
    3323           94 :             ipa_update_overall_fn_summary (node);
    3324       824752 :           timevar_pop (TV_INTEGRATION);
    3325       824752 :           iterations++;
    3326       824752 :           inlined = false;
    3327              :         }
    3328      2379252 :       if (dump_file)
    3329          203 :         fprintf (dump_file, "Iterations: %i\n", iterations);
    3330              :     }
    3331              : 
    3332              :   /* do AFDO inlining in case it was not done as part of early inlining.  */
    3333      2848317 :   if (optimize
    3334      2412294 :       && !flag_no_inline
    3335      2380912 :       && !flag_early_inlining
    3336         1525 :       && flag_auto_profile_inlining)
    3337              :     {
    3338         1525 :       bool speculative_calls = false;
    3339         1525 :       inlined |= inline_functions_by_afdo (node, &speculative_calls);
    3340         1525 :       if (speculative_calls)
    3341              :         {
    3342            0 :           cgraph_edge *next;
    3343            0 :           for (cgraph_edge *e = node->callees; e; e = next)
    3344              :             {
    3345            0 :               next = e->next_callee;
    3346            0 :               cgraph_edge::redirect_call_stmt_to_callee (e);
    3347              :             }
    3348              :         }
    3349              :     }
    3350              : 
    3351      2848317 :   if (inlined)
    3352              :     {
    3353        23182 :       timevar_push (TV_INTEGRATION);
    3354        23182 :       todo |= optimize_inline_calls (current_function_decl);
    3355        23182 :       timevar_pop (TV_INTEGRATION);
    3356              :     }
    3357              : 
    3358      2848317 :   fun->always_inline_functions_inlined = true;
    3359              : 
    3360      2848317 :   return todo;
    3361              : }
    3362              : 
    3363              : /* Do inlining of small functions.  Doing so early helps profiling and other
    3364              :    passes to be somewhat more effective and avoids some code duplication in
    3365              :    later real inlining pass for testcases with very many function calls.  */
    3366              : 
    3367              : namespace {
    3368              : 
    3369              : const pass_data pass_data_early_inline =
    3370              : {
    3371              :   GIMPLE_PASS, /* type */
    3372              :   "einline", /* name */
    3373              :   OPTGROUP_INLINE, /* optinfo_flags */
    3374              :   TV_EARLY_INLINING, /* tv_id */
    3375              :   PROP_ssa, /* properties_required */
    3376              :   0, /* properties_provided */
    3377              :   0, /* properties_destroyed */
    3378              :   0, /* todo_flags_start */
    3379              :   0, /* todo_flags_finish */
    3380              : };
    3381              : 
    3382              : class pass_early_inline : public gimple_opt_pass
    3383              : {
    3384              : public:
    3385       285722 :   pass_early_inline (gcc::context *ctxt)
    3386       571444 :     : gimple_opt_pass (pass_data_early_inline, ctxt)
    3387              :   {}
    3388              : 
    3389              :   /* opt_pass methods: */
    3390              :   unsigned int execute (function *) final override;
    3391              : 
    3392              : }; // class pass_early_inline
    3393              : 
    3394              : unsigned int
    3395      2848331 : pass_early_inline::execute (function *fun)
    3396              : {
    3397      2848331 :   return early_inliner (fun);
    3398              : }
    3399              : 
    3400              : } // anon namespace
    3401              : 
    3402              : gimple_opt_pass *
    3403       285722 : make_pass_early_inline (gcc::context *ctxt)
    3404              : {
    3405       285722 :   return new pass_early_inline (ctxt);
    3406              : }
    3407              : 
    3408              : namespace {
    3409              : 
    3410              : const pass_data pass_data_ipa_inline =
    3411              : {
    3412              :   IPA_PASS, /* type */
    3413              :   "inline", /* name */
    3414              :   OPTGROUP_INLINE, /* optinfo_flags */
    3415              :   TV_IPA_INLINING, /* tv_id */
    3416              :   0, /* properties_required */
    3417              :   0, /* properties_provided */
    3418              :   0, /* properties_destroyed */
    3419              :   0, /* todo_flags_start */
    3420              :   ( TODO_dump_symtab ), /* todo_flags_finish */
    3421              : };
    3422              : 
    3423              : class pass_ipa_inline : public ipa_opt_pass_d
    3424              : {
    3425              : public:
    3426       285722 :   pass_ipa_inline (gcc::context *ctxt)
    3427              :     : ipa_opt_pass_d (pass_data_ipa_inline, ctxt,
    3428              :                       NULL, /* generate_summary */
    3429              :                       NULL, /* write_summary */
    3430              :                       NULL, /* read_summary */
    3431              :                       NULL, /* write_optimization_summary */
    3432              :                       NULL, /* read_optimization_summary */
    3433              :                       NULL, /* stmt_fixup */
    3434              :                       0, /* function_transform_todo_flags_start */
    3435              :                       inline_transform, /* function_transform */
    3436       285722 :                       NULL) /* variable_transform */
    3437       285722 :   {}
    3438              : 
    3439              :   /* opt_pass methods: */
    3440       230059 :   unsigned int execute (function *) final override { return ipa_inline (); }
    3441              : 
    3442              : }; // class pass_ipa_inline
    3443              : 
    3444              : } // anon namespace
    3445              : 
    3446              : ipa_opt_pass_d *
    3447       285722 : make_pass_ipa_inline (gcc::context *ctxt)
    3448              : {
    3449       285722 :   return new pass_ipa_inline (ctxt);
    3450              : }
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.