/* Search for references that a functions loads or stores.
   Copyright (C) 2019-2026 Free Software Foundation, Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#ifndef IPA_MODREF_H
#define IPA_MODREF_H

typedef modref_tree <alias_set_type> modref_records;
typedef unsigned short eaf_flags_t;

/* Single function summary.  */

struct GTY(()) modref_summary
{
  /* Load and stores in function (transitively closed to all callees)  */
  modref_records *loads;
  modref_records *stores;
  auto_vec<modref_access_node> GTY((skip)) kills;
  auto_vec<eaf_flags_t> GTY((skip)) arg_flags;

  eaf_flags_t retslot_flags;
  eaf_flags_t static_chain_flags;

  unsigned writes_errno : 1;
  /* Side effects does not include memory loads and stores which are
     expressed using loads, stores and calls_interposable fields.  */
  unsigned side_effects : 1;
  /* If true function can not be CSE optimized because it may behave
     differently even if invoked with same inputs.  */
  unsigned nondeterministic : 1;
  /* IF true the function may read any reachable memory but not use
     it for anything useful.  This may happen i.e. when interposing
     function with optimized out conditional with unoptimized one.

     In this situation the loads summary is not useful for DSE but
     it is still useful for CSE.  */
  unsigned calls_interposable : 1;

  /* Flags computed by finalize method.  */

  /* Total number of accesses in loads tree.  */
  unsigned int load_accesses;
  /* global_memory_read is not set for functions calling functions
     with !binds_to_current_def which, after interposition, may read global
     memory but do nothing useful with it (except for crashing if some
     stores are optimized out.  */
  unsigned global_memory_read : 1;
  unsigned global_memory_written : 1;
  unsigned try_dse : 1;


  modref_summary ();
  ~modref_summary ();
  void dump (FILE *) const;
  bool useful_p (int ecf_flags, bool check_flags = true);
  void finalize (tree);
};

modref_summary *get_modref_function_summary (cgraph_node *func);
modref_summary *get_modref_function_summary (gcall *call, bool *interposed);
void ipa_modref_cc_finalize ();
void ipa_merge_modref_summary_after_inlining (cgraph_edge *e);
bool ipa_modref_callee_reads_no_memory_p (gcall *call);

/* All flags that are implied by the ECF_CONST functions.  */
static const int implicit_const_eaf_flags
   = EAF_NO_DIRECT_CLOBBER | EAF_NO_INDIRECT_CLOBBER
    | EAF_NO_DIRECT_ESCAPE | EAF_NO_INDIRECT_ESCAPE
    | EAF_NO_DIRECT_READ | EAF_NO_INDIRECT_READ
    | EAF_NOT_RETURNED_INDIRECTLY;

/* All flags that are implied by the ECF_PURE function.  */
static const int implicit_pure_eaf_flags
   = EAF_NO_DIRECT_CLOBBER | EAF_NO_INDIRECT_CLOBBER
    | EAF_NO_DIRECT_ESCAPE | EAF_NO_INDIRECT_ESCAPE;

/* All flags implied when we know we can ignore stores (i.e. when handling
   call to noreturn).  */
static const int ignore_stores_eaf_flags
   = EAF_NO_DIRECT_CLOBBER | EAF_NO_INDIRECT_CLOBBER
    | EAF_NO_DIRECT_ESCAPE | EAF_NO_INDIRECT_ESCAPE;

/* Return slot is write-only.  */
static const int implicit_retslot_eaf_flags
   = EAF_NO_DIRECT_READ | EAF_NO_INDIRECT_READ
     | EAF_NO_INDIRECT_ESCAPE | EAF_NO_INDIRECT_CLOBBER
     | EAF_NOT_RETURNED_INDIRECTLY;

/* If function does not bind to current def (i.e. it is inline in comdat
   section), the modref analysis may not match the behavior of function
   which will be later symbol interposed to.  All side effects must match
   however it is possible that the other function body contains more loads
   which may trap.
   MODREF_FLAGS are flags determined by analysis of function body while
   FLAGS are flags known otherwise (i.e. by fnspec, pure/const attributes
   etc.)  */
inline int
interposable_eaf_flags (int modref_flags, int flags)
{
  /* If parameter was previously unused, we know it is only read
     and its value is not used.  */
  if ((modref_flags & EAF_UNUSED) && !(flags & EAF_UNUSED))
    {
      modref_flags &= ~EAF_UNUSED;
      modref_flags |= EAF_NO_DIRECT_ESCAPE | EAF_NO_INDIRECT_ESCAPE
		      | EAF_NOT_RETURNED_DIRECTLY | EAF_NOT_RETURNED_INDIRECTLY
		      | EAF_NO_DIRECT_CLOBBER | EAF_NO_INDIRECT_CLOBBER;
    }
  /* We can not determine that value is not read at all.  */
  if ((modref_flags & EAF_NO_DIRECT_READ) && !(flags & EAF_NO_DIRECT_READ))
    modref_flags &= ~EAF_NO_DIRECT_READ;
  if ((modref_flags & EAF_NO_INDIRECT_READ) && !(flags & EAF_NO_INDIRECT_READ))
    modref_flags &= ~EAF_NO_INDIRECT_READ;
  return modref_flags;
}

#endif
