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

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.