(root)/
gcc-13.2.0/
gcc/
ipa-modref.h
       1  /* Search for references that a functions loads or stores.
       2     Copyright (C) 2019-2023 Free Software Foundation, Inc.
       3  
       4  This file is part of GCC.
       5  
       6  GCC is free software; you can redistribute it and/or modify it under
       7  the terms of the GNU General Public License as published by the Free
       8  Software Foundation; either version 3, or (at your option) any later
       9  version.
      10  
      11  GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      12  WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      14  for more details.
      15  
      16  You should have received a copy of the GNU General Public License
      17  along with GCC; see the file COPYING3.  If not see
      18  <http://www.gnu.org/licenses/>.  */
      19  
      20  #ifndef IPA_MODREF_H
      21  #define IPA_MODREF_H
      22  
      23  typedef modref_tree <alias_set_type> modref_records;
      24  typedef unsigned short eaf_flags_t;
      25  
      26  /* Single function summary.  */
      27  
      28  struct GTY(()) modref_summary
      29  {
      30    /* Load and stores in function (transitively closed to all callees)  */
      31    modref_records *loads;
      32    modref_records *stores;
      33    auto_vec<modref_access_node> GTY((skip)) kills;
      34    auto_vec<eaf_flags_t> GTY((skip)) arg_flags;
      35  
      36    eaf_flags_t retslot_flags;
      37    eaf_flags_t static_chain_flags;
      38  
      39    unsigned writes_errno : 1;
      40    /* Side effects does not include memory loads and stores which are
      41       expressed using loads, stores and calls_interposable fields.  */
      42    unsigned side_effects : 1;
      43    /* If true function can not be CSE optimized because it may behave
      44       differently even if invoked with same inputs.  */
      45    unsigned nondeterministic : 1;
      46    /* IF true the function may read any reachable memory but not use
      47       it for anything useful.  This may happen i.e. when interposing
      48       function with optimized out conditional with unoptimized one.
      49  
      50       In this situation the loads summary is not useful for DSE but
      51       it is still useful for CSE.  */
      52    unsigned calls_interposable : 1;
      53  
      54    /* Flags computed by finalize method.  */
      55  
      56    /* Total number of accesses in loads tree.  */
      57    unsigned int load_accesses;
      58    /* global_memory_read is not set for functions calling functions
      59       with !binds_to_current_def which, after interposition, may read global
      60       memory but do nothing useful with it (except for crashing if some
      61       stores are optimized out.  */
      62    unsigned global_memory_read : 1;
      63    unsigned global_memory_written : 1;
      64    unsigned try_dse : 1;
      65  
      66  
      67    modref_summary ();
      68    ~modref_summary ();
      69    void dump (FILE *);
      70    bool useful_p (int ecf_flags, bool check_flags = true);
      71    void finalize (tree);
      72  };
      73  
      74  modref_summary *get_modref_function_summary (cgraph_node *func);
      75  modref_summary *get_modref_function_summary (gcall *call, bool *interposed);
      76  void ipa_modref_cc_finalize ();
      77  void ipa_merge_modref_summary_after_inlining (cgraph_edge *e);
      78  
      79  /* All flags that are implied by the ECF_CONST functions.  */
      80  static const int implicit_const_eaf_flags
      81     = EAF_NO_DIRECT_CLOBBER | EAF_NO_INDIRECT_CLOBBER
      82      | EAF_NO_DIRECT_ESCAPE | EAF_NO_INDIRECT_ESCAPE
      83      | EAF_NO_DIRECT_READ | EAF_NO_INDIRECT_READ
      84      | EAF_NOT_RETURNED_INDIRECTLY;
      85  
      86  /* All flags that are implied by the ECF_PURE function.  */
      87  static const int implicit_pure_eaf_flags
      88     = EAF_NO_DIRECT_CLOBBER | EAF_NO_INDIRECT_CLOBBER
      89      | EAF_NO_DIRECT_ESCAPE | EAF_NO_INDIRECT_ESCAPE;
      90  
      91  /* All flags implied when we know we can ignore stores (i.e. when handling
      92     call to noreturn).  */
      93  static const int ignore_stores_eaf_flags
      94     = EAF_NO_DIRECT_CLOBBER | EAF_NO_INDIRECT_CLOBBER
      95      | EAF_NO_DIRECT_ESCAPE | EAF_NO_INDIRECT_ESCAPE;
      96  
      97  /* Return slot is write-only.  */
      98  static const int implicit_retslot_eaf_flags
      99     = EAF_NO_DIRECT_READ | EAF_NO_INDIRECT_READ
     100       | EAF_NO_INDIRECT_ESCAPE | EAF_NO_INDIRECT_CLOBBER
     101       | EAF_NOT_RETURNED_INDIRECTLY;
     102  
     103  /* If function does not bind to current def (i.e. it is inline in comdat
     104     section), the modref analysis may not match the behavior of function
     105     which will be later symbol interposed to.  All side effects must match
     106     however it is possible that the other function body contains more loads
     107     which may trap.
     108     MODREF_FLAGS are flags determined by analysis of function body while
     109     FLAGS are flags known otherwise (i.e. by fnspec, pure/const attributes
     110     etc.)  */
     111  inline int
     112  interposable_eaf_flags (int modref_flags, int flags)
     113  {
     114    /* If parameter was previously unused, we know it is only read
     115       and its value is not used.  */
     116    if ((modref_flags & EAF_UNUSED) && !(flags & EAF_UNUSED))
     117      {
     118        modref_flags &= ~EAF_UNUSED;
     119        modref_flags |= EAF_NO_DIRECT_ESCAPE | EAF_NO_INDIRECT_ESCAPE
     120  		      | EAF_NOT_RETURNED_DIRECTLY | EAF_NOT_RETURNED_INDIRECTLY
     121  		      | EAF_NO_DIRECT_CLOBBER | EAF_NO_INDIRECT_CLOBBER;
     122      }
     123    /* We can not determine that value is not read at all.  */
     124    if ((modref_flags & EAF_NO_DIRECT_READ) && !(flags & EAF_NO_DIRECT_READ))
     125      modref_flags &= ~EAF_NO_DIRECT_READ;
     126    if ((modref_flags & EAF_NO_INDIRECT_READ) && !(flags & EAF_NO_INDIRECT_READ))
     127      modref_flags &= ~EAF_NO_INDIRECT_READ;
     128    return modref_flags;
     129  }
     130  
     131  #endif