LCOV - code coverage report
Current view: top level - gcc - ipa-fnsummary.h (source / functions) Hit Total Coverage
Test: gcc.info Lines: 41 44 93.2 %
Date: 2020-03-28 11:57:23 Functions: 3 4 75.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /* IPA function body analysis.
       2                 :            :    Copyright (C) 2003-2020 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                 :            : #ifndef GCC_IPA_SUMMARY_H
      22                 :            : #define GCC_IPA_SUMMARY_H
      23                 :            : 
      24                 :            : #include "sreal.h"
      25                 :            : #include "ipa-predicate.h"
      26                 :            : 
      27                 :            : 
      28                 :            : /* Hints are reasons why IPA heuristics should prefer specializing given
      29                 :            :    function.  They are represented as bitmap of the following values.  */
      30                 :            : enum ipa_hints_vals {
      31                 :            :   /* When specialization turns indirect call into a direct call,
      32                 :            :      it is good idea to do so.  */
      33                 :            :   INLINE_HINT_indirect_call = 1,
      34                 :            :   /* Inlining may make loop iterations or loop stride known.  It is good idea
      35                 :            :      to do so because it enables loop optimizations.  */
      36                 :            :   INLINE_HINT_loop_iterations = 2,
      37                 :            :   INLINE_HINT_loop_stride = 4,
      38                 :            :   /* Inlining within same strongly connected component of callgraph is often
      39                 :            :      a loss due to increased stack frame usage and prologue setup costs.  */
      40                 :            :   INLINE_HINT_same_scc = 8,
      41                 :            :   /* Inlining functions in strongly connected component is not such a great
      42                 :            :      win.  */
      43                 :            :   INLINE_HINT_in_scc = 16,
      44                 :            :   /* If function is declared inline by user, it may be good idea to inline
      45                 :            :      it.  Set by simple_edge_hints in ipa-inline-analysis.c.  */
      46                 :            :   INLINE_HINT_declared_inline = 32,
      47                 :            :   /* Programs are usually still organized for non-LTO compilation and thus
      48                 :            :      if functions are in different modules, inlining may not be so important. 
      49                 :            :      Set by simple_edge_hints in ipa-inline-analysis.c.   */
      50                 :            :   INLINE_HINT_cross_module = 64,
      51                 :            :   /* We know that the callee is hot by profile.  */
      52                 :            :   INLINE_HINT_known_hot = 128
      53                 :            : };
      54                 :            : 
      55                 :            : typedef int ipa_hints;
      56                 :            : 
      57                 :            : /* Simple description of whether a memory load or a condition refers to a load
      58                 :            :    from an aggregate and if so, how and where from in the aggregate.
      59                 :            :    Individual fields have the same meaning like fields with the same name in
      60                 :            :    struct condition.  */
      61                 :            : 
      62                 :            : struct agg_position_info
      63                 :            : {
      64                 :            :   HOST_WIDE_INT offset;
      65                 :            :   bool agg_contents;
      66                 :            :   bool by_ref;
      67                 :            : };
      68                 :            : 
      69                 :            : /* Representation of function body size and time depending on the call
      70                 :            :    context.  We keep simple array of record, every containing of predicate
      71                 :            :    and time/size to account.  */
      72                 :   16116300 : class GTY(()) size_time_entry
      73                 :            : {
      74                 :            : public:
      75                 :            :   /* Predicate for code to be executed.  */
      76                 :            :   predicate exec_predicate;
      77                 :            :   /* Predicate for value to be constant and optimized out in a specialized copy.
      78                 :            :      When deciding on specialization this makes it possible to see how much
      79                 :            :      the executed code paths will simplify.  */
      80                 :            :   predicate nonconst_predicate;
      81                 :            :   int size;
      82                 :            :   sreal GTY((skip)) time;
      83                 :            : };
      84                 :            : 
      85                 :            : /* Summary about function and stack frame sizes.  We keep this info 
      86                 :            :    for inline clones and also for WPA streaming. For this reason this is not
      87                 :            :    part of ipa_fn_summary which exists only for offline functions.  */
      88                 :            : class ipa_size_summary
      89                 :            : {
      90                 :            : public:
      91                 :            :   /* Estimated stack frame consumption by the function.  */
      92                 :            :   HOST_WIDE_INT estimated_self_stack_size;
      93                 :            :   /* Size of the function body.  */
      94                 :            :   int self_size;
      95                 :            :   /* Estimated size of the function after inlining.  */
      96                 :            :   int size;
      97                 :            : 
      98                 :    4404140 :   ipa_size_summary ()
      99                 :    4404140 :   : estimated_self_stack_size (0), self_size (0), size (0)
     100                 :            :   {
     101                 :            :   }
     102                 :            : };
     103                 :            : 
     104                 :            : /* Function inlining information.  */
     105                 :            : class GTY(()) ipa_fn_summary
     106                 :            : {
     107                 :            : public:
     108                 :            :   /* Keep all field empty so summary dumping works during its computation.
     109                 :            :      This is useful for debugging.  */
     110                 :    6131040 :   ipa_fn_summary ()
     111                 :    6131040 :     : min_size (0),
     112                 :            :       inlinable (false), single_caller (false),
     113                 :            :       fp_expressions (false), estimated_stack_size (false),
     114                 :            :       time (0), conds (NULL),
     115                 :            :       size_time_table (NULL), call_size_time_table (NULL), loop_iterations (NULL),
     116                 :    6131040 :       loop_stride (NULL), growth (0), scc_no (0)
     117                 :            :   {
     118                 :    6131040 :   }
     119                 :            : 
     120                 :            :   /* Copy constructor.  */
     121                 :    1451390 :   ipa_fn_summary (const ipa_fn_summary &s)
     122                 :    1451390 :     : min_size (s.min_size),
     123                 :    1451390 :     inlinable (s.inlinable), single_caller (s.single_caller),
     124                 :    1451390 :     fp_expressions (s.fp_expressions),
     125                 :    1451390 :     estimated_stack_size (s.estimated_stack_size),
     126                 :    1451390 :     time (s.time), conds (s.conds), size_time_table (s.size_time_table),
     127                 :            :     call_size_time_table (NULL),
     128                 :    1451390 :     loop_iterations (s.loop_iterations), loop_stride (s.loop_stride),
     129                 :    1451390 :     growth (s.growth), scc_no (s.scc_no)
     130                 :            :   {}
     131                 :            : 
     132                 :            :   /* Default constructor.  */
     133                 :            :   ~ipa_fn_summary ();
     134                 :            : 
     135                 :            :   /* Information about the function body itself.  */
     136                 :            : 
     137                 :            :   /* Minimal size increase after inlining.  */
     138                 :            :   int min_size;
     139                 :            : 
     140                 :            :   /* False when there something makes inlining impossible (such as va_arg).  */
     141                 :            :   unsigned inlinable : 1;
     142                 :            :   /* True wen there is only one caller of the function before small function
     143                 :            :      inlining.  */
     144                 :            :   unsigned int single_caller : 1;
     145                 :            :   /* True if function contains any floating point expressions.  */
     146                 :            :   unsigned int fp_expressions : 1;
     147                 :            : 
     148                 :            :   /* Information about function that will result after applying all the
     149                 :            :      inline decisions present in the callgraph.  Generally kept up to
     150                 :            :      date only for functions that are not inline clones. */
     151                 :            : 
     152                 :            :   /* Estimated stack frame consumption by the function.  */
     153                 :            :   HOST_WIDE_INT estimated_stack_size;
     154                 :            :   /* Estimated runtime of function after inlining.  */
     155                 :            :   sreal GTY((skip)) time;
     156                 :            : 
     157                 :            :   /* Conditional size/time information.  The summaries are being
     158                 :            :      merged during inlining.  */
     159                 :            :   conditions conds;
     160                 :            :   /* Normal code is accounted in size_time_table, while calls are
     161                 :            :      accounted in call_size_time_table.  This is because calls
     162                 :            :      are often adjusted by IPA optimizations and thus this summary
     163                 :            :      is generated from call summary information when needed.  */
     164                 :            :   vec<size_time_entry, va_gc> *size_time_table;
     165                 :            :   vec<size_time_entry, va_gc> *call_size_time_table;
     166                 :            : 
     167                 :            :   /* Predicate on when some loop in the function becomes to have known
     168                 :            :      bounds.   */
     169                 :            :   predicate * GTY((skip)) loop_iterations;
     170                 :            :   /* Predicate on when some loop in the function becomes to have known
     171                 :            :      stride.   */
     172                 :            :   predicate * GTY((skip)) loop_stride;
     173                 :            :   /* Estimated growth for inlining all copies of the function before start
     174                 :            :      of small functions inlining.
     175                 :            :      This value will get out of date as the callers are duplicated, but
     176                 :            :      using up-to-date value in the badness metric mean a lot of extra
     177                 :            :      expenses.  */
     178                 :            :   int growth;
     179                 :            :   /* Number of SCC on the beginning of inlining process.  */
     180                 :            :   int scc_no;
     181                 :            : 
     182                 :            :   /* Record time and size under given predicates.  */
     183                 :            :   void account_size_time (int, sreal, const predicate &, const predicate &,
     184                 :            :                           bool call = false);
     185                 :            : 
     186                 :            :   /* We keep values scaled up, so fractional sizes can be accounted.  */
     187                 :            :   static const int size_scale = 2;
     188                 :            :   /* Maximal size of size_time_table before we start to be conservative.  */
     189                 :            :   static const int max_size_time_table_size = 256;
     190                 :            : };
     191                 :            : 
     192                 :            : class GTY((user)) ipa_fn_summary_t:
     193                 :            :   public fast_function_summary <ipa_fn_summary *, va_gc>
     194                 :            : {
     195                 :            : public:
     196                 :     323258 :   ipa_fn_summary_t (symbol_table *symtab):
     197                 :     323258 :     fast_function_summary <ipa_fn_summary *, va_gc> (symtab) {}
     198                 :            : 
     199                 :     323258 :   static ipa_fn_summary_t *create_ggc (symbol_table *symtab)
     200                 :            :   {
     201                 :     323258 :     class ipa_fn_summary_t *summary
     202                 :     323258 :       = new (ggc_alloc_no_dtor<ipa_fn_summary_t> ()) ipa_fn_summary_t (symtab);
     203                 :     323258 :     summary->disable_insertion_hook ();
     204                 :     323258 :     return summary;
     205                 :            :   }
     206                 :            : 
     207                 :            :   /* Remove ipa_fn_summary for all callees of NODE.  */
     208                 :            :   void remove_callees (cgraph_node *node);
     209                 :            : 
     210                 :            :   virtual void insert (cgraph_node *, ipa_fn_summary *);
     211                 :          0 :   virtual void remove (cgraph_node *node, ipa_fn_summary *)
     212                 :            :   {
     213                 :          0 :     remove_callees (node);
     214                 :          0 :   }
     215                 :            : 
     216                 :            :   virtual void duplicate (cgraph_node *src, cgraph_node *dst,
     217                 :            :                           ipa_fn_summary *src_data, ipa_fn_summary *dst_data);
     218                 :            : };
     219                 :            : 
     220                 :            : extern GTY(()) fast_function_summary <ipa_fn_summary *, va_gc>
     221                 :            :   *ipa_fn_summaries;
     222                 :            : 
     223                 :            : class ipa_size_summary_t:
     224                 :            :   public fast_function_summary <ipa_size_summary *, va_heap>
     225                 :            : {
     226                 :            : public:
     227                 :     323258 :   ipa_size_summary_t (symbol_table *symtab):
     228                 :     323258 :     fast_function_summary <ipa_size_summary *, va_heap> (symtab)
     229                 :            :   {
     230                 :     323258 :     disable_insertion_hook ();
     231                 :            :   }
     232                 :            : 
     233                 :    1584540 :   virtual void duplicate (cgraph_node *, cgraph_node *,
     234                 :            :                           ipa_size_summary *src_data,
     235                 :            :                           ipa_size_summary *dst_data)
     236                 :            :   {
     237                 :    1584540 :     *dst_data = *src_data;
     238                 :    1584540 :   }
     239                 :            : };
     240                 :            : extern fast_function_summary <ipa_size_summary *, va_heap>
     241                 :            :   *ipa_size_summaries;
     242                 :            : 
     243                 :            : /* Information kept about callgraph edges.  */
     244                 :            : class ipa_call_summary
     245                 :            : {
     246                 :            : public:
     247                 :            :   /* Keep all field empty so summary dumping works during its computation.
     248                 :            :      This is useful for debugging.  */
     249                 :   16320400 :   ipa_call_summary ()
     250                 :   16320400 :     : predicate (NULL), param (vNULL), call_stmt_size (0), call_stmt_time (0),
     251                 :   16320400 :       loop_depth (0), is_return_callee_uncaptured (false)
     252                 :            :     {
     253                 :            :     }
     254                 :            : 
     255                 :            :   /* Copy constructor.  */
     256                 :    1584080 :   ipa_call_summary (const ipa_call_summary &s):
     257                 :    1584080 :     predicate (s.predicate), param (s.param), call_stmt_size (s.call_stmt_size),
     258                 :    1584080 :     call_stmt_time (s.call_stmt_time), loop_depth (s.loop_depth),
     259                 :    1584080 :     is_return_callee_uncaptured (s.is_return_callee_uncaptured)
     260                 :            :   {
     261                 :            :   }
     262                 :            : 
     263                 :            :   /* Default destructor.  */
     264                 :            :   ~ipa_call_summary ();
     265                 :            : 
     266                 :            :   class predicate *predicate;
     267                 :            :   /* Vector indexed by parameters.  */
     268                 :            :   vec<inline_param_summary> param;
     269                 :            :   /* Estimated size and time of the call statement.  */
     270                 :            :   int call_stmt_size;
     271                 :            :   int call_stmt_time;
     272                 :            :   /* Depth of loop nest, 0 means no nesting.  */
     273                 :            :   unsigned int loop_depth;
     274                 :            :   /* Indicates whether the caller returns the value of it's callee.  */
     275                 :            :   bool is_return_callee_uncaptured;
     276                 :            : };
     277                 :            : 
     278                 :            : class ipa_call_summary_t: public fast_call_summary <ipa_call_summary *, va_heap>
     279                 :            : {
     280                 :            : public:
     281                 :     323258 :   ipa_call_summary_t (symbol_table *symtab):
     282                 :     323258 :     fast_call_summary <ipa_call_summary *, va_heap> (symtab) {}
     283                 :            : 
     284                 :            :   /* Hook that is called by summary when an edge is duplicated.  */
     285                 :            :   virtual void duplicate (cgraph_edge *src, cgraph_edge *dst,
     286                 :            :                           ipa_call_summary *src_data,
     287                 :            :                           ipa_call_summary *dst_data);
     288                 :            : };
     289                 :            : 
     290                 :            : /* This object describe a context of call.  That is a summary of known
     291                 :            :    information about its parameters.  Main purpose of this context is
     292                 :            :    to give more realistic estimations of function runtime, size and
     293                 :            :    inline hints.  */
     294                 :            : class ipa_call_context
     295                 :            : {
     296                 :            : public:
     297                 :            :   ipa_call_context (cgraph_node *node,
     298                 :            :                     clause_t possible_truths,
     299                 :            :                     clause_t nonspec_possible_truths,
     300                 :            :                     vec<tree> known_vals,
     301                 :            :                     vec<ipa_polymorphic_call_context> known_contexts,
     302                 :            :                     vec<ipa_agg_value_set> known_aggs,
     303                 :            :                     vec<inline_param_summary> m_inline_param_summary);
     304                 :     648521 :   ipa_call_context ()
     305                 :     648521 :   : m_node(NULL)
     306                 :            :   {
     307                 :            :   }
     308                 :            :   void estimate_size_and_time (int *ret_size, int *ret_min_size,
     309                 :            :                                sreal *ret_time,
     310                 :            :                                sreal *ret_nonspecialized_time,
     311                 :            :                                ipa_hints *ret_hints);
     312                 :            :   void duplicate_from (const ipa_call_context &ctx);
     313                 :            :   void release (bool all = false);
     314                 :            :   bool equal_to (const ipa_call_context &);
     315                 :     526534 :   bool exists_p ()
     316                 :            :   {
     317                 :     526534 :     return m_node != NULL;
     318                 :            :   }
     319                 :            : private:
     320                 :            :   /* Called function.  */
     321                 :            :   cgraph_node *m_node;
     322                 :            :   /* Clause describing what predicate conditionals can be satisfied
     323                 :            :      in this context if function is inlined/specialized.  */
     324                 :            :   clause_t m_possible_truths;
     325                 :            :   /* Clause describing what predicate conditionals can be satisfied
     326                 :            :      in this context if function is kept offline.  */
     327                 :            :   clause_t m_nonspec_possible_truths;
     328                 :            :   /* Inline summary maintains info about change probabilities.  */
     329                 :            :   vec<inline_param_summary> m_inline_param_summary;
     330                 :            : 
     331                 :            :   /* The following is used only to resolve indirect calls.  */
     332                 :            : 
     333                 :            :   /* Vector describing known values of parameters.  */
     334                 :            :   vec<tree> m_known_vals;
     335                 :            :   /* Vector describing known polymorphic call contexts.  */
     336                 :            :   vec<ipa_polymorphic_call_context> m_known_contexts;
     337                 :            :   /* Vector describing known aggregate values.  */
     338                 :            :   vec<ipa_agg_value_set> m_known_aggs;
     339                 :            : };
     340                 :            : 
     341                 :            : extern fast_call_summary <ipa_call_summary *, va_heap> *ipa_call_summaries;
     342                 :            : 
     343                 :            : /* In ipa-fnsummary.c  */
     344                 :            : void ipa_debug_fn_summary (struct cgraph_node *);
     345                 :            : void ipa_dump_fn_summaries (FILE *f);
     346                 :            : void ipa_dump_fn_summary (FILE *f, struct cgraph_node *node);
     347                 :            : void ipa_dump_hints (FILE *f, ipa_hints);
     348                 :            : void ipa_free_fn_summary (void);
     349                 :            : void ipa_free_size_summary (void);
     350                 :            : void inline_analyze_function (struct cgraph_node *node);
     351                 :            : void estimate_ipcp_clone_size_and_time (struct cgraph_node *,
     352                 :            :                                         vec<tree>,
     353                 :            :                                         vec<ipa_polymorphic_call_context>,
     354                 :            :                                         vec<ipa_agg_value_set>,
     355                 :            :                                         int *, sreal *, sreal *,
     356                 :            :                                         ipa_hints *);
     357                 :            : void ipa_merge_fn_summary_after_inlining (struct cgraph_edge *edge);
     358                 :            : void ipa_update_overall_fn_summary (struct cgraph_node *node, bool reset = true);
     359                 :            : void compute_fn_summary (struct cgraph_node *, bool);
     360                 :            : 
     361                 :            : 
     362                 :            : void evaluate_properties_for_edge (struct cgraph_edge *e,
     363                 :            :                                    bool inline_p,
     364                 :            :                                    clause_t *clause_ptr,
     365                 :            :                                    clause_t *nonspec_clause_ptr,
     366                 :            :                                    vec<tree> *known_vals_ptr,
     367                 :            :                                    vec<ipa_polymorphic_call_context>
     368                 :            :                                    *known_contexts_ptr,
     369                 :            :                                    vec<ipa_agg_value_set> *);
     370                 :            : 
     371                 :            : void ipa_fnsummary_c_finalize (void);
     372                 :            : HOST_WIDE_INT ipa_get_stack_frame_offset (struct cgraph_node *node);
     373                 :            : void ipa_remove_from_growth_caches (struct cgraph_edge *edge);
     374                 :            : 
     375                 :            : /* Return true if EDGE is a cross module call.  */
     376                 :            : 
     377                 :            : static inline bool
     378                 :            : cross_module_call_p (struct cgraph_edge *edge)
     379                 :            : {
     380                 :            :   /* Here we do not want to walk to alias target becuase ICF may create
     381                 :            :      cross-unit aliases.  */
     382                 :            :   if (edge->caller->unit_id == edge->callee->unit_id)
     383                 :            :     return false;
     384                 :            :   /* If the call is to a (former) comdat function or s symbol with mutiple
     385                 :            :      extern inline definitions then treat is as in-module call.  */
     386                 :            :   if (edge->callee->merged_extern_inline || edge->callee->merged_comdat
     387                 :            :       || DECL_COMDAT (edge->callee->decl))
     388                 :            :     return false;
     389                 :            :   return true;
     390                 :            : }
     391                 :            : 
     392                 :            : #endif /* GCC_IPA_FNSUMMARY_H */

Generated by: LCOV version 1.0

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 --enable-host-shared. GCC test suite is run with the built compiler.