/* Header file for routines that straddle the border between GIMPLE and
   SSA in gimple.
   Copyright (C) 2009-2024 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 GCC_GIMPLE_SSA_H
#define GCC_GIMPLE_SSA_H

#include "tree-ssa-operands.h"

/* This structure is used to map a gimple statement to a label,
   or list of labels to represent transaction restart.  */

struct GTY((for_user)) tm_restart_node {
  gimple *stmt;
  tree label_or_list;
};

/* Hasher for tm_restart_node.  */

struct tm_restart_hasher : ggc_ptr_hash<tm_restart_node>
{
  static hashval_t hash (tm_restart_node *n) { return htab_hash_pointer (n); }

  static bool
  equal (tm_restart_node *a, tm_restart_node *b)
  {
    return a == b;
  }
};

extern void gt_ggc_mx (gimple *&);
extern void gt_pch_nx (gimple *&);

struct ssa_name_hasher : ggc_ptr_hash<tree_node>
{
  /* Hash a tree in a uid_decl_map.  */

  static hashval_t
  hash (tree item)
  {
    return item->ssa_name.var->decl_minimal.uid;
  }

  /* Return true if the DECL_UID in both trees are equal.  */

  static bool
  equal (tree a, tree b)
{
  return (a->ssa_name.var->decl_minimal.uid == b->ssa_name.var->decl_minimal.uid);
}
};

/* Gimple dataflow datastructure. All publicly available fields shall have
   gimple_ accessor defined, all publicly modifiable fields should have
   gimple_set accessor.  */
struct GTY(()) gimple_df {
  /* Array of all SSA_NAMEs used in the function.  */
  vec<tree, va_gc> *ssa_names;

  /* Artificial variable used for the virtual operand FUD chain.  */
  tree vop;

  /* The PTA solution for the ESCAPED and ESCAPED_RETURN artificial
     variables.  */
  struct pt_solution escaped;
  struct pt_solution escaped_return;

  /* A map of decls to artificial ssa-names that point to the partition
     of the decl.  */
  hash_map<tree, tree> * GTY((skip(""))) decls_to_pointers;

  /* Free list of SSA_NAMEs.  */
  vec<tree, va_gc> *free_ssanames;

  /* Queue of SSA_NAMEs to be freed at the next opportunity.  */
  vec<tree, va_gc> *free_ssanames_queue;

  /* Hashtable holding definition for symbol.  If this field is not NULL, it
     means that the first reference to this variable in the function is a
     USE or a VUSE.  In those cases, the SSA renamer creates an SSA name
     for this variable with an empty defining statement.  */
  hash_table<ssa_name_hasher> *default_defs;

  /* True if there are any symbols that need to be renamed.  */
  unsigned int ssa_renaming_needed : 1;

  /* True if all virtual operands need to be renamed.  */
  unsigned int rename_vops : 1;

  /* True if the code is in ssa form.  */
  unsigned int in_ssa_p : 1;

  /* True if IPA points-to information was computed for this function.  */
  unsigned int ipa_pta : 1;

  struct ssa_operands ssa_operands;

  /* Map gimple stmt to tree label (or list of labels) for transaction
     restart and abort.  */
  hash_table<tm_restart_hasher> *tm_restart;
};


/* Return true when gimple SSA form was built.
   gimple_in_ssa_p is queried by gimplifier in various early stages before SSA
   infrastructure is initialized.  Check for presence of the datastructures
   at first place.  */
inline bool
gimple_in_ssa_p (const struct function *fun)
{
  return fun && fun->gimple_df && fun->gimple_df->in_ssa_p;
}

/* Artificial variable used for the virtual operand FUD chain.  */
inline tree
gimple_vop (const struct function *fun)
{
  gcc_checking_assert (fun && fun->gimple_df);
  return fun->gimple_df->vop;
}

/* Return the set of VUSE operand for statement G.  */

inline use_operand_p
gimple_vuse_op (const gimple *g)
{
  struct use_optype_d *ops;
  const gimple_statement_with_memory_ops *mem_ops_stmt =
     dyn_cast <const gimple_statement_with_memory_ops *> (g);
  if (!mem_ops_stmt)
    return NULL_USE_OPERAND_P;
  ops = mem_ops_stmt->use_ops;
  if (ops
      && USE_OP_PTR (ops)->use == &mem_ops_stmt->vuse)
    return USE_OP_PTR (ops);
  return NULL_USE_OPERAND_P;
}

/* Return the set of VDEF operand for statement G.  */

inline def_operand_p
gimple_vdef_op (gimple *g)
{
  gimple_statement_with_memory_ops *mem_ops_stmt =
     dyn_cast <gimple_statement_with_memory_ops *> (g);
  if (!mem_ops_stmt)
    return NULL_DEF_OPERAND_P;
  if (mem_ops_stmt->vdef)
    return &mem_ops_stmt->vdef;
  return NULL_DEF_OPERAND_P;
}

/* Mark statement S as modified, and update it.  */

inline void
update_stmt (gimple *s)
{
  if (gimple_has_ops (s))
    {
      gimple_set_modified (s, true);
      update_stmt_operands (cfun, s);
    }
}

/* Update statement S if it has been optimized.  */

inline void
update_stmt_if_modified (gimple *s)
{
  if (gimple_modified_p (s))
    update_stmt_operands (cfun, s);
}

/* Mark statement S as modified, and update it.  */

inline void
update_stmt_fn (struct function *fn, gimple *s)
{
  if (gimple_has_ops (s))
    {
      gimple_set_modified (s, true);
      update_stmt_operands (fn, s);
    }
}


#endif /* GCC_GIMPLE_SSA_H */
