LCOV - code coverage report
Current view: top level - gcc - ipa-pure-const.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 94.6 % 1082 1024
Test Date: 2025-03-22 13:13:03 Functions: 96.6 % 58 56
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Callgraph based analysis of static variables.
       2                 :             :    Copyright (C) 2004-2025 Free Software Foundation, Inc.
       3                 :             :    Contributed by Kenneth Zadeck <zadeck@naturalbridge.com>
       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                 :             : /* This file marks functions as being either const (TREE_READONLY) or
      22                 :             :    pure (DECL_PURE_P).  It can also set a variant of these that
      23                 :             :    are allowed to loop indefinitely (DECL_LOOPING_CONST_PURE_P).
      24                 :             : 
      25                 :             :    This must be run after inlining decisions have been made since
      26                 :             :    otherwise, the local sets will not contain information that is
      27                 :             :    consistent with post inlined state.  The global sets are not prone
      28                 :             :    to this problem since they are by definition transitive.  */
      29                 :             : 
      30                 :             : /* The code in this module is called by the ipa pass manager. It
      31                 :             :    should be one of the later passes since it's information is used by
      32                 :             :    the rest of the compilation. */
      33                 :             : 
      34                 :             : #include "config.h"
      35                 :             : #include "system.h"
      36                 :             : #include "coretypes.h"
      37                 :             : #include "backend.h"
      38                 :             : #include "target.h"
      39                 :             : #include "tree.h"
      40                 :             : #include "gimple.h"
      41                 :             : #include "tree-pass.h"
      42                 :             : #include "tree-streamer.h"
      43                 :             : #include "cgraph.h"
      44                 :             : #include "diagnostic.h"
      45                 :             : #include "calls.h"
      46                 :             : #include "cfganal.h"
      47                 :             : #include "tree-eh.h"
      48                 :             : #include "gimple-iterator.h"
      49                 :             : #include "gimple-walk.h"
      50                 :             : #include "tree-cfg.h"
      51                 :             : #include "tree-ssa-loop-niter.h"
      52                 :             : #include "langhooks.h"
      53                 :             : #include "ipa-utils.h"
      54                 :             : #include "gimple-pretty-print.h"
      55                 :             : #include "cfgloop.h"
      56                 :             : #include "tree-scalar-evolution.h"
      57                 :             : #include "intl.h"
      58                 :             : #include "opts.h"
      59                 :             : #include "ssa.h"
      60                 :             : #include "alloc-pool.h"
      61                 :             : #include "symbol-summary.h"
      62                 :             : #include "sreal.h"
      63                 :             : #include "ipa-cp.h"
      64                 :             : #include "ipa-prop.h"
      65                 :             : #include "ipa-fnsummary.h"
      66                 :             : #include "symtab-thunks.h"
      67                 :             : #include "dbgcnt.h"
      68                 :             : #include "gcc-urlifier.h"
      69                 :             : 
      70                 :             : /* Lattice values for const and pure functions.  Everything starts out
      71                 :             :    being const, then may drop to pure and then neither depending on
      72                 :             :    what is found.  */
      73                 :             : enum pure_const_state_e
      74                 :             : {
      75                 :             :   IPA_CONST,
      76                 :             :   IPA_PURE,
      77                 :             :   IPA_NEITHER
      78                 :             : };
      79                 :             : 
      80                 :             : static const char *pure_const_names[3] = {"const", "pure", "neither"};
      81                 :             : 
      82                 :             : enum malloc_state_e
      83                 :             : {
      84                 :             :   STATE_MALLOC_TOP,
      85                 :             :   STATE_MALLOC,
      86                 :             :   STATE_MALLOC_BOTTOM
      87                 :             : };
      88                 :             : 
      89                 :             : static const char *malloc_state_names[] = {"malloc_top", "malloc", "malloc_bottom"};
      90                 :             : 
      91                 :             : /* Holder for the const_state.  There is one of these per function
      92                 :             :    decl.  */
      93                 :             : class funct_state_d
      94                 :             : {
      95                 :             : public:
      96                 :     2503699 :   funct_state_d (): pure_const_state (IPA_NEITHER),
      97                 :     2503699 :     state_previously_known (IPA_NEITHER), looping_previously_known (true),
      98                 :     2503699 :     looping (true), can_throw (true), can_free (true),
      99                 :           0 :     malloc_state (STATE_MALLOC_BOTTOM) {}
     100                 :             : 
     101                 :     2395338 :   funct_state_d (const funct_state_d &s): pure_const_state (s.pure_const_state),
     102                 :     2395338 :     state_previously_known (s.state_previously_known),
     103                 :     2395338 :     looping_previously_known (s.looping_previously_known),
     104                 :     2395338 :     looping (s.looping), can_throw (s.can_throw), can_free (s.can_free),
     105                 :     2395338 :     malloc_state (s.malloc_state) {}
     106                 :             : 
     107                 :             :   /* See above.  */
     108                 :             :   enum pure_const_state_e pure_const_state;
     109                 :             :   /* What user set here; we can be always sure about this.  */
     110                 :             :   enum pure_const_state_e state_previously_known;
     111                 :             :   bool looping_previously_known;
     112                 :             : 
     113                 :             :   /* True if the function could possibly infinite loop.  There are a
     114                 :             :      lot of ways that this could be determined.  We are pretty
     115                 :             :      conservative here.  While it is possible to cse pure and const
     116                 :             :      calls, it is not legal to have dce get rid of the call if there
     117                 :             :      is a possibility that the call could infinite loop since this is
     118                 :             :      a behavioral change.  */
     119                 :             :   bool looping;
     120                 :             : 
     121                 :             :   bool can_throw;
     122                 :             : 
     123                 :             :   /* If function can call free, munmap or otherwise make previously
     124                 :             :      non-trapping memory accesses trapping.  */
     125                 :             :   bool can_free;
     126                 :             : 
     127                 :             :   enum malloc_state_e malloc_state;
     128                 :             : };
     129                 :             : 
     130                 :             : typedef class funct_state_d * funct_state;
     131                 :             : 
     132                 :             : /* The storage of the funct_state is abstracted because there is the
     133                 :             :    possibility that it may be desirable to move this to the cgraph
     134                 :             :    local info.  */
     135                 :             : 
     136                 :             : class funct_state_summary_t:
     137                 :             :   public fast_function_summary <funct_state_d *, va_heap>
     138                 :             : {
     139                 :             : public:
     140                 :      157699 :   funct_state_summary_t (symbol_table *symtab):
     141                 :      315398 :     fast_function_summary <funct_state_d *, va_heap> (symtab) {}
     142                 :             : 
     143                 :             :   void insert (cgraph_node *, funct_state_d *state) final override;
     144                 :             :   void duplicate (cgraph_node *src_node, cgraph_node *dst_node,
     145                 :             :                   funct_state_d *src_data,
     146                 :             :                   funct_state_d *dst_data) final override;
     147                 :             : };
     148                 :             : 
     149                 :             : static funct_state_summary_t *funct_state_summaries = NULL;
     150                 :             : 
     151                 :             : static bool gate_pure_const (void);
     152                 :             : 
     153                 :             : namespace {
     154                 :             : 
     155                 :             : const pass_data pass_data_ipa_pure_const =
     156                 :             : {
     157                 :             :   IPA_PASS, /* type */
     158                 :             :   "pure-const", /* name */
     159                 :             :   OPTGROUP_NONE, /* optinfo_flags */
     160                 :             :   TV_IPA_PURE_CONST, /* tv_id */
     161                 :             :   0, /* properties_required */
     162                 :             :   0, /* properties_provided */
     163                 :             :   0, /* properties_destroyed */
     164                 :             :   0, /* todo_flags_start */
     165                 :             :   0, /* todo_flags_finish */
     166                 :             : };
     167                 :             : 
     168                 :             : class pass_ipa_pure_const : public ipa_opt_pass_d
     169                 :             : {
     170                 :             : public:
     171                 :             :   pass_ipa_pure_const(gcc::context *ctxt);
     172                 :             : 
     173                 :             :   /* opt_pass methods: */
     174                 :     1165154 :   bool gate (function *) final override { return gate_pure_const (); }
     175                 :             :   unsigned int execute (function *fun) final override;
     176                 :             : 
     177                 :             :   void register_hooks (void);
     178                 :             : 
     179                 :             : private:
     180                 :             :   bool init_p;
     181                 :             : }; // class pass_ipa_pure_const
     182                 :             : 
     183                 :             : } // anon namespace
     184                 :             : 
     185                 :             : /* Try to guess if function body will always be visible to compiler
     186                 :             :    when compiling the call and whether compiler will be able
     187                 :             :    to propagate the information by itself.  */
     188                 :             : 
     189                 :             : static bool
     190                 :          26 : function_always_visible_to_compiler_p (tree decl)
     191                 :             : {
     192                 :          22 :   return (!TREE_PUBLIC (decl) || DECL_DECLARED_INLINE_P (decl)
     193                 :          48 :           || DECL_COMDAT (decl));
     194                 :             : }
     195                 :             : 
     196                 :             : /* Emit suggestion about attribute ATTRIB_NAME for DECL.  KNOWN_FINITE
     197                 :             :    is true if the function is known to be finite.  The diagnostic is
     198                 :             :    controlled by OPTION.  WARNED_ABOUT is a hash_set<tree> unique for
     199                 :             :    OPTION, this function may initialize it and it is always returned
     200                 :             :    by the function.  */
     201                 :             : 
     202                 :             : static hash_set<tree> *
     203                 :     1192144 : suggest_attribute (diagnostic_option_id option, tree decl, bool known_finite,
     204                 :             :                    hash_set<tree> *warned_about,
     205                 :             :                    const char * attrib_name)
     206                 :             : {
     207                 :     1192144 :   if (!option_enabled (option.m_idx, lang_hooks.option_lang_mask (),
     208                 :             :                        &global_options))
     209                 :             :     return warned_about;
     210                 :          30 :   if (TREE_THIS_VOLATILE (decl)
     211                 :          30 :       || (known_finite && function_always_visible_to_compiler_p (decl)))
     212                 :             :     return warned_about;
     213                 :             : 
     214                 :          26 :   if (!warned_about)
     215                 :          14 :     warned_about = new hash_set<tree>;
     216                 :          26 :   if (warned_about->contains (decl))
     217                 :             :     return warned_about;
     218                 :          26 :   warned_about->add (decl);
     219                 :          26 :   auto_urlify_attributes sentinel;
     220                 :          30 :   warning_at (DECL_SOURCE_LOCATION (decl),
     221                 :             :               option,
     222                 :             :               known_finite
     223                 :             :               ? G_("function might be candidate for attribute %qs")
     224                 :             :               : G_("function might be candidate for attribute %qs"
     225                 :             :                    " if it is known to return normally"), attrib_name);
     226                 :          26 :   return warned_about;
     227                 :          26 : }
     228                 :             : 
     229                 :             : /* Emit suggestion about __attribute_((pure)) for DECL.  KNOWN_FINITE
     230                 :             :    is true if the function is known to be finite.  */
     231                 :             : 
     232                 :             : static void
     233                 :      348270 : warn_function_pure (tree decl, bool known_finite)
     234                 :             : {
     235                 :             :   /* Declaring a void function pure makes no sense and is diagnosed
     236                 :             :      by -Wattributes because calling it would have no effect.  */
     237                 :      348270 :   if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl))))
     238                 :             :     return;
     239                 :             : 
     240                 :      320495 :   static hash_set<tree> *warned_about;
     241                 :      320495 :   warned_about
     242                 :      320495 :     = suggest_attribute (OPT_Wsuggest_attribute_pure, decl,
     243                 :             :                          known_finite, warned_about, "pure");
     244                 :             : }
     245                 :             : 
     246                 :             : /* Emit suggestion about __attribute_((const)) for DECL.  KNOWN_FINITE
     247                 :             :    is true if the function is known to be finite.  */
     248                 :             : 
     249                 :             : static void
     250                 :      894039 : warn_function_const (tree decl, bool known_finite)
     251                 :             : {
     252                 :             :   /* Declaring a void function const makes no sense is diagnosed
     253                 :             :      by -Wattributes because calling it would have no effect.  */
     254                 :      894039 :   if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl))))
     255                 :             :     return;
     256                 :             : 
     257                 :      645737 :   static hash_set<tree> *warned_about;
     258                 :      645737 :   warned_about
     259                 :      645737 :     = suggest_attribute (OPT_Wsuggest_attribute_const, decl,
     260                 :             :                          known_finite, warned_about, "const");
     261                 :             : }
     262                 :             : 
     263                 :             : /* Emit suggestion about __attribute__((malloc)) for DECL.  */
     264                 :             : 
     265                 :             : static void
     266                 :           3 : warn_function_malloc (tree decl)
     267                 :             : {
     268                 :           3 :   static hash_set<tree> *warned_about;
     269                 :           3 :   warned_about
     270                 :           3 :     = suggest_attribute (OPT_Wsuggest_attribute_malloc, decl,
     271                 :             :                          true, warned_about, "malloc");
     272                 :           3 : }
     273                 :             : 
     274                 :             : /* Emit suggestion about __attribute__((noreturn)) for DECL.  */
     275                 :             : 
     276                 :             : static void
     277                 :       31394 : warn_function_noreturn (tree decl)
     278                 :             : {
     279                 :       31394 :   tree original_decl = decl;
     280                 :             : 
     281                 :       31394 :   static hash_set<tree> *warned_about;
     282                 :       31394 :   if (!lang_hooks.missing_noreturn_ok_p (decl)
     283                 :       31394 :       && targetm.warn_func_return (decl))
     284                 :       19246 :     warned_about
     285                 :       19246 :       = suggest_attribute (OPT_Wsuggest_attribute_noreturn, original_decl,
     286                 :             :                            true, warned_about, "noreturn");
     287                 :       31394 : }
     288                 :             : 
     289                 :             : void
     290                 :       13877 : warn_function_cold (tree decl)
     291                 :             : {
     292                 :       13877 :   tree original_decl = decl;
     293                 :             : 
     294                 :       13877 :   static hash_set<tree> *warned_about;
     295                 :       13877 :   warned_about
     296                 :       13877 :     = suggest_attribute (OPT_Wsuggest_attribute_cold, original_decl,
     297                 :             :                          true, warned_about, "cold");
     298                 :       13877 : }
     299                 :             : 
     300                 :             : void
     301                 :      192786 : warn_function_returns_nonnull (tree decl)
     302                 :             : {
     303                 :      192786 :   static hash_set<tree> *warned_about;
     304                 :      192786 :   warned_about
     305                 :      192786 :     = suggest_attribute (OPT_Wsuggest_attribute_returns_nonnull, decl,
     306                 :             :                          true, warned_about, "returns_nonnull");
     307                 :      192786 : }
     308                 :             : 
     309                 :             : /* Check to see if the use (or definition when CHECKING_WRITE is true)
     310                 :             :    variable T is legal in a function that is either pure or const.  */
     311                 :             : 
     312                 :             : static inline void
     313                 :    20650141 : check_decl (funct_state local,
     314                 :             :             tree t, bool checking_write, bool ipa)
     315                 :             : {
     316                 :             :   /* Do not want to do anything with volatile except mark any
     317                 :             :      function that uses one to be not const or pure.  */
     318                 :    20650141 :   if (TREE_THIS_VOLATILE (t))
     319                 :             :     {
     320                 :     1444466 :       local->pure_const_state = IPA_NEITHER;
     321                 :     1444466 :       if (dump_file)
     322                 :          30 :         fprintf (dump_file, "    Volatile operand is not const/pure\n");
     323                 :     1444466 :       return;
     324                 :             :     }
     325                 :             : 
     326                 :             :   /* Do not care about a local automatic that is not static.  */
     327                 :    19205675 :   if (!TREE_STATIC (t) && !DECL_EXTERNAL (t))
     328                 :             :     return;
     329                 :             : 
     330                 :             :   /* If the variable has the "used" attribute, treat it as if it had a
     331                 :             :      been touched by the devil.  */
     332                 :     3442885 :   if (DECL_PRESERVE_P (t))
     333                 :             :     {
     334                 :        2997 :       local->pure_const_state = IPA_NEITHER;
     335                 :        2997 :       if (dump_file)
     336                 :           0 :         fprintf (dump_file, "    Used static/global variable is not const/pure\n");
     337                 :        2997 :       return;
     338                 :             :     }
     339                 :             : 
     340                 :             :   /* In IPA mode we are not interested in checking actual loads and stores;
     341                 :             :      they will be processed at propagation time using ipa_ref.  */
     342                 :     3439888 :   if (ipa)
     343                 :             :     return;
     344                 :             : 
     345                 :             :   /* Since we have dealt with the locals and params cases above, if we
     346                 :             :      are CHECKING_WRITE, this cannot be a pure or constant
     347                 :             :      function.  */
     348                 :     2212077 :   if (checking_write)
     349                 :             :     {
     350                 :      793238 :       local->pure_const_state = IPA_NEITHER;
     351                 :      793238 :       if (dump_file)
     352                 :           1 :         fprintf (dump_file, "    static/global memory write is not const/pure\n");
     353                 :      793238 :       return;
     354                 :             :     }
     355                 :             : 
     356                 :     1418839 :   if (DECL_EXTERNAL (t) || TREE_PUBLIC (t))
     357                 :             :     {
     358                 :             :       /* Readonly reads are safe.  */
     359                 :      817545 :       if (TREE_READONLY (t))
     360                 :             :         return; /* Read of a constant, do not change the function state.  */
     361                 :             :       else
     362                 :             :         {
     363                 :      813935 :           if (dump_file)
     364                 :           0 :             fprintf (dump_file, "    global memory read is not const\n");
     365                 :             :           /* Just a regular read.  */
     366                 :      813935 :           if (local->pure_const_state == IPA_CONST)
     367                 :      163019 :             local->pure_const_state = IPA_PURE;
     368                 :             :         }
     369                 :             :     }
     370                 :             :   else
     371                 :             :     {
     372                 :             :       /* Compilation level statics can be read if they are readonly
     373                 :             :          variables.  */
     374                 :      601294 :       if (TREE_READONLY (t))
     375                 :             :         return;
     376                 :             : 
     377                 :      572856 :       if (dump_file)
     378                 :           1 :         fprintf (dump_file, "    static memory read is not const\n");
     379                 :             :       /* Just a regular read.  */
     380                 :      572856 :       if (local->pure_const_state == IPA_CONST)
     381                 :       31481 :         local->pure_const_state = IPA_PURE;
     382                 :             :     }
     383                 :             : }
     384                 :             : 
     385                 :             : 
     386                 :             : /* Check to see if the use (or definition when CHECKING_WRITE is true)
     387                 :             :    variable T is legal in a function that is either pure or const.  */
     388                 :             : 
     389                 :             : static inline void
     390                 :    16924607 : check_op (funct_state local, tree t, bool checking_write)
     391                 :             : {
     392                 :    16924607 :   t = get_base_address (t);
     393                 :    16924607 :   if (t && TREE_THIS_VOLATILE (t))
     394                 :             :     {
     395                 :       19003 :       local->pure_const_state = IPA_NEITHER;
     396                 :       19003 :       if (dump_file)
     397                 :           2 :         fprintf (dump_file, "    Volatile indirect ref is not const/pure\n");
     398                 :       19003 :       return;
     399                 :             :     }
     400                 :    16905604 :   else if (refs_local_or_readonly_memory_p (t))
     401                 :             :     {
     402                 :     3802863 :       if (dump_file)
     403                 :          10 :         fprintf (dump_file, "    Indirect ref to local or readonly "
     404                 :             :                  "memory is OK\n");
     405                 :     3802863 :       return;
     406                 :             :     }
     407                 :    13102741 :   else if (checking_write)
     408                 :             :     {
     409                 :     4616550 :       local->pure_const_state = IPA_NEITHER;
     410                 :     4616550 :       if (dump_file)
     411                 :          65 :         fprintf (dump_file, "    Indirect ref write is not const/pure\n");
     412                 :     4616550 :       return;
     413                 :             :     }
     414                 :             :   else
     415                 :             :     {
     416                 :     8486191 :       if (dump_file)
     417                 :         175 :         fprintf (dump_file, "    Indirect ref read is not const\n");
     418                 :     8486191 :       if (local->pure_const_state == IPA_CONST)
     419                 :     1242692 :         local->pure_const_state = IPA_PURE;
     420                 :             :     }
     421                 :             : }
     422                 :             : 
     423                 :             : /* compute state based on ECF FLAGS and store to STATE and LOOPING.  */
     424                 :             : 
     425                 :             : static void
     426                 :    15109929 : state_from_flags (enum pure_const_state_e *state, bool *looping,
     427                 :             :                   int flags, bool cannot_lead_to_return)
     428                 :             : {
     429                 :    15109929 :   *looping = false;
     430                 :    15109929 :   if (flags & ECF_LOOPING_CONST_OR_PURE)
     431                 :             :     {
     432                 :      195801 :       *looping = true;
     433                 :      195801 :       if (dump_file && (dump_flags & TDF_DETAILS))
     434                 :           0 :         fprintf (dump_file, " looping\n");
     435                 :             :     }
     436                 :    15109929 :   if (flags & ECF_CONST)
     437                 :             :     {
     438                 :     1109382 :       *state = IPA_CONST;
     439                 :     1109382 :       if (dump_file && (dump_flags & TDF_DETAILS))
     440                 :           3 :         fprintf (dump_file, " const\n");
     441                 :             :     }
     442                 :    14000547 :   else if (flags & ECF_PURE)
     443                 :             :     {
     444                 :     1163359 :       *state = IPA_PURE;
     445                 :     1163359 :       if (dump_file && (dump_flags & TDF_DETAILS))
     446                 :           3 :         fprintf (dump_file, " pure\n");
     447                 :             :     }
     448                 :    12837188 :   else if (cannot_lead_to_return)
     449                 :             :     {
     450                 :      937112 :       *state = IPA_PURE;
     451                 :      937112 :       *looping = true;
     452                 :      937112 :       if (dump_file && (dump_flags & TDF_DETAILS))
     453                 :           1 :         fprintf (dump_file, " ignoring side effects->pure looping\n");
     454                 :             :     }
     455                 :             :   else
     456                 :             :     {
     457                 :    11900076 :       if (dump_file && (dump_flags & TDF_DETAILS))
     458                 :          42 :         fprintf (dump_file, " neither\n");
     459                 :    11900076 :       *state = IPA_NEITHER;
     460                 :    11900076 :       *looping = true;
     461                 :             :     }
     462                 :    15109929 : }
     463                 :             : 
     464                 :             : /* Merge STATE and STATE2 and LOOPING and LOOPING2 and store
     465                 :             :    into STATE and LOOPING better of the two variants.
     466                 :             :    Be sure to merge looping correctly.  IPA_NEITHER functions
     467                 :             :    have looping 0 even if they don't have to return.  */
     468                 :             : 
     469                 :             : static inline void
     470                 :     6601980 : better_state (enum pure_const_state_e *state, bool *looping,
     471                 :             :               enum pure_const_state_e state2, bool looping2)
     472                 :             : {
     473                 :     6601980 :   if (state2 < *state)
     474                 :             :     {
     475                 :       31668 :       if (*state == IPA_NEITHER)
     476                 :       30173 :         *looping = looping2;
     477                 :             :       else
     478                 :        1495 :         *looping = MIN (*looping, looping2);
     479                 :       31668 :       *state = state2;
     480                 :             :     }
     481                 :     6570312 :   else if (state2 != IPA_NEITHER)
     482                 :     1551306 :     *looping = MIN (*looping, looping2);
     483                 :     6601980 : }
     484                 :             : 
     485                 :             : /* Merge STATE and STATE2 and LOOPING and LOOPING2 and store
     486                 :             :    into STATE and LOOPING worse of the two variants.
     487                 :             :    N is the actual node called.  */
     488                 :             : 
     489                 :             : static inline void
     490                 :    14120403 : worse_state (enum pure_const_state_e *state, bool *looping,
     491                 :             :              enum pure_const_state_e state2, bool looping2,
     492                 :             :              struct symtab_node *from,
     493                 :             :              struct symtab_node *to)
     494                 :             : {
     495                 :             :   /* Consider function:
     496                 :             : 
     497                 :             :      bool a(int *p)
     498                 :             :      {
     499                 :             :        return *p==*p;
     500                 :             :      }
     501                 :             : 
     502                 :             :      During early optimization we will turn this into:
     503                 :             : 
     504                 :             :      bool a(int *p)
     505                 :             :      {
     506                 :             :        return true;
     507                 :             :      }
     508                 :             : 
     509                 :             :      Now if this function will be detected as CONST however when interposed it
     510                 :             :      may end up being just pure.  We always must assume the worst scenario here.
     511                 :             :    */
     512                 :    14120403 :   if (*state == IPA_CONST && state2 == IPA_CONST
     513                 :    14120403 :       && to && !TREE_READONLY (to->decl) && !to->binds_to_current_def_p (from))
     514                 :             :     {
     515                 :        3651 :       if (dump_file && (dump_flags & TDF_DETAILS))
     516                 :           0 :         fprintf (dump_file, "Dropping state to PURE because call to %s may not "
     517                 :             :                  "bind to current def.\n", to->dump_name ());
     518                 :             :       state2 = IPA_PURE;
     519                 :             :     }
     520                 :    14120403 :   *state = MAX (*state, state2);
     521                 :    14120403 :   *looping = MAX (*looping, looping2);
     522                 :    14120403 : }
     523                 :             : 
     524                 :             : /* Recognize special cases of builtins that are by themselves not const
     525                 :             :    but function using them is.  */
     526                 :             : bool
     527                 :    22930377 : builtin_safe_for_const_function_p (bool *looping, tree callee)
     528                 :             : {
     529                 :    22930377 :   if (DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL)
     530                 :     6411096 :     switch (DECL_FUNCTION_CODE (callee))
     531                 :             :       {
     532                 :      818797 :       case BUILT_IN_RETURN:
     533                 :      818797 :       case BUILT_IN_UNREACHABLE:
     534                 :      818797 :       CASE_BUILT_IN_ALLOCA:
     535                 :      818797 :       case BUILT_IN_STACK_SAVE:
     536                 :      818797 :       case BUILT_IN_STACK_RESTORE:
     537                 :      818797 :       case BUILT_IN_EH_POINTER:
     538                 :      818797 :       case BUILT_IN_EH_FILTER:
     539                 :      818797 :       case BUILT_IN_UNWIND_RESUME:
     540                 :      818797 :       case BUILT_IN_CXA_END_CLEANUP:
     541                 :      818797 :       case BUILT_IN_EH_COPY_VALUES:
     542                 :      818797 :       case BUILT_IN_FRAME_ADDRESS:
     543                 :      818797 :       case BUILT_IN_APPLY_ARGS:
     544                 :      818797 :       case BUILT_IN_ASAN_BEFORE_DYNAMIC_INIT:
     545                 :      818797 :       case BUILT_IN_ASAN_AFTER_DYNAMIC_INIT:
     546                 :      818797 :       case BUILT_IN_DWARF_CFA:
     547                 :      818797 :       case BUILT_IN_RETURN_ADDRESS:
     548                 :      818797 :         *looping = false;
     549                 :      818797 :         return true;
     550                 :        9717 :       case BUILT_IN_PREFETCH:
     551                 :        9717 :         *looping = true;
     552                 :        9717 :         return true;
     553                 :             :       default:
     554                 :             :         break;
     555                 :             :       }
     556                 :             :   return false;
     557                 :             : }
     558                 :             : 
     559                 :             : /* Check the parameters of a function call to CALL_EXPR to see if
     560                 :             :    there are any references in the parameters that are not allowed for
     561                 :             :    pure or const functions.  Also check to see if this is either an
     562                 :             :    indirect call, a call outside the compilation unit, or has special
     563                 :             :    attributes that may also effect the purity.  The CALL_EXPR node for
     564                 :             :    the entire call expression.  */
     565                 :             : 
     566                 :             : static void
     567                 :    14884561 : check_call (funct_state local, gcall *call, bool ipa)
     568                 :             : {
     569                 :    14884561 :   int flags = gimple_call_flags (call);
     570                 :    14884561 :   tree callee_t = gimple_call_fndecl (call);
     571                 :    14884561 :   bool possibly_throws = stmt_could_throw_p (cfun, call);
     572                 :    14884561 :   bool possibly_throws_externally = (possibly_throws
     573                 :    14884561 :                                      && stmt_can_throw_external (cfun, call));
     574                 :             : 
     575                 :     5493881 :   if (possibly_throws)
     576                 :             :     {
     577                 :             :       unsigned int i;
     578                 :    33039376 :       for (i = 0; i < gimple_num_ops (call); i++)
     579                 :    27545495 :         if (gimple_op (call, i)
     580                 :    27545495 :             && tree_could_throw_p (gimple_op (call, i)))
     581                 :             :           {
     582                 :       80434 :             if (possibly_throws && cfun->can_throw_non_call_exceptions)
     583                 :             :               {
     584                 :       80434 :                 if (dump_file)
     585                 :           0 :                   fprintf (dump_file, "    operand can throw; looping\n");
     586                 :       80434 :                 local->looping = true;
     587                 :             :               }
     588                 :       80434 :             if (possibly_throws_externally)
     589                 :             :               {
     590                 :       66926 :                 if (dump_file)
     591                 :           0 :                   fprintf (dump_file, "    operand can throw externally\n");
     592                 :       66926 :                 local->can_throw = true;
     593                 :             :               }
     594                 :             :           }
     595                 :             :     }
     596                 :             : 
     597                 :             :   /* The const and pure flags are set by a variety of places in the
     598                 :             :      compiler (including here).  If someone has already set the flags
     599                 :             :      for the callee, (such as for some of the builtins) we will use
     600                 :             :      them, otherwise we will compute our own information.
     601                 :             : 
     602                 :             :      Const and pure functions have less clobber effects than other
     603                 :             :      functions so we process these first.  Otherwise if it is a call
     604                 :             :      outside the compilation unit or an indirect call we punt.  This
     605                 :             :      leaves local calls which will be processed by following the call
     606                 :             :      graph.  */
     607                 :    14884561 :   if (callee_t)
     608                 :             :     {
     609                 :    13950333 :       bool call_looping;
     610                 :             : 
     611                 :    13950333 :       if (gimple_call_builtin_p (call, BUILT_IN_NORMAL)
     612                 :    13950333 :           && !nonfreeing_call_p (call))
     613                 :      667019 :         local->can_free = true;
     614                 :             : 
     615                 :    13950333 :       if (builtin_safe_for_const_function_p (&call_looping, callee_t))
     616                 :             :         {
     617                 :      290858 :           worse_state (&local->pure_const_state, &local->looping,
     618                 :             :                        IPA_CONST, call_looping,
     619                 :             :                        NULL, NULL);
     620                 :      290858 :           return;
     621                 :             :         }
     622                 :             :       /* When bad things happen to bad functions, they cannot be const
     623                 :             :          or pure.  */
     624                 :    13659475 :       if (setjmp_call_p (callee_t))
     625                 :             :         {
     626                 :        2560 :           if (dump_file)
     627                 :           0 :             fprintf (dump_file, "    setjmp is not const/pure\n");
     628                 :        2560 :           local->looping = true;
     629                 :        2560 :           local->pure_const_state = IPA_NEITHER;
     630                 :             :         }
     631                 :             : 
     632                 :    13659475 :       if (DECL_BUILT_IN_CLASS (callee_t) == BUILT_IN_NORMAL)
     633                 :     3208314 :         switch (DECL_FUNCTION_CODE (callee_t))
     634                 :             :           {
     635                 :        1856 :           case BUILT_IN_LONGJMP:
     636                 :        1856 :           case BUILT_IN_NONLOCAL_GOTO:
     637                 :        1856 :             if (dump_file)
     638                 :           0 :               fprintf (dump_file,
     639                 :             :                        "    longjmp and nonlocal goto is not const/pure\n");
     640                 :        1856 :             local->pure_const_state = IPA_NEITHER;
     641                 :        1856 :             local->looping = true;
     642                 :        1856 :             break;
     643                 :             :           default:
     644                 :             :             break;
     645                 :             :           }
     646                 :             :     }
     647                 :      934228 :   else if (gimple_call_internal_p (call) && !nonfreeing_call_p (call))
     648                 :      150567 :     local->can_free = true;
     649                 :             : 
     650                 :             :   /* When not in IPA mode, we can still handle self recursion.  */
     651                 :    14593703 :   if (!ipa && callee_t
     652                 :    14593703 :       && recursive_call_p (current_function_decl, callee_t))
     653                 :             :     {
     654                 :       19977 :       if (dump_file)
     655                 :           0 :         fprintf (dump_file, "    Recursive call can loop.\n");
     656                 :       19977 :       local->looping = true;
     657                 :             :     }
     658                 :             :   /* Either callee is unknown or we are doing local analysis.
     659                 :             :      Look to see if there are any bits available for the callee (such as by
     660                 :             :      declaration or because it is builtin) and process solely on the basis of
     661                 :             :      those bits.  Handle internal calls always, those calls don't have
     662                 :             :      corresponding cgraph edges and thus aren't processed during
     663                 :             :      the propagation.  */
     664                 :    14573726 :   else if (!ipa || gimple_call_internal_p (call))
     665                 :             :     {
     666                 :     9517448 :       enum pure_const_state_e call_state;
     667                 :     9517448 :       bool call_looping;
     668                 :     9517448 :       if (possibly_throws && cfun->can_throw_non_call_exceptions)
     669                 :             :         {
     670                 :     2181399 :           if (dump_file)
     671                 :           0 :             fprintf (dump_file, "    can throw; looping\n");
     672                 :     2181399 :           local->looping = true;
     673                 :             :         }
     674                 :     9517448 :       if (possibly_throws_externally)
     675                 :             :         {
     676                 :     2553728 :           if (dump_file)
     677                 :             :             {
     678                 :           0 :               fprintf (dump_file, "    can throw externally to lp %i\n",
     679                 :             :                        lookup_stmt_eh_lp (call));
     680                 :           0 :               if (callee_t)
     681                 :           0 :                 fprintf (dump_file, "     callee:%s\n",
     682                 :           0 :                          IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (callee_t)));
     683                 :             :             }
     684                 :     2553728 :           local->can_throw = true;
     685                 :             :         }
     686                 :     9517448 :       if (dump_file && (dump_flags & TDF_DETAILS))
     687                 :          22 :         fprintf (dump_file, "    checking flags for call:");
     688                 :     9517448 :       state_from_flags (&call_state, &call_looping, flags,
     689                 :     9517448 :                         ((flags & (ECF_NORETURN | ECF_NOTHROW))
     690                 :             :                          == (ECF_NORETURN | ECF_NOTHROW))
     691                 :     9517448 :                         || (!flag_exceptions && (flags & ECF_NORETURN)));
     692                 :     9517448 :       worse_state (&local->pure_const_state, &local->looping,
     693                 :             :                    call_state, call_looping, NULL, NULL);
     694                 :             :     }
     695                 :             :   /* Direct functions calls are handled by IPA propagation.  */
     696                 :             : }
     697                 :             : 
     698                 :             : /* Wrapper around check_decl for loads in local more.  */
     699                 :             : 
     700                 :             : static bool
     701                 :    12141960 : check_load (gimple *, tree op, tree, void *data)
     702                 :             : {
     703                 :    12141960 :   if (DECL_P (op))
     704                 :     5421620 :     check_decl ((funct_state)data, op, false, false);
     705                 :             :   else
     706                 :     6720340 :     check_op ((funct_state)data, op, false);
     707                 :    12141960 :   return false;
     708                 :             : }
     709                 :             : 
     710                 :             : /* Wrapper around check_decl for stores in local more.  */
     711                 :             : 
     712                 :             : static bool
     713                 :    13122702 : check_store (gimple *, tree op, tree, void *data)
     714                 :             : {
     715                 :    13122702 :   if (DECL_P (op))
     716                 :     7876598 :     check_decl ((funct_state)data, op, true, false);
     717                 :             :   else
     718                 :     5246104 :     check_op ((funct_state)data, op, true);
     719                 :    13122702 :   return false;
     720                 :             : }
     721                 :             : 
     722                 :             : /* Wrapper around check_decl for loads in ipa mode.  */
     723                 :             : 
     724                 :             : static bool
     725                 :     6058181 : check_ipa_load (gimple *, tree op, tree, void *data)
     726                 :             : {
     727                 :     6058181 :   if (DECL_P (op))
     728                 :     3089163 :     check_decl ((funct_state)data, op, false, true);
     729                 :             :   else
     730                 :     2969018 :     check_op ((funct_state)data, op, false);
     731                 :     6058181 :   return false;
     732                 :             : }
     733                 :             : 
     734                 :             : /* Wrapper around check_decl for stores in ipa mode.  */
     735                 :             : 
     736                 :             : static bool
     737                 :     6251905 : check_ipa_store (gimple *, tree op, tree, void *data)
     738                 :             : {
     739                 :     6251905 :   if (DECL_P (op))
     740                 :     4262760 :     check_decl ((funct_state)data, op, true, true);
     741                 :             :   else
     742                 :     1989145 :     check_op ((funct_state)data, op, true);
     743                 :     6251905 :   return false;
     744                 :             : }
     745                 :             : 
     746                 :             : /* Look into pointer pointed to by GSIP and figure out what interesting side
     747                 :             :    effects it has.  */
     748                 :             : static void
     749                 :   170976908 : check_stmt (gimple_stmt_iterator *gsip, funct_state local, bool ipa)
     750                 :             : {
     751                 :   170976908 :   gimple *stmt = gsi_stmt (*gsip);
     752                 :             : 
     753                 :   170976908 :   if (is_gimple_debug (stmt))
     754                 :             :     return;
     755                 :             : 
     756                 :             :   /* Do consider clobber as side effects before IPA, so we rather inline
     757                 :             :      C++ destructors and keep clobber semantics than eliminate them.
     758                 :             : 
     759                 :             :      Similar logic is in ipa-modref.
     760                 :             : 
     761                 :             :      TODO: We may get smarter during early optimizations on these and let
     762                 :             :      functions containing only clobbers to be optimized more.  This is a common
     763                 :             :      case of C++ destructors.  */
     764                 :             : 
     765                 :    89439468 :   if ((ipa || cfun->after_inlining) && gimple_clobber_p (stmt))
     766                 :             :     return;
     767                 :             : 
     768                 :    87101559 :   if (dump_file)
     769                 :             :     {
     770                 :        1709 :       fprintf (dump_file, "  scanning: ");
     771                 :        1709 :       print_gimple_stmt (dump_file, stmt, 0);
     772                 :             :     }
     773                 :             : 
     774                 :    87101559 :   if (gimple_has_volatile_ops (stmt)
     775                 :    74312167 :       && !gimple_clobber_p (stmt))
     776                 :             :     {
     777                 :     1465480 :       local->pure_const_state = IPA_NEITHER;
     778                 :     1465480 :       if (dump_file)
     779                 :          33 :         fprintf (dump_file, "    Volatile stmt is not const/pure\n");
     780                 :             :     }
     781                 :             : 
     782                 :             :   /* Look for loads and stores.  */
     783                 :   145919456 :   walk_stmt_load_store_ops (stmt, local,
     784                 :             :                             ipa ? check_ipa_load : check_load,
     785                 :             :                             ipa ? check_ipa_store :  check_store);
     786                 :             : 
     787                 :    87101559 :   if (gimple_code (stmt) != GIMPLE_CALL
     788                 :    87101559 :       && stmt_could_throw_p (cfun, stmt))
     789                 :             :     {
     790                 :     2549557 :       if (cfun->can_throw_non_call_exceptions)
     791                 :             :         {
     792                 :     2245173 :           if (dump_file)
     793                 :           0 :             fprintf (dump_file, "    can throw; looping\n");
     794                 :     2245173 :           local->looping = true;
     795                 :             :         }
     796                 :     2549557 :       if (stmt_can_throw_external (cfun, stmt))
     797                 :             :         {
     798                 :     2121655 :           if (dump_file)
     799                 :           6 :             fprintf (dump_file, "    can throw externally\n");
     800                 :     2121655 :           local->can_throw = true;
     801                 :             :         }
     802                 :             :       else
     803                 :      427902 :         if (dump_file)
     804                 :           0 :           fprintf (dump_file, "    can throw\n");
     805                 :             :     }
     806                 :    87101559 :   switch (gimple_code (stmt))
     807                 :             :     {
     808                 :    14884561 :     case GIMPLE_CALL:
     809                 :    14884561 :       check_call (local, as_a <gcall *> (stmt), ipa);
     810                 :    14884561 :       break;
     811                 :     1668675 :     case GIMPLE_LABEL:
     812                 :     1668675 :       if (DECL_NONLOCAL (gimple_label_label (as_a <glabel *> (stmt))))
     813                 :             :         /* Target of long jump. */
     814                 :             :         {
     815                 :         812 :           if (dump_file)
     816                 :           0 :             fprintf (dump_file, "    nonlocal label is not const/pure\n");
     817                 :         812 :           local->pure_const_state = IPA_NEITHER;
     818                 :             :         }
     819                 :             :       break;
     820                 :      253854 :     case GIMPLE_ASM:
     821                 :      253854 :       if (gimple_asm_clobbers_memory_p (as_a <gasm *> (stmt)))
     822                 :             :         {
     823                 :      112608 :           if (dump_file)
     824                 :           3 :             fprintf (dump_file, "    memory asm clobber is not const/pure\n");
     825                 :             :           /* Abandon all hope, ye who enter here. */
     826                 :      112608 :           local->pure_const_state = IPA_NEITHER;
     827                 :      112608 :           local->can_free = true;
     828                 :             :         }
     829                 :      253854 :       if (gimple_asm_volatile_p (as_a <gasm *> (stmt)))
     830                 :             :         {
     831                 :      231536 :           if (dump_file)
     832                 :           3 :             fprintf (dump_file, "    volatile is not const/pure\n");
     833                 :             :           /* Abandon all hope, ye who enter here. */
     834                 :      231536 :           local->pure_const_state = IPA_NEITHER;
     835                 :      231536 :           local->looping = true;
     836                 :      231536 :           local->can_free = true;
     837                 :             :         }
     838                 :             :       return;
     839                 :             :     default:
     840                 :             :       break;
     841                 :             :     }
     842                 :             : }
     843                 :             : 
     844                 :             : /* Check that RETVAL is used only in STMT and in comparisons against 0.
     845                 :             :    RETVAL is return value of the function and STMT is return stmt.  */
     846                 :             : 
     847                 :             : static bool
     848                 :      414245 : check_retval_uses (tree retval, gimple *stmt)
     849                 :             : {
     850                 :      414245 :   imm_use_iterator use_iter;
     851                 :      414245 :   gimple *use_stmt;
     852                 :             : 
     853                 :      892148 :   FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, retval)
     854                 :      601440 :     if (gcond *cond = dyn_cast<gcond *> (use_stmt))
     855                 :             :       {
     856                 :       12582 :         tree op2 = gimple_cond_rhs (cond);
     857                 :       12582 :         if (!integer_zerop (op2))
     858                 :             :           return false;
     859                 :             :       }
     860                 :      588858 :     else if (gassign *ga = dyn_cast<gassign *> (use_stmt))
     861                 :             :       {
     862                 :       82922 :         enum tree_code code = gimple_assign_rhs_code (ga);
     863                 :       82922 :         if (TREE_CODE_CLASS (code) != tcc_comparison)
     864                 :             :           return false;
     865                 :        2462 :         if (!integer_zerop (gimple_assign_rhs2 (ga)))
     866                 :             :           return false;
     867                 :             :       }
     868                 :      505936 :     else if (is_gimple_debug (use_stmt))
     869                 :             :       ;
     870                 :      405404 :     else if (use_stmt != stmt)
     871                 :      414245 :       return false;
     872                 :             : 
     873                 :      290708 :   return true;
     874                 :             : }
     875                 :             : 
     876                 :             : /* malloc_candidate_p() checks if FUN can possibly be annotated with malloc
     877                 :             :    attribute. Currently this function does a very conservative analysis.
     878                 :             :    FUN is considered to be a candidate if
     879                 :             :    1) It returns a value of pointer type.
     880                 :             :    2) SSA_NAME_DEF_STMT (return_value) is either a function call or
     881                 :             :       a phi, and element of phi is either NULL or
     882                 :             :       SSA_NAME_DEF_STMT(element) is function call.
     883                 :             :    3) The return-value has immediate uses only within comparisons (gcond or gassign)
     884                 :             :       and return_stmt (and likewise a phi arg has immediate use only within comparison
     885                 :             :       or the phi stmt).  */
     886                 :             : 
     887                 :             : #define DUMP_AND_RETURN(reason)  \
     888                 :             : {  \
     889                 :             :   if (dump_file && (dump_flags & TDF_DETAILS))  \
     890                 :             :     fprintf (dump_file, "\n%s is not a malloc candidate, reason: %s\n", \
     891                 :             :              (node->dump_name ()), (reason));  \
     892                 :             :   return false;  \
     893                 :             : }
     894                 :             : 
     895                 :             : static bool
     896                 :      350388 : malloc_candidate_p_1 (function *fun, tree retval, gimple *ret_stmt, bool ipa,
     897                 :             :                       bitmap visited)
     898                 :             : {
     899                 :      350388 :   cgraph_node *node = cgraph_node::get_create (fun->decl);
     900                 :      350388 :   if (!bitmap_set_bit (visited, SSA_NAME_VERSION (retval)))
     901                 :             :     return true;
     902                 :             : 
     903                 :      350388 :   if (!check_retval_uses (retval, ret_stmt))
     904                 :       97337 :     DUMP_AND_RETURN("Return value has uses outside return stmt"
     905                 :             :                     " and comparisons against 0.")
     906                 :             : 
     907                 :      253051 :   gimple *def = SSA_NAME_DEF_STMT (retval);
     908                 :             : 
     909                 :      253051 :   if (gcall *call_stmt = dyn_cast<gcall *> (def))
     910                 :             :     {
     911                 :       53375 :       tree callee_decl = gimple_call_fndecl (call_stmt);
     912                 :       53375 :       if (!callee_decl)
     913                 :             :         return false;
     914                 :             : 
     915                 :       95253 :       if (!ipa && !DECL_IS_MALLOC (callee_decl))
     916                 :       24810 :         DUMP_AND_RETURN("callee_decl does not have malloc attribute for"
     917                 :             :                         " non-ipa mode.")
     918                 :             : 
     919                 :       27117 :       cgraph_edge *cs = node->get_edge (call_stmt);
     920                 :       27117 :       if (cs)
     921                 :             :         {
     922                 :        8601 :           ipa_call_summary *es = ipa_call_summaries->get_create (cs);
     923                 :        8601 :           es->is_return_callee_uncaptured = true;
     924                 :             :         }
     925                 :             :     }
     926                 :             : 
     927                 :      199676 :     else if (gphi *phi = dyn_cast<gphi *> (def))
     928                 :             :       {
     929                 :             :         bool all_args_zero = true;
     930                 :       89362 :         for (unsigned i = 0; i < gimple_phi_num_args (phi); ++i)
     931                 :             :           {
     932                 :       84621 :             tree arg = gimple_phi_arg_def (phi, i);
     933                 :       84621 :             if (integer_zerop (arg))
     934                 :       18156 :               continue;
     935                 :             : 
     936                 :       66465 :             all_args_zero = false;
     937                 :       66465 :             if (TREE_CODE (arg) != SSA_NAME)
     938                 :        2608 :               DUMP_AND_RETURN ("phi arg is not SSA_NAME.");
     939                 :       63857 :             if (!check_retval_uses (arg, phi))
     940                 :       26200 :               DUMP_AND_RETURN ("phi arg has uses outside phi"
     941                 :             :                                  " and comparisons against 0.")
     942                 :             : 
     943                 :       37657 :             gimple *arg_def = SSA_NAME_DEF_STMT (arg);
     944                 :       37657 :             if (is_a<gphi *> (arg_def))
     945                 :             :               {
     946                 :        3464 :                 if (!malloc_candidate_p_1 (fun, arg, phi, ipa, visited))
     947                 :        3380 :                     DUMP_AND_RETURN ("nested phi fail")
     948                 :          84 :                 continue;
     949                 :             :               }
     950                 :             : 
     951                 :       34193 :             gcall *call_stmt = dyn_cast<gcall *> (arg_def);
     952                 :       34193 :             if (!call_stmt)
     953                 :       18393 :               DUMP_AND_RETURN ("phi arg is a not a call_stmt.")
     954                 :             : 
     955                 :       15800 :             tree callee_decl = gimple_call_fndecl (call_stmt);
     956                 :       15800 :             if (!callee_decl)
     957                 :             :               return false;
     958                 :       20715 :             if (!ipa && !DECL_IS_MALLOC (callee_decl))
     959                 :        4931 :               DUMP_AND_RETURN("callee_decl does not have malloc attribute"
     960                 :             :                               " for non-ipa mode.")
     961                 :             : 
     962                 :        8052 :             cgraph_edge *cs = node->get_edge (call_stmt);
     963                 :        8052 :             if (cs)
     964                 :             :               {
     965                 :        5353 :                 ipa_call_summary *es = ipa_call_summaries->get_create (cs);
     966                 :        5353 :                 es->is_return_callee_uncaptured = true;
     967                 :             :               }
     968                 :             :           }
     969                 :             : 
     970                 :        4741 :         if (all_args_zero)
     971                 :           4 :           DUMP_AND_RETURN ("Return value is a phi with all args equal to 0.")
     972                 :             :       }
     973                 :             : 
     974                 :             :     else
     975                 :      136606 :       DUMP_AND_RETURN("def_stmt of return value is not a call or phi-stmt.")
     976                 :             : 
     977                 :             :   return true;
     978                 :             : }
     979                 :             : 
     980                 :             : static bool
     981                 :     5733381 : malloc_candidate_p (function *fun, bool ipa)
     982                 :             : {
     983                 :     5733381 :   basic_block exit_block = EXIT_BLOCK_PTR_FOR_FN (fun);
     984                 :     5733381 :   edge e;
     985                 :     5733381 :   edge_iterator ei;
     986                 :     5733381 :   cgraph_node *node = cgraph_node::get_create (fun->decl);
     987                 :             : 
     988                 :     5733381 :   if (EDGE_COUNT (exit_block->preds) == 0
     989                 :     5730379 :       || !flag_delete_null_pointer_checks)
     990                 :             :     return false;
     991                 :             : 
     992                 :     5599895 :   auto_bitmap visited;
     993                 :     5631665 :   FOR_EACH_EDGE (e, ei, exit_block->preds)
     994                 :             :     {
     995                 :     5599895 :       gimple_stmt_iterator gsi = gsi_last_bb (e->src);
     996                 :    11166769 :       greturn *ret_stmt = dyn_cast<greturn *> (gsi_stmt (gsi));
     997                 :             : 
     998                 :     5598644 :       if (!ret_stmt)
     999                 :     5599895 :         return false;
    1000                 :             : 
    1001                 :     5598644 :       tree retval = gimple_return_retval (ret_stmt);
    1002                 :     5598644 :       if (!retval)
    1003                 :     2531000 :         DUMP_AND_RETURN("No return value.")
    1004                 :             : 
    1005                 :     3067644 :       if (TREE_CODE (retval) != SSA_NAME
    1006                 :     3067644 :           || TREE_CODE (TREE_TYPE (retval)) != POINTER_TYPE)
    1007                 :     2720720 :         DUMP_AND_RETURN("Return value is not SSA_NAME or not a pointer type.")
    1008                 :             : 
    1009                 :      346924 :       if (!malloc_candidate_p_1 (fun, retval, ret_stmt, ipa, visited))
    1010                 :             :         return false;
    1011                 :             :     }
    1012                 :             : 
    1013                 :       31770 :   if (dump_file && (dump_flags & TDF_DETAILS))
    1014                 :           8 :     fprintf (dump_file, "\nFound %s to be candidate for malloc attribute\n",
    1015                 :           4 :              IDENTIFIER_POINTER (DECL_NAME (fun->decl)));
    1016                 :             :   return true;
    1017                 :     5599895 : }
    1018                 :             : 
    1019                 :             : #undef DUMP_AND_RETURN
    1020                 :             : 
    1021                 :             : /* Return true if function is known to be finite.  */
    1022                 :             : 
    1023                 :             : bool
    1024                 :     4097576 : finite_function_p ()
    1025                 :             : {
    1026                 :             :   /* Const functions cannot have back edges (an
    1027                 :             :      indication of possible infinite loop side
    1028                 :             :      effect.  */
    1029                 :     4097576 :   bool finite = true;
    1030                 :     4097576 :   if (mark_dfs_back_edges ())
    1031                 :             :     {
    1032                 :             :       /* Preheaders are needed for SCEV to work.
    1033                 :             :          Simple latches and recorded exits improve chances that loop will
    1034                 :             :          proved to be finite in testcases such as in loop-15.c
    1035                 :             :          and loop-24.c  */
    1036                 :      405321 :       loop_optimizer_init (LOOPS_HAVE_PREHEADERS
    1037                 :             :                            | LOOPS_HAVE_SIMPLE_LATCHES
    1038                 :             :                            | LOOPS_HAVE_RECORDED_EXITS);
    1039                 :      405321 :       if (dump_file && (dump_flags & TDF_DETAILS))
    1040                 :           0 :         flow_loops_dump (dump_file, NULL, 0);
    1041                 :      405321 :       if (mark_irreducible_loops ())
    1042                 :             :         {
    1043                 :        1930 :           if (dump_file)
    1044                 :           0 :             fprintf (dump_file, "    has irreducible loops\n");
    1045                 :             :           finite = false;
    1046                 :             :         }
    1047                 :             :       else
    1048                 :             :         {
    1049                 :      403391 :           scev_initialize ();
    1050                 :     2013785 :           for (auto loop : loops_list (cfun, 0))
    1051                 :      877384 :             if (!finite_loop_p (loop))
    1052                 :             :               {
    1053                 :       73772 :                 if (dump_file)
    1054                 :           1 :                   fprintf (dump_file, "    cannot prove finiteness of "
    1055                 :             :                            "loop %i\n", loop->num);
    1056                 :             :                 finite =false;
    1057                 :             :                 break;
    1058                 :      403391 :               }
    1059                 :      403391 :           scev_finalize ();
    1060                 :             :         }
    1061                 :      405321 :       loop_optimizer_finalize ();
    1062                 :             :     }
    1063                 :     4097576 :   return finite;
    1064                 :             : }
    1065                 :             : 
    1066                 :             : /* This is the main routine for finding the reference patterns for
    1067                 :             :    global variables within a function FN.  */
    1068                 :             : 
    1069                 :             : static funct_state
    1070                 :     4518608 : analyze_function (struct cgraph_node *fn, bool ipa)
    1071                 :             : {
    1072                 :     4518608 :   tree decl = fn->decl;
    1073                 :     4518608 :   funct_state l;
    1074                 :     4518608 :   basic_block this_block;
    1075                 :             : 
    1076                 :     4518608 :   l = XCNEW (class funct_state_d);
    1077                 :     4518608 :   l->pure_const_state = IPA_CONST;
    1078                 :     4518608 :   l->state_previously_known = IPA_NEITHER;
    1079                 :     4518608 :   l->looping_previously_known = true;
    1080                 :     4518608 :   l->looping = false;
    1081                 :     4518608 :   l->can_throw = false;
    1082                 :     4518608 :   l->can_free = false;
    1083                 :     4518608 :   state_from_flags (&l->state_previously_known, &l->looping_previously_known,
    1084                 :     4518608 :                     flags_from_decl_or_type (fn->decl),
    1085                 :     4518608 :                     fn->cannot_return_p ());
    1086                 :             : 
    1087                 :     4518608 :   if (fn->thunk || fn->alias)
    1088                 :             :     {
    1089                 :             :       /* Thunk gets propagated through, so nothing interesting happens.  */
    1090                 :       64468 :       gcc_assert (ipa);
    1091                 :       64468 :       if (fn->thunk && thunk_info::get (fn)->virtual_offset_p)
    1092                 :         739 :         l->pure_const_state = IPA_NEITHER;
    1093                 :       64468 :       return l;
    1094                 :             :     }
    1095                 :             : 
    1096                 :     4454140 :   if (dump_file)
    1097                 :             :     {
    1098                 :         189 :       fprintf (dump_file, "\n\n local analysis of %s\n ",
    1099                 :             :                fn->dump_name ());
    1100                 :             :     }
    1101                 :             : 
    1102                 :     4454140 :   push_cfun (DECL_STRUCT_FUNCTION (decl));
    1103                 :             : 
    1104                 :    34742830 :   FOR_EACH_BB_FN (this_block, cfun)
    1105                 :             :     {
    1106                 :    30348712 :       gimple_stmt_iterator gsi;
    1107                 :    30348712 :       struct walk_stmt_info wi;
    1108                 :             : 
    1109                 :    30348712 :       memset (&wi, 0, sizeof (wi));
    1110                 :    60697424 :       for (gsi = gsi_start_bb (this_block);
    1111                 :   201265598 :            !gsi_end_p (gsi);
    1112                 :   170916886 :            gsi_next (&gsi))
    1113                 :             :         {
    1114                 :             :           /* NULL memory accesses terminates BB.  These accesses are known
    1115                 :             :              to trip undefined behaviour.  gimple-ssa-isolate-paths turns them
    1116                 :             :              to volatile accesses and adds builtin_trap call which would
    1117                 :             :              confuse us otherwise.  */
    1118                 :   170979172 :           if (infer_nonnull_range_by_dereference (gsi_stmt (gsi),
    1119                 :             :                                                   null_pointer_node))
    1120                 :             :             {
    1121                 :        2264 :               if (dump_file)
    1122                 :           0 :                 fprintf (dump_file, "  NULL memory access; terminating BB%s\n",
    1123                 :           0 :                          flag_non_call_exceptions ? "; looping" : "");
    1124                 :        2264 :               if (flag_non_call_exceptions)
    1125                 :             :                 {
    1126                 :         424 :                   l->looping = true;
    1127                 :         424 :                   if (stmt_can_throw_external (cfun, gsi_stmt (gsi)))
    1128                 :             :                     {
    1129                 :         328 :                       if (dump_file)
    1130                 :           0 :                         fprintf (dump_file, "    can throw externally\n");
    1131                 :         328 :                       l->can_throw = true;
    1132                 :             :                     }
    1133                 :             :                 }
    1134                 :             :               break;
    1135                 :             :             }
    1136                 :   170976908 :           check_stmt (&gsi, l, ipa);
    1137                 :   170976908 :           if (l->pure_const_state == IPA_NEITHER
    1138                 :   109695373 :               && l->looping
    1139                 :    88695766 :               && l->can_throw
    1140                 :    42766650 :               && l->can_free)
    1141                 :       60022 :             goto end;
    1142                 :             :         }
    1143                 :             :     }
    1144                 :             : 
    1145                 :     4394118 : end:
    1146                 :     4454140 :   if (l->pure_const_state != IPA_NEITHER
    1147                 :     1965122 :       && !l->looping
    1148                 :     6238547 :       && !finite_function_p ())
    1149                 :       23563 :     l->looping = true;
    1150                 :             : 
    1151                 :     4454140 :   if (dump_file && (dump_flags & TDF_DETAILS))
    1152                 :          22 :     fprintf (dump_file, "    checking previously known:");
    1153                 :             : 
    1154                 :     4454140 :   better_state (&l->pure_const_state, &l->looping,
    1155                 :             :                 l->state_previously_known,
    1156                 :     4454140 :                 l->looping_previously_known);
    1157                 :     4454140 :   if (TREE_NOTHROW (decl))
    1158                 :     3031638 :     l->can_throw = false;
    1159                 :             : 
    1160                 :     4454140 :   l->malloc_state = STATE_MALLOC_BOTTOM;
    1161                 :     4454140 :   if (DECL_IS_MALLOC (decl))
    1162                 :        6253 :     l->malloc_state = STATE_MALLOC;
    1163                 :     4447887 :   else if (ipa && malloc_candidate_p (DECL_STRUCT_FUNCTION (decl), true))
    1164                 :       10808 :     l->malloc_state = STATE_MALLOC_TOP;
    1165                 :     4437079 :   else if (malloc_candidate_p (DECL_STRUCT_FUNCTION (decl), false))
    1166                 :       20962 :     l->malloc_state = STATE_MALLOC;
    1167                 :             : 
    1168                 :     4454140 :   pop_cfun ();
    1169                 :     4454140 :   if (dump_file)
    1170                 :             :     {
    1171                 :         189 :       if (l->looping)
    1172                 :          50 :         fprintf (dump_file, "Function is locally looping.\n");
    1173                 :         189 :       if (l->can_throw)
    1174                 :           6 :         fprintf (dump_file, "Function is locally throwing.\n");
    1175                 :         189 :       if (l->pure_const_state == IPA_CONST)
    1176                 :         102 :         fprintf (dump_file, "Function is locally const.\n");
    1177                 :         189 :       if (l->pure_const_state == IPA_PURE)
    1178                 :           7 :         fprintf (dump_file, "Function is locally pure.\n");
    1179                 :         189 :       if (l->can_free)
    1180                 :           3 :         fprintf (dump_file, "Function can locally free.\n");
    1181                 :         189 :       if (l->malloc_state == STATE_MALLOC)
    1182                 :           8 :         fprintf (dump_file, "Function is locally malloc.\n");
    1183                 :             :     }
    1184                 :             :   return l;
    1185                 :             : }
    1186                 :             : 
    1187                 :             : void
    1188                 :       17976 : funct_state_summary_t::insert (cgraph_node *node, funct_state_d *state)
    1189                 :             : {
    1190                 :             :   /* There are some shared nodes, in particular the initializers on
    1191                 :             :      static declarations.  We do not need to scan them more than once
    1192                 :             :      since all we would be interested in are the addressof
    1193                 :             :      operations.  */
    1194                 :       17976 :   if (opt_for_fn (node->decl, flag_ipa_pure_const))
    1195                 :             :     {
    1196                 :       17975 :       funct_state_d *a = analyze_function (node, true);
    1197                 :       17975 :       new (state) funct_state_d (*a);
    1198                 :       17975 :       free (a);
    1199                 :             :     }
    1200                 :             :   else
    1201                 :             :     /* Do not keep stale summaries.  */
    1202                 :           1 :     funct_state_summaries->remove (node);
    1203                 :       17976 : }
    1204                 :             : 
    1205                 :             : /* Called when new clone is inserted to callgraph late.  */
    1206                 :             : 
    1207                 :             : void
    1208                 :     1029004 : funct_state_summary_t::duplicate (cgraph_node *, cgraph_node *dst,
    1209                 :             :                                   funct_state_d *src_data,
    1210                 :             :                                   funct_state_d *dst_data)
    1211                 :             : {
    1212                 :     1029004 :   new (dst_data) funct_state_d (*src_data);
    1213                 :     1029004 :   if (dst_data->malloc_state == STATE_MALLOC
    1214                 :     1029004 :       && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (dst->decl))))
    1215                 :          11 :     dst_data->malloc_state = STATE_MALLOC_BOTTOM;
    1216                 :     1029004 : }
    1217                 :             : 
    1218                 :             : 
    1219                 :             : void
    1220                 :      157699 : pass_ipa_pure_const::
    1221                 :             : register_hooks (void)
    1222                 :             : {
    1223                 :      157699 :   if (init_p)
    1224                 :             :     return;
    1225                 :             : 
    1226                 :      157699 :   init_p = true;
    1227                 :             : 
    1228                 :      157699 :   funct_state_summaries = new funct_state_summary_t (symtab);
    1229                 :             : }
    1230                 :             : 
    1231                 :             : 
    1232                 :             : /* Analyze each function in the cgraph to see if it is locally PURE or
    1233                 :             :    CONST.  */
    1234                 :             : 
    1235                 :             : static void
    1236                 :      144885 : pure_const_generate_summary (void)
    1237                 :             : {
    1238                 :      144885 :   struct cgraph_node *node;
    1239                 :             : 
    1240                 :      144885 :   pass_ipa_pure_const *pass = static_cast <pass_ipa_pure_const *> (current_pass);
    1241                 :      144885 :   pass->register_hooks ();
    1242                 :             : 
    1243                 :             :   /* Process all of the functions.
    1244                 :             : 
    1245                 :             :      We process AVAIL_INTERPOSABLE functions.  We cannot use the results
    1246                 :             :      by default, but the info can be used at LTO with -fwhole-program or
    1247                 :             :      when function got cloned and the clone is AVAILABLE.  */
    1248                 :             : 
    1249                 :     1493489 :   FOR_EACH_DEFINED_FUNCTION (node)
    1250                 :     1348604 :     if (opt_for_fn (node->decl, flag_ipa_pure_const))
    1251                 :             :       {
    1252                 :     1348359 :         funct_state_d *a = analyze_function (node, true);
    1253                 :     1348359 :         new (funct_state_summaries->get_create (node)) funct_state_d (*a);
    1254                 :     1348359 :         free (a);
    1255                 :             :       }
    1256                 :      144885 : }
    1257                 :             : 
    1258                 :             : 
    1259                 :             : /* Serialize the ipa info for lto.  */
    1260                 :             : 
    1261                 :             : static void
    1262                 :       19142 : pure_const_write_summary (void)
    1263                 :             : {
    1264                 :       19142 :   struct cgraph_node *node;
    1265                 :       19142 :   struct lto_simple_output_block *ob
    1266                 :       19142 :     = lto_create_simple_output_block (LTO_section_ipa_pure_const);
    1267                 :       19142 :   unsigned int count = 0;
    1268                 :       19142 :   lto_symtab_encoder_iterator lsei;
    1269                 :       19142 :   lto_symtab_encoder_t encoder;
    1270                 :             : 
    1271                 :       19142 :   encoder = lto_get_out_decl_state ()->symtab_node_encoder;
    1272                 :             : 
    1273                 :      110050 :   for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
    1274                 :       90908 :        lsei_next_function_in_partition (&lsei))
    1275                 :             :     {
    1276                 :       90908 :       node = lsei_cgraph_node (lsei);
    1277                 :       90908 :       if (node->definition && funct_state_summaries->exists (node))
    1278                 :       90757 :         count++;
    1279                 :             :     }
    1280                 :             : 
    1281                 :       19142 :   streamer_write_uhwi_stream (ob->main_stream, count);
    1282                 :             : 
    1283                 :             :   /* Process all of the functions.  */
    1284                 :      110050 :   for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
    1285                 :       90908 :        lsei_next_function_in_partition (&lsei))
    1286                 :             :     {
    1287                 :       90908 :       node = lsei_cgraph_node (lsei);
    1288                 :       90908 :       funct_state_d *fs = funct_state_summaries->get (node);
    1289                 :       90908 :       if (node->definition && fs != NULL)
    1290                 :             :         {
    1291                 :       90757 :           struct bitpack_d bp;
    1292                 :       90757 :           int node_ref;
    1293                 :       90757 :           lto_symtab_encoder_t encoder;
    1294                 :             : 
    1295                 :       90757 :           encoder = ob->decl_state->symtab_node_encoder;
    1296                 :       90757 :           node_ref = lto_symtab_encoder_encode (encoder, node);
    1297                 :       90757 :           streamer_write_uhwi_stream (ob->main_stream, node_ref);
    1298                 :             : 
    1299                 :             :           /* Note that flags will need to be read in the opposite
    1300                 :             :              order as we are pushing the bitflags into FLAGS.  */
    1301                 :       90757 :           bp = bitpack_create (ob->main_stream);
    1302                 :       90757 :           bp_pack_value (&bp, fs->pure_const_state, 2);
    1303                 :       90757 :           bp_pack_value (&bp, fs->state_previously_known, 2);
    1304                 :       90757 :           bp_pack_value (&bp, fs->looping_previously_known, 1);
    1305                 :       90757 :           bp_pack_value (&bp, fs->looping, 1);
    1306                 :       90757 :           bp_pack_value (&bp, fs->can_throw, 1);
    1307                 :       90757 :           bp_pack_value (&bp, fs->can_free, 1);
    1308                 :       90757 :           bp_pack_value (&bp, fs->malloc_state, 2);
    1309                 :       90757 :           streamer_write_bitpack (&bp);
    1310                 :             :         }
    1311                 :             :     }
    1312                 :             : 
    1313                 :       19142 :   lto_destroy_simple_output_block (ob);
    1314                 :       19142 : }
    1315                 :             : 
    1316                 :             : 
    1317                 :             : /* Deserialize the ipa info for lto.  */
    1318                 :             : 
    1319                 :             : static void
    1320                 :       12814 : pure_const_read_summary (void)
    1321                 :             : {
    1322                 :       12814 :   struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
    1323                 :       12814 :   struct lto_file_decl_data *file_data;
    1324                 :       12814 :   unsigned int j = 0;
    1325                 :             : 
    1326                 :       12814 :   pass_ipa_pure_const *pass = static_cast <pass_ipa_pure_const *> (current_pass);
    1327                 :       12814 :   pass->register_hooks ();
    1328                 :             : 
    1329                 :       39467 :   while ((file_data = file_data_vec[j++]))
    1330                 :             :     {
    1331                 :       13839 :       const char *data;
    1332                 :       13839 :       size_t len;
    1333                 :       13839 :       class lto_input_block *ib
    1334                 :       13839 :         = lto_create_simple_input_block (file_data,
    1335                 :             :                                          LTO_section_ipa_pure_const,
    1336                 :             :                                          &data, &len);
    1337                 :       13839 :       if (ib)
    1338                 :             :         {
    1339                 :       10422 :           unsigned int i;
    1340                 :       10422 :           unsigned int count = streamer_read_uhwi (ib);
    1341                 :             : 
    1342                 :       86034 :           for (i = 0; i < count; i++)
    1343                 :             :             {
    1344                 :       75612 :               unsigned int index;
    1345                 :       75612 :               struct cgraph_node *node;
    1346                 :       75612 :               struct bitpack_d bp;
    1347                 :       75612 :               funct_state fs;
    1348                 :       75612 :               lto_symtab_encoder_t encoder;
    1349                 :             : 
    1350                 :       75612 :               index = streamer_read_uhwi (ib);
    1351                 :       75612 :               encoder = file_data->symtab_node_encoder;
    1352                 :       75612 :               node = dyn_cast<cgraph_node *> (lto_symtab_encoder_deref (encoder,
    1353                 :             :                                                                         index));
    1354                 :             : 
    1355                 :       75612 :               fs = funct_state_summaries->get_create (node);
    1356                 :             :               /* Note that the flags must be read in the opposite
    1357                 :             :                  order in which they were written (the bitflags were
    1358                 :             :                  pushed into FLAGS).  */
    1359                 :       75612 :               bp = streamer_read_bitpack (ib);
    1360                 :       75612 :               fs->pure_const_state
    1361                 :       75612 :                         = (enum pure_const_state_e) bp_unpack_value (&bp, 2);
    1362                 :       75612 :               fs->state_previously_known
    1363                 :       75612 :                         = (enum pure_const_state_e) bp_unpack_value (&bp, 2);
    1364                 :       75612 :               fs->looping_previously_known = bp_unpack_value (&bp, 1);
    1365                 :       75612 :               fs->looping = bp_unpack_value (&bp, 1);
    1366                 :       75612 :               fs->can_throw = bp_unpack_value (&bp, 1);
    1367                 :       75612 :               fs->can_free = bp_unpack_value (&bp, 1);
    1368                 :       75612 :               fs->malloc_state
    1369                 :       75612 :                         = (enum malloc_state_e) bp_unpack_value (&bp, 2);
    1370                 :             : 
    1371                 :       75612 :               if (dump_file)
    1372                 :             :                 {
    1373                 :           0 :                   int flags = flags_from_decl_or_type (node->decl);
    1374                 :           0 :                   fprintf (dump_file, "Read info for %s ", node->dump_name ());
    1375                 :           0 :                   if (flags & ECF_CONST)
    1376                 :           0 :                     fprintf (dump_file, " const");
    1377                 :           0 :                   if (flags & ECF_PURE)
    1378                 :           0 :                     fprintf (dump_file, " pure");
    1379                 :           0 :                   if (flags & ECF_NOTHROW)
    1380                 :           0 :                     fprintf (dump_file, " nothrow");
    1381                 :           0 :                   fprintf (dump_file, "\n  pure const state: %s\n",
    1382                 :           0 :                            pure_const_names[fs->pure_const_state]);
    1383                 :           0 :                   fprintf (dump_file, "  previously known state: %s\n",
    1384                 :           0 :                            pure_const_names[fs->state_previously_known]);
    1385                 :           0 :                   if (fs->looping)
    1386                 :           0 :                     fprintf (dump_file,"  function is locally looping\n");
    1387                 :           0 :                   if (fs->looping_previously_known)
    1388                 :           0 :                     fprintf (dump_file,"  function is previously known looping\n");
    1389                 :           0 :                   if (fs->can_throw)
    1390                 :           0 :                     fprintf (dump_file,"  function is locally throwing\n");
    1391                 :           0 :                   if (fs->can_free)
    1392                 :           0 :                     fprintf (dump_file,"  function can locally free\n");
    1393                 :           0 :                   fprintf (dump_file, "\n malloc state: %s\n",
    1394                 :           0 :                            malloc_state_names[fs->malloc_state]);
    1395                 :             :                 }
    1396                 :             :             }
    1397                 :             : 
    1398                 :       10422 :           lto_destroy_simple_input_block (file_data,
    1399                 :             :                                           LTO_section_ipa_pure_const,
    1400                 :             :                                           ib, data, len);
    1401                 :             :         }
    1402                 :             :     }
    1403                 :       12814 : }
    1404                 :             : 
    1405                 :             : /* We only propagate across edges that can throw externally and their callee
    1406                 :             :    is not interposable.  */
    1407                 :             : 
    1408                 :             : static bool
    1409                 :     6785928 : ignore_edge_for_nothrow (struct cgraph_edge *e)
    1410                 :             : {
    1411                 :     6785928 :   if (!e->can_throw_external || TREE_NOTHROW (e->callee->decl))
    1412                 :             :     return true;
    1413                 :             : 
    1414                 :     1918061 :   enum availability avail;
    1415                 :     1918061 :   cgraph_node *ultimate_target
    1416                 :     1918061 :     = e->callee->function_or_virtual_thunk_symbol (&avail, e->caller);
    1417                 :     1918061 :   if (avail <= AVAIL_INTERPOSABLE || TREE_NOTHROW (ultimate_target->decl))
    1418                 :             :     return true;
    1419                 :      644125 :   return ((opt_for_fn (e->callee->decl, flag_non_call_exceptions)
    1420                 :      201569 :            && !e->callee->binds_to_current_def_p (e->caller))
    1421                 :      644081 :           || !opt_for_fn (e->caller->decl, flag_ipa_pure_const)
    1422                 :     1287171 :           || !opt_for_fn (ultimate_target->decl, flag_ipa_pure_const));
    1423                 :             : }
    1424                 :             : 
    1425                 :             : /* Return true if NODE is self recursive function.
    1426                 :             :    Indirectly recursive functions appears as non-trivial strongly
    1427                 :             :    connected components, so we need to care about self recursion
    1428                 :             :    only.  */
    1429                 :             : 
    1430                 :             : static bool
    1431                 :     1909949 : self_recursive_p (struct cgraph_node *node)
    1432                 :             : {
    1433                 :     1909949 :   struct cgraph_edge *e;
    1434                 :     7455746 :   for (e = node->callees; e; e = e->next_callee)
    1435                 :     5549314 :     if (e->callee->function_symbol () == node)
    1436                 :             :       return true;
    1437                 :             :   return false;
    1438                 :             : }
    1439                 :             : 
    1440                 :             : /* Return true if N is cdtor that is not const or pure.  In this case we may
    1441                 :             :    need to remove unreachable function if it is marked const/pure.  */
    1442                 :             : 
    1443                 :             : static bool
    1444                 :       48018 : cdtor_p (cgraph_node *n, void *)
    1445                 :             : {
    1446                 :       48018 :   if (DECL_STATIC_CONSTRUCTOR (n->decl) || DECL_STATIC_DESTRUCTOR (n->decl))
    1447                 :           3 :     return ((!TREE_READONLY (n->decl) && !DECL_PURE_P (n->decl))
    1448                 :           3 :             || DECL_LOOPING_CONST_OR_PURE_P (n->decl));
    1449                 :             :   return false;
    1450                 :             : }
    1451                 :             : 
    1452                 :             : /* Skip edges from and to nodes without ipa_pure_const enabled.
    1453                 :             :    Ignore not available symbols.  */
    1454                 :             : 
    1455                 :             : static bool
    1456                 :     6785928 : ignore_edge_for_pure_const (struct cgraph_edge *e)
    1457                 :             : {
    1458                 :     6785928 :   enum availability avail;
    1459                 :     6785928 :   cgraph_node *ultimate_target
    1460                 :     6785928 :     = e->callee->function_or_virtual_thunk_symbol (&avail, e->caller);
    1461                 :             : 
    1462                 :     6785928 :   return (avail <= AVAIL_INTERPOSABLE
    1463                 :     2313009 :           || !opt_for_fn (e->caller->decl, flag_ipa_pure_const)
    1464                 :     9089929 :           || !opt_for_fn (ultimate_target->decl,
    1465                 :     6785928 :                           flag_ipa_pure_const));
    1466                 :             : }
    1467                 :             : 
    1468                 :             : /* Return true if function should be skipped for local pure const analysis.  */
    1469                 :             : 
    1470                 :             : static bool
    1471                 :     4498009 : skip_function_for_local_pure_const (struct cgraph_node *node)
    1472                 :             : {
    1473                 :             :   /* Because we do not schedule pass_fixup_cfg over whole program after early
    1474                 :             :      optimizations we must not promote functions that are called by already
    1475                 :             :      processed functions.  */
    1476                 :             : 
    1477                 :     4498009 :   if (function_called_by_processed_nodes_p ())
    1478                 :             :     {
    1479                 :        4664 :       if (dump_file)
    1480                 :           1 :         fprintf (dump_file, "Function called in recursive cycle; ignoring\n");
    1481                 :        4664 :       return true;
    1482                 :             :     }
    1483                 :             :   /* Save some work and do not analyze functions which are interposable and
    1484                 :             :      do not have any non-interposable aliases.  */
    1485                 :     4493345 :   if (node->get_availability () <= AVAIL_INTERPOSABLE
    1486                 :      202373 :       && !flag_lto
    1487                 :     4689058 :       && !node->has_aliases_p ())
    1488                 :             :     {
    1489                 :      186405 :       if (dump_file)
    1490                 :           0 :         fprintf (dump_file,
    1491                 :             :                  "Function is interposable; not analyzing.\n");
    1492                 :      186405 :       return true;
    1493                 :             :     }
    1494                 :             :   return false;
    1495                 :             : }
    1496                 :             : 
    1497                 :             : /* Make function const and output warning.  If LOCAL is true,
    1498                 :             :    return true if anything changed.  Otherwise return true if
    1499                 :             :    we may have introduced removale ctors.  */
    1500                 :             : 
    1501                 :             : bool
    1502                 :     1516085 : ipa_make_function_const (struct cgraph_node *node, bool looping, bool local)
    1503                 :             : {
    1504                 :     1516085 :   bool cdtor = false;
    1505                 :             : 
    1506                 :     1516085 :   if (TREE_READONLY (node->decl)
    1507                 :     1516085 :       && (looping || !DECL_LOOPING_CONST_OR_PURE_P (node->decl)))
    1508                 :             :     return false;
    1509                 :      894039 :   warn_function_const (node->decl, !looping);
    1510                 :      894039 :   if (local && skip_function_for_local_pure_const (node))
    1511                 :             :     return false;
    1512                 :      875165 :   if (dump_file)
    1513                 :          58 :     fprintf (dump_file, "Function found to be %sconst: %s\n",
    1514                 :             :              looping ? "looping " : "",
    1515                 :             :              node->dump_name ());
    1516                 :      875165 :   if (!local && !looping)
    1517                 :       41848 :     cdtor = node->call_for_symbol_and_aliases (cdtor_p, NULL, true);
    1518                 :      875165 :   if (!dbg_cnt (ipa_attr))
    1519                 :             :     return false;
    1520                 :      875165 :   if (node->set_const_flag (true, looping))
    1521                 :             :     {
    1522                 :      492494 :       if (dump_file)
    1523                 :          58 :         fprintf (dump_file,
    1524                 :             :                  "Declaration updated to be %sconst: %s\n",
    1525                 :             :                  looping ? "looping " : "",
    1526                 :             :                  node->dump_name ());
    1527                 :      492494 :       if (local)
    1528                 :             :         return true;
    1529                 :        2571 :       return cdtor;
    1530                 :             :     }
    1531                 :             :   return false;
    1532                 :             : }
    1533                 :             : 
    1534                 :             : /* Make function const and output warning.  If LOCAL is true,
    1535                 :             :    return true if anything changed.  Otherwise return true if
    1536                 :             :    we may have introduced removale ctors.  */
    1537                 :             : 
    1538                 :             : bool
    1539                 :      997131 : ipa_make_function_pure (struct cgraph_node *node, bool looping, bool local)
    1540                 :             : {
    1541                 :      997131 :   bool cdtor = false;
    1542                 :             : 
    1543                 :      997131 :   if (TREE_READONLY (node->decl)
    1544                 :      997131 :       || (DECL_PURE_P (node->decl)
    1545                 :      648092 :           && (looping || !DECL_LOOPING_CONST_OR_PURE_P (node->decl))))
    1546                 :             :     return false;
    1547                 :      348270 :   warn_function_pure (node->decl, !looping);
    1548                 :      348270 :   if (local && skip_function_for_local_pure_const (node))
    1549                 :             :     return false;
    1550                 :      339538 :   if (dump_file)
    1551                 :           8 :     fprintf (dump_file, "Function found to be %spure: %s\n",
    1552                 :             :              looping ? "looping " : "",
    1553                 :             :              node->dump_name ());
    1554                 :      339538 :   if (!local && !looping)
    1555                 :        3215 :     cdtor = node->call_for_symbol_and_aliases (cdtor_p, NULL, true);
    1556                 :      339538 :   if (!dbg_cnt (ipa_attr))
    1557                 :             :     return false;
    1558                 :      339538 :   if (node->set_pure_flag (true, looping))
    1559                 :             :     {
    1560                 :      328242 :       if (dump_file)
    1561                 :           8 :         fprintf (dump_file,
    1562                 :             :                  "Declaration updated to be %spure: %s\n",
    1563                 :             :                  looping ? "looping " : "",
    1564                 :             :                  node->dump_name ());
    1565                 :      328242 :       if (local)
    1566                 :             :         return true;
    1567                 :        7349 :       return cdtor;
    1568                 :             :     }
    1569                 :             :   return false;
    1570                 :             : }
    1571                 :             : 
    1572                 :             : /* Produce transitive closure over the callgraph and compute pure/const
    1573                 :             :    attributes.  */
    1574                 :             : 
    1575                 :             : static bool
    1576                 :      148840 : propagate_pure_const (void)
    1577                 :             : {
    1578                 :      148840 :   struct cgraph_node *node;
    1579                 :      148840 :   struct cgraph_node *w;
    1580                 :      148840 :   struct cgraph_node **order =
    1581                 :      148840 :     XCNEWVEC (struct cgraph_node *, symtab->cgraph_count);
    1582                 :      148840 :   int order_pos;
    1583                 :      148840 :   int i;
    1584                 :      148840 :   struct ipa_dfs_info * w_info;
    1585                 :      148840 :   bool remove_p = false;
    1586                 :             : 
    1587                 :      148840 :   order_pos = ipa_reduced_postorder (order, true,
    1588                 :             :                                      ignore_edge_for_pure_const);
    1589                 :      148840 :   if (dump_file)
    1590                 :             :     {
    1591                 :          29 :       cgraph_node::dump_cgraph (dump_file);
    1592                 :          29 :       ipa_print_order (dump_file, "reduced", order, order_pos);
    1593                 :             :     }
    1594                 :             : 
    1595                 :             :   /* Propagate the local information through the call graph to produce
    1596                 :             :      the global information.  All the nodes within a cycle will have
    1597                 :             :      the same info so we collapse cycles first.  Then we can do the
    1598                 :             :      propagation in one pass from the leaves to the roots.  */
    1599                 :     2346419 :   for (i = 0; i < order_pos; i++ )
    1600                 :             :     {
    1601                 :     2197579 :       enum pure_const_state_e pure_const_state = IPA_CONST;
    1602                 :     2197579 :       bool looping = false;
    1603                 :     2197579 :       int count = 0;
    1604                 :     2197579 :       node = order[i];
    1605                 :             : 
    1606                 :     2197579 :       if (node->alias)
    1607                 :       36138 :         continue;
    1608                 :             : 
    1609                 :     2161441 :       if (dump_file && (dump_flags & TDF_DETAILS))
    1610                 :           5 :         fprintf (dump_file, "Starting cycle\n");
    1611                 :             : 
    1612                 :             :       /* Find the worst state for any node in the cycle.  */
    1613                 :             :       w = node;
    1614                 :     3649951 :       while (w && pure_const_state != IPA_NEITHER)
    1615                 :             :         {
    1616                 :     2164257 :           struct cgraph_edge *e;
    1617                 :     2164257 :           struct cgraph_edge *ie;
    1618                 :     2164257 :           int i;
    1619                 :     2164257 :           struct ipa_ref *ref = NULL;
    1620                 :             : 
    1621                 :     2164257 :           funct_state w_l = funct_state_summaries->get_create (w);
    1622                 :     2164257 :           if (dump_file && (dump_flags & TDF_DETAILS))
    1623                 :           6 :             fprintf (dump_file, "  Visiting %s state:%s looping %i\n",
    1624                 :             :                      w->dump_name (),
    1625                 :           6 :                      pure_const_names[w_l->pure_const_state],
    1626                 :           6 :                      w_l->looping);
    1627                 :             : 
    1628                 :             :           /* First merge in function body properties.
    1629                 :             :              We are safe to pass NULL as FROM and TO because we will take care
    1630                 :             :              of possible interposition when walking callees.  */
    1631                 :     2164257 :           worse_state (&pure_const_state, &looping,
    1632                 :     2164257 :                        w_l->pure_const_state, w_l->looping,
    1633                 :             :                        NULL, NULL);
    1634                 :     2164257 :           if (pure_const_state == IPA_NEITHER)
    1635                 :             :             break;
    1636                 :             : 
    1637                 :     1488510 :           count++;
    1638                 :             : 
    1639                 :             :           /* We consider recursive cycles as possibly infinite.
    1640                 :             :              This might be relaxed since infinite recursion leads to stack
    1641                 :             :              overflow.  */
    1642                 :     1488510 :           if (count > 1)
    1643                 :        2816 :             looping = true;
    1644                 :             : 
    1645                 :             :           /* Now walk the edges and merge in callee properties.  */
    1646                 :     2285239 :           for (e = w->callees; e && pure_const_state != IPA_NEITHER;
    1647                 :      796729 :                e = e->next_callee)
    1648                 :             :             {
    1649                 :     1782571 :               enum availability avail;
    1650                 :     1782571 :               struct cgraph_node *y = e->callee->
    1651                 :     3565142 :                                 function_or_virtual_thunk_symbol (&avail,
    1652                 :     1782571 :                                                                   e->caller);
    1653                 :     1782571 :               enum pure_const_state_e edge_state = IPA_CONST;
    1654                 :     1782571 :               bool edge_looping = false;
    1655                 :             : 
    1656                 :     1782571 :               if (e->recursive_p ())
    1657                 :        6052 :                 looping = true;
    1658                 :             : 
    1659                 :     1782571 :               if (dump_file && (dump_flags & TDF_DETAILS))
    1660                 :             :                 {
    1661                 :           7 :                   fprintf (dump_file, "    Call to %s",
    1662                 :           7 :                            e->callee->dump_name ());
    1663                 :             :                 }
    1664                 :     1782571 :               if (avail > AVAIL_INTERPOSABLE)
    1665                 :             :                 {
    1666                 :      593775 :                   funct_state y_l = funct_state_summaries->get_create (y);
    1667                 :             : 
    1668                 :      593775 :                   if (dump_file && (dump_flags & TDF_DETAILS))
    1669                 :             :                     {
    1670                 :           2 :                       fprintf (dump_file,
    1671                 :             :                                " state:%s looping:%i\n",
    1672                 :           2 :                                pure_const_names[y_l->pure_const_state],
    1673                 :           2 :                                y_l->looping);
    1674                 :             :                     }
    1675                 :      593775 :                   if (y_l->pure_const_state > IPA_PURE
    1676                 :      593775 :                       && e->cannot_lead_to_return_p ())
    1677                 :             :                     {
    1678                 :        8194 :                       if (dump_file && (dump_flags & TDF_DETAILS))
    1679                 :           0 :                         fprintf (dump_file,
    1680                 :             :                                  "        Ignoring side effects"
    1681                 :             :                                  " -> pure, looping\n");
    1682                 :        8194 :                       edge_state = IPA_PURE;
    1683                 :        8194 :                       edge_looping = true;
    1684                 :             :                     }
    1685                 :             :                   else
    1686                 :             :                     {
    1687                 :      585581 :                       edge_state = y_l->pure_const_state;
    1688                 :      585581 :                       edge_looping = y_l->looping;
    1689                 :             :                     }
    1690                 :             :                 }
    1691                 :     1188796 :               else if (builtin_safe_for_const_function_p (&edge_looping,
    1692                 :             :                                                            y->decl))
    1693                 :             :                 edge_state = IPA_CONST;
    1694                 :             :               else
    1695                 :     1047673 :                 state_from_flags (&edge_state, &edge_looping,
    1696                 :     1047673 :                                   flags_from_decl_or_type (y->decl),
    1697                 :     1047673 :                                   e->cannot_lead_to_return_p ());
    1698                 :             : 
    1699                 :             :               /* Merge the results with what we already know.  */
    1700                 :     1782571 :               better_state (&edge_state, &edge_looping,
    1701                 :             :                             w_l->state_previously_known,
    1702                 :     1782571 :                             w_l->looping_previously_known);
    1703                 :     1782571 :               worse_state (&pure_const_state, &looping,
    1704                 :     1782571 :                            edge_state, edge_looping, e->caller, e->callee);
    1705                 :     1782571 :               if (pure_const_state == IPA_NEITHER)
    1706                 :             :                 break;
    1707                 :             :             }
    1708                 :             : 
    1709                 :             :           /* Now process the indirect call.  */
    1710                 :     1488510 :           for (ie = w->indirect_calls;
    1711                 :     1489210 :                ie && pure_const_state != IPA_NEITHER; ie = ie->next_callee)
    1712                 :             :             {
    1713                 :       26200 :               enum pure_const_state_e edge_state = IPA_CONST;
    1714                 :       26200 :               bool edge_looping = false;
    1715                 :             : 
    1716                 :       26200 :               if (dump_file && (dump_flags & TDF_DETAILS))
    1717                 :           0 :                 fprintf (dump_file, "    Indirect call");
    1718                 :       52400 :               state_from_flags (&edge_state, &edge_looping,
    1719                 :       26200 :                                 ie->indirect_info->ecf_flags,
    1720                 :       26200 :                                 ie->cannot_lead_to_return_p ());
    1721                 :             :               /* Merge the results with what we already know.  */
    1722                 :       26200 :               better_state (&edge_state, &edge_looping,
    1723                 :             :                             w_l->state_previously_known,
    1724                 :       26200 :                             w_l->looping_previously_known);
    1725                 :       26200 :               worse_state (&pure_const_state, &looping,
    1726                 :             :                            edge_state, edge_looping, NULL, NULL);
    1727                 :       26200 :               if (pure_const_state == IPA_NEITHER)
    1728                 :             :                 break;
    1729                 :             :             }
    1730                 :             : 
    1731                 :             :           /* And finally all loads and stores.  */
    1732                 :      312544 :           for (i = 0; w->iterate_reference (i, ref)
    1733                 :     2436150 :                && pure_const_state != IPA_NEITHER; i++)
    1734                 :             :             {
    1735                 :      339069 :               enum pure_const_state_e ref_state = IPA_CONST;
    1736                 :      339069 :               bool ref_looping = false;
    1737                 :      339069 :               switch (ref->use)
    1738                 :             :                 {
    1739                 :      215196 :                 case IPA_REF_LOAD:
    1740                 :             :                   /* readonly reads are safe.  */
    1741                 :      215196 :                   if (TREE_READONLY (ref->referred->decl))
    1742                 :             :                     break;
    1743                 :      201573 :                   if (dump_file && (dump_flags & TDF_DETAILS))
    1744                 :           0 :                     fprintf (dump_file, "    nonreadonly global var read\n");
    1745                 :      201573 :                   ref_state = IPA_PURE;
    1746                 :      201573 :                   break;
    1747                 :       88182 :                 case IPA_REF_STORE:
    1748                 :       88182 :                   if (ref->cannot_lead_to_return ())
    1749                 :             :                     break;
    1750                 :       26589 :                   ref_state = IPA_NEITHER;
    1751                 :       26589 :                   if (dump_file && (dump_flags & TDF_DETAILS))
    1752                 :           0 :                     fprintf (dump_file, "    global var write\n");
    1753                 :             :                   break;
    1754                 :             :                 case IPA_REF_ADDR:
    1755                 :             :                   break;
    1756                 :           0 :                 default:
    1757                 :           0 :                   gcc_unreachable ();
    1758                 :             :                 }
    1759                 :      339069 :               better_state (&ref_state, &ref_looping,
    1760                 :             :                             w_l->state_previously_known,
    1761                 :      339069 :                             w_l->looping_previously_known);
    1762                 :      339069 :               worse_state (&pure_const_state, &looping,
    1763                 :             :                            ref_state, ref_looping, NULL, NULL);
    1764                 :      339069 :               if (pure_const_state == IPA_NEITHER)
    1765                 :             :                 break;
    1766                 :             :             }
    1767                 :     1488510 :           w_info = (struct ipa_dfs_info *) w->aux;
    1768                 :     1488510 :           w = w_info->next_cycle;
    1769                 :             :         }
    1770                 :     2161441 :       if (dump_file && (dump_flags & TDF_DETAILS))
    1771                 :           5 :         fprintf (dump_file, "Result %s looping %i\n",
    1772                 :           5 :                  pure_const_names [pure_const_state],
    1773                 :             :                  looping);
    1774                 :             : 
    1775                 :             :       /* Find the worst state of can_free for any node in the cycle.  */
    1776                 :             :       bool can_free = false;
    1777                 :             :       w = node;
    1778                 :     4326212 :       while (w && !can_free)
    1779                 :             :         {
    1780                 :     2164771 :           struct cgraph_edge *e;
    1781                 :     2164771 :           funct_state w_l = funct_state_summaries->get (w);
    1782                 :             : 
    1783                 :     2164771 :           if (w_l->can_free
    1784                 :     1982430 :               || w->get_availability () == AVAIL_INTERPOSABLE
    1785                 :     4069689 :               || w->indirect_calls)
    1786                 :             :             can_free = true;
    1787                 :             : 
    1788                 :     3737373 :           for (e = w->callees; e && !can_free; e = e->next_callee)
    1789                 :             :             {
    1790                 :     1572602 :               enum availability avail;
    1791                 :     1572602 :               struct cgraph_node *y = e->callee->
    1792                 :     3145204 :                                 function_or_virtual_thunk_symbol (&avail,
    1793                 :     1572602 :                                                                   e->caller);
    1794                 :             : 
    1795                 :     1572602 :               if (avail > AVAIL_INTERPOSABLE)
    1796                 :      724143 :                 can_free = funct_state_summaries->get (y)->can_free;
    1797                 :             :               else
    1798                 :             :                 can_free = true;
    1799                 :             :             }
    1800                 :     2164771 :           w_info = (struct ipa_dfs_info *) w->aux;
    1801                 :     2164771 :           w = w_info->next_cycle;
    1802                 :             :         }
    1803                 :             : 
    1804                 :             :       /* Copy back the region's pure_const_state which is shared by
    1805                 :             :          all nodes in the region.  */
    1806                 :             :       w = node;
    1807                 :     4344670 :       while (w)
    1808                 :             :         {
    1809                 :     2183229 :           funct_state w_l = funct_state_summaries->get (w);
    1810                 :     2183229 :           enum pure_const_state_e this_state = pure_const_state;
    1811                 :     2183229 :           bool this_looping = looping;
    1812                 :             : 
    1813                 :     2183229 :           w_l->can_free = can_free;
    1814                 :     2183229 :           w->nonfreeing_fn = !can_free;
    1815                 :     2183229 :           if (!can_free && dump_file)
    1816                 :          28 :             fprintf (dump_file, "Function found not to call free: %s\n",
    1817                 :             :                      w->dump_name ());
    1818                 :             : 
    1819                 :     2183229 :           if (w_l->state_previously_known != IPA_NEITHER
    1820                 :      367415 :               && this_state > w_l->state_previously_known)
    1821                 :             :             {
    1822                 :        1159 :               if (this_state == IPA_NEITHER)
    1823                 :          50 :                 this_looping = w_l->looping_previously_known;
    1824                 :             :               this_state = w_l->state_previously_known;
    1825                 :             :             }
    1826                 :     2183229 :           if (!this_looping && self_recursive_p (w))
    1827                 :             :             this_looping = true;
    1828                 :     2183229 :           if (!w_l->looping_previously_known)
    1829                 :      282653 :             this_looping = false;
    1830                 :             : 
    1831                 :             :           /* All nodes within a cycle share the same info.  */
    1832                 :     2183229 :           w_l->pure_const_state = this_state;
    1833                 :     2183229 :           w_l->looping = this_looping;
    1834                 :             : 
    1835                 :             :           /* Inline clones share declaration with their offline copies;
    1836                 :             :              do not modify their declarations since the offline copy may
    1837                 :             :              be different.  */
    1838                 :     2183229 :           if (!w->inlined_to)
    1839                 :     1012959 :             switch (this_state)
    1840                 :             :               {
    1841                 :      158588 :               case IPA_CONST:
    1842                 :      158588 :                 remove_p |= ipa_make_function_const (w, this_looping, false);
    1843                 :      158588 :                 break;
    1844                 :             : 
    1845                 :       95096 :               case IPA_PURE:
    1846                 :       95096 :                 remove_p |= ipa_make_function_pure (w, this_looping, false);
    1847                 :       95096 :                 break;
    1848                 :             : 
    1849                 :             :               default:
    1850                 :             :                 break;
    1851                 :             :               }
    1852                 :     2183229 :           w_info = (struct ipa_dfs_info *) w->aux;
    1853                 :     2183229 :           w = w_info->next_cycle;
    1854                 :             :         }
    1855                 :             :     }
    1856                 :             : 
    1857                 :      148840 :   ipa_free_postorder_info ();
    1858                 :      148840 :   free (order);
    1859                 :      148840 :   return remove_p;
    1860                 :             : }
    1861                 :             : 
    1862                 :             : /* Produce transitive closure over the callgraph and compute nothrow
    1863                 :             :    attributes.  */
    1864                 :             : 
    1865                 :             : static void
    1866                 :      148840 : propagate_nothrow (void)
    1867                 :             : {
    1868                 :      148840 :   struct cgraph_node *node;
    1869                 :      148840 :   struct cgraph_node *w;
    1870                 :      148840 :   struct cgraph_node **order =
    1871                 :      148840 :     XCNEWVEC (struct cgraph_node *, symtab->cgraph_count);
    1872                 :      148840 :   int order_pos;
    1873                 :      148840 :   int i;
    1874                 :      148840 :   struct ipa_dfs_info * w_info;
    1875                 :             : 
    1876                 :      148840 :   order_pos = ipa_reduced_postorder (order, true,
    1877                 :             :                                      ignore_edge_for_nothrow);
    1878                 :      148840 :   if (dump_file)
    1879                 :             :     {
    1880                 :          29 :       cgraph_node::dump_cgraph (dump_file);
    1881                 :          29 :       ipa_print_order (dump_file, "reduced for nothrow", order, order_pos);
    1882                 :             :     }
    1883                 :             : 
    1884                 :             :   /* Propagate the local information through the call graph to produce
    1885                 :             :      the global information.  All the nodes within a cycle will have
    1886                 :             :      the same info so we collapse cycles first.  Then we can do the
    1887                 :             :      propagation in one pass from the leaves to the roots.  */
    1888                 :     2363169 :   for (i = 0; i < order_pos; i++ )
    1889                 :             :     {
    1890                 :     2214329 :       bool can_throw = false;
    1891                 :     2214329 :       node = order[i];
    1892                 :             : 
    1893                 :     2214329 :       if (node->alias)
    1894                 :       36138 :         continue;
    1895                 :             : 
    1896                 :             :       /* Find the worst state for any node in the cycle.  */
    1897                 :             :       w = node;
    1898                 :     4356538 :       while (w && !can_throw)
    1899                 :             :         {
    1900                 :     2178347 :           struct cgraph_edge *e, *ie;
    1901                 :             : 
    1902                 :     2178347 :           if (!TREE_NOTHROW (w->decl))
    1903                 :             :             {
    1904                 :      868245 :               funct_state w_l = funct_state_summaries->get_create (w);
    1905                 :             : 
    1906                 :      868245 :               if (w_l->can_throw
    1907                 :      868245 :                   || w->get_availability () == AVAIL_INTERPOSABLE)
    1908                 :             :                 can_throw = true;
    1909                 :             : 
    1910                 :     1606544 :               for (e = w->callees; e && !can_throw; e = e->next_callee)
    1911                 :             :                 {
    1912                 :      738299 :                   enum availability avail;
    1913                 :             : 
    1914                 :      738299 :                   if (!e->can_throw_external || TREE_NOTHROW (e->callee->decl))
    1915                 :      196161 :                     continue;
    1916                 :             : 
    1917                 :      542138 :                   struct cgraph_node *y = e->callee->
    1918                 :     1084276 :                                    function_or_virtual_thunk_symbol (&avail,
    1919                 :      542138 :                                                                      e->caller);
    1920                 :             : 
    1921                 :             :                   /* We can use info about the callee only if we know it
    1922                 :             :                      cannot be interposed.
    1923                 :             :                      When callee is compiled with non-call exceptions we also
    1924                 :             :                      must check that the declaration is bound to current
    1925                 :             :                      body as other semantically equivalent body may still
    1926                 :             :                      throw.  */
    1927                 :      542138 :                   if (avail <= AVAIL_INTERPOSABLE
    1928                 :      542138 :                       || (!TREE_NOTHROW (y->decl)
    1929                 :      263730 :                           && (funct_state_summaries->get_create (y)->can_throw
    1930                 :        2186 :                               || (opt_for_fn (y->decl, flag_non_call_exceptions)
    1931                 :         550 :                                   && !e->callee->binds_to_current_def_p (w)))))
    1932                 :             :                     can_throw = true;
    1933                 :             :                 }
    1934                 :      882053 :               for (ie = w->indirect_calls; ie && !can_throw;
    1935                 :       13808 :                    ie = ie->next_callee)
    1936                 :       13808 :                 if (ie->can_throw_external
    1937                 :       12336 :                     && !(ie->indirect_info->ecf_flags & ECF_NOTHROW))
    1938                 :       13808 :                   can_throw = true;
    1939                 :             :             }
    1940                 :     2178347 :           w_info = (struct ipa_dfs_info *) w->aux;
    1941                 :     2178347 :           w = w_info->next_cycle;
    1942                 :             :         }
    1943                 :             : 
    1944                 :             :       /* Copy back the region's pure_const_state which is shared by
    1945                 :             :          all nodes in the region.  */
    1946                 :             :       w = node;
    1947                 :     4361420 :       while (w)
    1948                 :             :         {
    1949                 :     2183229 :           funct_state w_l = funct_state_summaries->get_create (w);
    1950                 :     2183229 :           if (!can_throw && !TREE_NOTHROW (w->decl))
    1951                 :             :             {
    1952                 :             :               /* Inline clones share declaration with their offline copies;
    1953                 :             :                  do not modify their declarations since the offline copy may
    1954                 :             :                  be different.  */
    1955                 :       12713 :               if (!w->inlined_to)
    1956                 :             :                 {
    1957                 :        2867 :                   w->set_nothrow_flag (true);
    1958                 :        2867 :                   if (dump_file)
    1959                 :           0 :                     fprintf (dump_file, "Function found to be nothrow: %s\n",
    1960                 :             :                              w->dump_name ());
    1961                 :             :                 }
    1962                 :             :             }
    1963                 :      860378 :           else if (can_throw && !TREE_NOTHROW (w->decl))
    1964                 :      860378 :             w_l->can_throw = true;
    1965                 :     2183229 :           w_info = (struct ipa_dfs_info *) w->aux;
    1966                 :     2183229 :           w = w_info->next_cycle;
    1967                 :             :         }
    1968                 :             :     }
    1969                 :             : 
    1970                 :      148840 :   ipa_free_postorder_info ();
    1971                 :      148840 :   free (order);
    1972                 :      148840 : }
    1973                 :             : 
    1974                 :             : /* Debugging function to dump state of malloc lattice.  */
    1975                 :             : 
    1976                 :             : DEBUG_FUNCTION
    1977                 :             : static void
    1978                 :      297680 : dump_malloc_lattice (FILE *dump_file, const char *s)
    1979                 :             : {
    1980                 :      297680 :   if (!dump_file)
    1981                 :             :     return;
    1982                 :             : 
    1983                 :          58 :   fprintf (dump_file, "\n\nMALLOC LATTICE %s:\n", s);
    1984                 :          58 :   cgraph_node *node;
    1985                 :         580 :   FOR_EACH_FUNCTION (node)
    1986                 :             :     {
    1987                 :         232 :       funct_state fs = funct_state_summaries->get (node);
    1988                 :         232 :       if (fs)
    1989                 :         156 :         fprintf (dump_file, "%s: %s\n", node->dump_name (),
    1990                 :         156 :                  malloc_state_names[fs->malloc_state]);
    1991                 :             :     }
    1992                 :             : }
    1993                 :             : 
    1994                 :             : /* Propagate malloc attribute across the callgraph.  */
    1995                 :             : 
    1996                 :             : static void
    1997                 :      148840 : propagate_malloc (void)
    1998                 :             : {
    1999                 :      148840 :   cgraph_node *node;
    2000                 :     7506150 :   FOR_EACH_FUNCTION (node)
    2001                 :             :     {
    2002                 :     3604235 :       if (DECL_IS_MALLOC (node->decl))
    2003                 :       44546 :         if (!funct_state_summaries->exists (node))
    2004                 :             :           {
    2005                 :       21226 :             funct_state fs = funct_state_summaries->get_create (node);
    2006                 :       21226 :             fs->malloc_state = STATE_MALLOC;
    2007                 :             :           }
    2008                 :             :     }
    2009                 :             : 
    2010                 :      148840 :   dump_malloc_lattice (dump_file, "Initial");
    2011                 :      148840 :   struct cgraph_node **order
    2012                 :      148840 :     = XNEWVEC (struct cgraph_node *, symtab->cgraph_count);
    2013                 :      148840 :   int order_pos = ipa_reverse_postorder (order);
    2014                 :      148840 :   bool changed = true;
    2015                 :             : 
    2016                 :      448283 :   while (changed)
    2017                 :             :     {
    2018                 :      150603 :       changed = false;
    2019                 :             :       /* Walk in postorder.  */
    2020                 :     4429224 :       for (int i = order_pos - 1; i >= 0; --i)
    2021                 :             :         {
    2022                 :     4278621 :           cgraph_node *node = order[i];
    2023                 :     5844905 :           if (node->alias
    2024                 :     4278621 :               || !node->definition
    2025                 :     4278621 :               || !funct_state_summaries->exists (node))
    2026                 :     4226751 :             continue;
    2027                 :             : 
    2028                 :     2712337 :           funct_state l = funct_state_summaries->get (node);
    2029                 :             : 
    2030                 :             :           /* FIXME: add support for indirect-calls.  */
    2031                 :     2712337 :           if (node->indirect_calls)
    2032                 :             :             {
    2033                 :      138328 :               l->malloc_state = STATE_MALLOC_BOTTOM;
    2034                 :      138328 :               continue;
    2035                 :             :             }
    2036                 :             : 
    2037                 :     2574009 :           if (node->get_availability () <= AVAIL_INTERPOSABLE)
    2038                 :             :             {
    2039                 :       90593 :               l->malloc_state = STATE_MALLOC_BOTTOM;
    2040                 :       90593 :               continue;
    2041                 :             :             }
    2042                 :             : 
    2043                 :     2483416 :           if (l->malloc_state == STATE_MALLOC_BOTTOM)
    2044                 :     2431546 :             continue;
    2045                 :             : 
    2046                 :       51870 :           auto_vec<cgraph_node *, 16> callees;
    2047                 :      200642 :           for (cgraph_edge *cs = node->callees; cs; cs = cs->next_callee)
    2048                 :             :             {
    2049                 :      148772 :               ipa_call_summary *es = ipa_call_summaries->get_create (cs);
    2050                 :      148772 :               if (es && es->is_return_callee_uncaptured)
    2051                 :       12636 :                 callees.safe_push (cs->callee);
    2052                 :             :             }
    2053                 :             : 
    2054                 :       51870 :           malloc_state_e new_state = l->malloc_state;
    2055                 :       64506 :           for (unsigned j = 0; j < callees.length (); j++)
    2056                 :             :             {
    2057                 :       12636 :               cgraph_node *callee = callees[j];
    2058                 :       12636 :               if (!funct_state_summaries->exists (node))
    2059                 :             :                 {
    2060                 :             :                   new_state = STATE_MALLOC_BOTTOM;
    2061                 :             :                   break;
    2062                 :             :                 }
    2063                 :       12636 :               malloc_state_e callee_state
    2064                 :       12636 :                 = funct_state_summaries->get_create (callee)->malloc_state;
    2065                 :       12636 :               if (new_state < callee_state)
    2066                 :       10776 :                 new_state = callee_state;
    2067                 :             :             }
    2068                 :       51870 :           if (new_state != l->malloc_state)
    2069                 :             :             {
    2070                 :       10758 :               changed = true;
    2071                 :       10758 :               l->malloc_state = new_state;
    2072                 :             :             }
    2073                 :       51870 :         }
    2074                 :             :     }
    2075                 :             : 
    2076                 :     2368211 :   FOR_EACH_DEFINED_FUNCTION (node)
    2077                 :     2219371 :     if (funct_state_summaries->exists (node))
    2078                 :             :       {
    2079                 :     2207744 :         funct_state l = funct_state_summaries->get (node);
    2080                 :     2207744 :         if (!node->alias
    2081                 :     2183229 :             && l->malloc_state == STATE_MALLOC
    2082                 :       18345 :             && !node->inlined_to
    2083                 :     2208170 :             && !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (node->decl))))
    2084                 :             :           {
    2085                 :         426 :             if (dump_file && (dump_flags & TDF_DETAILS))
    2086                 :           6 :               fprintf (dump_file, "Function %s found to be malloc\n",
    2087                 :             :                        node->dump_name ());
    2088                 :             : 
    2089                 :         426 :             bool malloc_decl_p = DECL_IS_MALLOC (node->decl);
    2090                 :         426 :             node->set_malloc_flag (true);
    2091                 :         426 :             if (!malloc_decl_p && warn_suggest_attribute_malloc)
    2092                 :           0 :                 warn_function_malloc (node->decl);
    2093                 :             :           }
    2094                 :             :       }
    2095                 :             : 
    2096                 :      148840 :   dump_malloc_lattice (dump_file, "after propagation");
    2097                 :      148840 :   ipa_free_postorder_info ();
    2098                 :      148840 :   free (order);
    2099                 :      148840 : }
    2100                 :             : 
    2101                 :             : /* Produce the global information by preforming a transitive closure
    2102                 :             :    on the local information that was produced by generate_summary.  */
    2103                 :             : 
    2104                 :             : unsigned int
    2105                 :      148840 : pass_ipa_pure_const::
    2106                 :             : execute (function *)
    2107                 :             : {
    2108                 :      148840 :   bool remove_p;
    2109                 :             : 
    2110                 :             :   /* Nothrow makes more function to not lead to return and improve
    2111                 :             :      later analysis.  */
    2112                 :      148840 :   propagate_nothrow ();
    2113                 :      148840 :   propagate_malloc ();
    2114                 :      148840 :   remove_p = propagate_pure_const ();
    2115                 :             : 
    2116                 :      148840 :   delete funct_state_summaries;
    2117                 :      148840 :   return remove_p ? TODO_remove_functions : 0;
    2118                 :             : }
    2119                 :             : 
    2120                 :             : static bool
    2121                 :     3898625 : gate_pure_const (void)
    2122                 :             : {
    2123                 :      582829 :   return flag_ipa_pure_const || in_lto_p;
    2124                 :             : }
    2125                 :             : 
    2126                 :      283157 : pass_ipa_pure_const::pass_ipa_pure_const(gcc::context *ctxt)
    2127                 :             :     : ipa_opt_pass_d(pass_data_ipa_pure_const, ctxt,
    2128                 :             :                      pure_const_generate_summary, /* generate_summary */
    2129                 :             :                      pure_const_write_summary, /* write_summary */
    2130                 :             :                      pure_const_read_summary, /* read_summary */
    2131                 :             :                      NULL, /* write_optimization_summary */
    2132                 :             :                      NULL, /* read_optimization_summary */
    2133                 :             :                      NULL, /* stmt_fixup */
    2134                 :             :                      0, /* function_transform_todo_flags_start */
    2135                 :             :                      NULL, /* function_transform */
    2136                 :             :                      NULL), /* variable_transform */
    2137                 :      283157 :   init_p (false) {}
    2138                 :             : 
    2139                 :             : ipa_opt_pass_d *
    2140                 :      283157 : make_pass_ipa_pure_const (gcc::context *ctxt)
    2141                 :             : {
    2142                 :      283157 :   return new pass_ipa_pure_const (ctxt);
    2143                 :             : }
    2144                 :             : 
    2145                 :             : /* Simple local pass for pure const discovery reusing the analysis from
    2146                 :             :    ipa_pure_const.   This pass is effective when executed together with
    2147                 :             :    other optimization passes in early optimization pass queue.  */
    2148                 :             : 
    2149                 :             : namespace {
    2150                 :             : 
    2151                 :             : const pass_data pass_data_local_pure_const =
    2152                 :             : {
    2153                 :             :   GIMPLE_PASS, /* type */
    2154                 :             :   "local-pure-const", /* name */
    2155                 :             :   OPTGROUP_NONE, /* optinfo_flags */
    2156                 :             :   TV_IPA_PURE_CONST, /* tv_id */
    2157                 :             :   0, /* properties_required */
    2158                 :             :   0, /* properties_provided */
    2159                 :             :   0, /* properties_destroyed */
    2160                 :             :   0, /* todo_flags_start */
    2161                 :             :   0, /* todo_flags_finish */
    2162                 :             : };
    2163                 :             : 
    2164                 :             : class pass_local_pure_const : public gimple_opt_pass
    2165                 :             : {
    2166                 :             : public:
    2167                 :      566314 :   pass_local_pure_const (gcc::context *ctxt)
    2168                 :     1132628 :     : gimple_opt_pass (pass_data_local_pure_const, ctxt)
    2169                 :             :   {}
    2170                 :             : 
    2171                 :             :   /* opt_pass methods: */
    2172                 :      283157 :   opt_pass * clone () final override
    2173                 :             :   {
    2174                 :      283157 :     return new pass_local_pure_const (m_ctxt);
    2175                 :             :   }
    2176                 :     3316048 :   bool gate (function *) final override { return gate_pure_const (); }
    2177                 :             :   unsigned int execute (function *) final override;
    2178                 :             : 
    2179                 :             : }; // class pass_local_pure_const
    2180                 :             : 
    2181                 :             : unsigned int
    2182                 :     3315737 : pass_local_pure_const::execute (function *fun)
    2183                 :             : {
    2184                 :     3315737 :   bool changed = false;
    2185                 :     3315737 :   funct_state l;
    2186                 :     3315737 :   bool skip;
    2187                 :     3315737 :   struct cgraph_node *node;
    2188                 :             : 
    2189                 :     3315737 :   node = cgraph_node::get (current_function_decl);
    2190                 :     3315737 :   skip = skip_function_for_local_pure_const (node);
    2191                 :             : 
    2192                 :     3315737 :   if (!warn_suggest_attribute_const
    2193                 :     3315714 :       && !warn_suggest_attribute_pure
    2194                 :     3315693 :       && skip)
    2195                 :             :     return 0;
    2196                 :             : 
    2197                 :     3152274 :   l = analyze_function (node, false);
    2198                 :             : 
    2199                 :             :   /* Do NORETURN discovery.  */
    2200                 :     3152274 :   if (!skip && !TREE_THIS_VOLATILE (current_function_decl)
    2201                 :     6279600 :       && EDGE_COUNT (EXIT_BLOCK_PTR_FOR_FN (fun)->preds) == 0)
    2202                 :             :     {
    2203                 :       31390 :       warn_function_noreturn (fun->decl);
    2204                 :       31390 :       if (dump_file)
    2205                 :           1 :         fprintf (dump_file, "Function found to be noreturn: %s\n",
    2206                 :             :                  current_function_name ());
    2207                 :             : 
    2208                 :             :       /* Update declaration and reduce profile to executed once.  */
    2209                 :       31390 :       if (cgraph_node::get (current_function_decl)->set_noreturn_flag (true))
    2210                 :             :         changed = true;
    2211                 :       31390 :       if (node->frequency > NODE_FREQUENCY_EXECUTED_ONCE)
    2212                 :       11909 :         node->frequency = NODE_FREQUENCY_EXECUTED_ONCE;
    2213                 :             :     }
    2214                 :             : 
    2215                 :     3152274 :   switch (l->pure_const_state)
    2216                 :             :     {
    2217                 :      635436 :     case IPA_CONST:
    2218                 :     1270872 :       changed |= ipa_make_function_const
    2219                 :      635436 :                    (cgraph_node::get (current_function_decl), l->looping, true);
    2220                 :      635436 :       break;
    2221                 :             : 
    2222                 :      403403 :     case IPA_PURE:
    2223                 :      806806 :       changed |= ipa_make_function_pure
    2224                 :      403403 :                    (cgraph_node::get (current_function_decl), l->looping, true);
    2225                 :      403403 :       break;
    2226                 :             : 
    2227                 :             :     default:
    2228                 :             :       break;
    2229                 :             :     }
    2230                 :     3152274 :   if (!l->can_throw && !TREE_NOTHROW (current_function_decl))
    2231                 :             :     {
    2232                 :       22829 :       node->set_nothrow_flag (true);
    2233                 :       22829 :       changed = true;
    2234                 :       22829 :       if (dump_file)
    2235                 :           2 :         fprintf (dump_file, "Function found to be nothrow: %s\n",
    2236                 :             :                  current_function_name ());
    2237                 :             :     }
    2238                 :             : 
    2239                 :     3152274 :   if (l->malloc_state == STATE_MALLOC
    2240                 :     3152274 :       && !DECL_IS_MALLOC (current_function_decl))
    2241                 :             :     {
    2242                 :       20962 :       node->set_malloc_flag (true);
    2243                 :       20962 :       if (warn_suggest_attribute_malloc)
    2244                 :           3 :         warn_function_malloc (node->decl);
    2245                 :       20962 :       changed = true;
    2246                 :       20962 :       if (dump_file)
    2247                 :           2 :         fprintf (dump_file, "Function found to be malloc: %s\n",
    2248                 :             :                  node->dump_name ());
    2249                 :             :     }
    2250                 :             : 
    2251                 :     3152274 :   free (l);
    2252                 :     3152274 :   if (changed)
    2253                 :      861585 :     return execute_fixup_cfg ();
    2254                 :             :   else
    2255                 :             :     return 0;
    2256                 :             : }
    2257                 :             : 
    2258                 :             : } // anon namespace
    2259                 :             : 
    2260                 :             : gimple_opt_pass *
    2261                 :      283157 : make_pass_local_pure_const (gcc::context *ctxt)
    2262                 :             : {
    2263                 :      283157 :   return new pass_local_pure_const (ctxt);
    2264                 :             : }
    2265                 :             : 
    2266                 :             : /* Emit noreturn warnings.  */
    2267                 :             : 
    2268                 :             : namespace {
    2269                 :             : 
    2270                 :             : const pass_data pass_data_warn_function_noreturn =
    2271                 :             : {
    2272                 :             :   GIMPLE_PASS, /* type */
    2273                 :             :   "*warn_function_noreturn", /* name */
    2274                 :             :   OPTGROUP_NONE, /* optinfo_flags */
    2275                 :             :   TV_NONE, /* tv_id */
    2276                 :             :   PROP_cfg, /* properties_required */
    2277                 :             :   0, /* properties_provided */
    2278                 :             :   0, /* properties_destroyed */
    2279                 :             :   0, /* todo_flags_start */
    2280                 :             :   0, /* todo_flags_finish */
    2281                 :             : };
    2282                 :             : 
    2283                 :             : class pass_warn_function_noreturn : public gimple_opt_pass
    2284                 :             : {
    2285                 :             : public:
    2286                 :      283157 :   pass_warn_function_noreturn (gcc::context *ctxt)
    2287                 :      566314 :     : gimple_opt_pass (pass_data_warn_function_noreturn, ctxt)
    2288                 :             :   {}
    2289                 :             : 
    2290                 :             :   /* opt_pass methods: */
    2291                 :     1436616 :   bool gate (function *) final override
    2292                 :             :   {
    2293                 :     1436616 :     return warn_suggest_attribute_noreturn;
    2294                 :             :   }
    2295                 :          27 :   unsigned int execute (function *fun) final override
    2296                 :             :     {
    2297                 :          27 :       if (!TREE_THIS_VOLATILE (current_function_decl)
    2298                 :          27 :           && EDGE_COUNT (EXIT_BLOCK_PTR_FOR_FN (fun)->preds) == 0)
    2299                 :           4 :         warn_function_noreturn (current_function_decl);
    2300                 :          27 :       return 0;
    2301                 :             :     }
    2302                 :             : 
    2303                 :             : }; // class pass_warn_function_noreturn
    2304                 :             : 
    2305                 :             : } // anon namespace
    2306                 :             : 
    2307                 :             : gimple_opt_pass *
    2308                 :      283157 : make_pass_warn_function_noreturn (gcc::context *ctxt)
    2309                 :             : {
    2310                 :      283157 :   return new pass_warn_function_noreturn (ctxt);
    2311                 :             : }
    2312                 :             : 
    2313                 :             : /* Simple local pass for pure const discovery reusing the analysis from
    2314                 :             :    ipa_pure_const.   This pass is effective when executed together with
    2315                 :             :    other optimization passes in early optimization pass queue.  */
    2316                 :             : 
    2317                 :             : namespace {
    2318                 :             : 
    2319                 :             : const pass_data pass_data_nothrow =
    2320                 :             : {
    2321                 :             :   GIMPLE_PASS, /* type */
    2322                 :             :   "nothrow", /* name */
    2323                 :             :   OPTGROUP_NONE, /* optinfo_flags */
    2324                 :             :   TV_IPA_PURE_CONST, /* tv_id */
    2325                 :             :   0, /* properties_required */
    2326                 :             :   0, /* properties_provided */
    2327                 :             :   0, /* properties_destroyed */
    2328                 :             :   0, /* todo_flags_start */
    2329                 :             :   0, /* todo_flags_finish */
    2330                 :             : };
    2331                 :             : 
    2332                 :             : class pass_nothrow : public gimple_opt_pass
    2333                 :             : {
    2334                 :             : public:
    2335                 :      283157 :   pass_nothrow (gcc::context *ctxt)
    2336                 :      566314 :     : gimple_opt_pass (pass_data_nothrow, ctxt)
    2337                 :             :   {}
    2338                 :             : 
    2339                 :             :   /* opt_pass methods: */
    2340                 :           0 :   opt_pass * clone () final override { return new pass_nothrow (m_ctxt); }
    2341                 :     2746276 :   bool gate (function *) final override { return optimize; }
    2342                 :             :   unsigned int execute (function *) final override;
    2343                 :             : 
    2344                 :             : }; // class pass_nothrow
    2345                 :             : 
    2346                 :             : unsigned int
    2347                 :     2309739 : pass_nothrow::execute (function *)
    2348                 :             : {
    2349                 :     2309739 :   struct cgraph_node *node;
    2350                 :     2309739 :   basic_block this_block;
    2351                 :             : 
    2352                 :     2309739 :   if (TREE_NOTHROW (current_function_decl))
    2353                 :             :     return 0;
    2354                 :             : 
    2355                 :     1427364 :   node = cgraph_node::get (current_function_decl);
    2356                 :             : 
    2357                 :             :   /* We run during lowering, we cannot really use availability yet.  */
    2358                 :     1427364 :   if (cgraph_node::get (current_function_decl)->get_availability ()
    2359                 :             :       <= AVAIL_INTERPOSABLE)
    2360                 :             :     {
    2361                 :       78944 :       if (dump_file)
    2362                 :           0 :         fprintf (dump_file, "Function is interposable;"
    2363                 :             :                  " not analyzing.\n");
    2364                 :       78944 :       return true;
    2365                 :             :     }
    2366                 :             : 
    2367                 :    10547734 :   FOR_EACH_BB_FN (this_block, cfun)
    2368                 :             :     {
    2369                 :    19517512 :       for (gimple_stmt_iterator gsi = gsi_start_bb (this_block);
    2370                 :    47974598 :            !gsi_end_p (gsi);
    2371                 :    38215842 :            gsi_next (&gsi))
    2372                 :    38775284 :         if (stmt_can_throw_external (cfun, gsi_stmt (gsi)))
    2373                 :             :           {
    2374                 :      560763 :             if (is_gimple_call (gsi_stmt (gsi)))
    2375                 :             :               {
    2376                 :      347696 :                 tree callee_t = gimple_call_fndecl (gsi_stmt (gsi));
    2377                 :      347696 :                 if (callee_t && recursive_call_p (current_function_decl,
    2378                 :             :                                                   callee_t))
    2379                 :        1321 :                   continue;
    2380                 :             :               }
    2381                 :             : 
    2382                 :      559442 :             if (dump_file)
    2383                 :             :               {
    2384                 :           0 :                 fprintf (dump_file, "Statement can throw: ");
    2385                 :           0 :                 print_gimple_stmt (dump_file, gsi_stmt (gsi), 0);
    2386                 :             :               }
    2387                 :      559442 :             return 0;
    2388                 :             :           }
    2389                 :             :     }
    2390                 :             : 
    2391                 :      788978 :   node->set_nothrow_flag (true);
    2392                 :             : 
    2393                 :      788978 :   bool cfg_changed = false;
    2394                 :      788978 :   if (self_recursive_p (node))
    2395                 :       28718 :     FOR_EACH_BB_FN (this_block, cfun)
    2396                 :       77549 :       if (gcall *g = safe_dyn_cast <gcall *> (*gsi_last_bb (this_block)))
    2397                 :             :         {
    2398                 :        1912 :           tree callee_t = gimple_call_fndecl (g);
    2399                 :        1912 :           if (callee_t
    2400                 :        1812 :               && recursive_call_p (current_function_decl, callee_t)
    2401                 :         537 :               && maybe_clean_eh_stmt (g)
    2402                 :        1915 :               && gimple_purge_dead_eh_edges (this_block))
    2403                 :             :             cfg_changed = true;
    2404                 :             :         }
    2405                 :             : 
    2406                 :      788978 :   if (dump_file)
    2407                 :          33 :     fprintf (dump_file, "Function found to be nothrow: %s\n",
    2408                 :             :              current_function_name ());
    2409                 :      788978 :   return cfg_changed ? TODO_cleanup_cfg : 0;
    2410                 :             : }
    2411                 :             : 
    2412                 :             : } // anon namespace
    2413                 :             : 
    2414                 :             : gimple_opt_pass *
    2415                 :      283157 : make_pass_nothrow (gcc::context *ctxt)
    2416                 :             : {
    2417                 :      283157 :   return new pass_nothrow (ctxt);
    2418                 :             : }
        

Generated by: LCOV version 2.1-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.