/* Header file for gimple decl, type and expressions.
   Copyright (C) 2013-2021 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_EXPR_H
#define GCC_GIMPLE_EXPR_H

extern bool useless_type_conversion_p (tree, tree);


extern void gimple_set_body (tree, gimple_seq);
extern gimple_seq gimple_body (tree);
extern bool gimple_has_body_p (tree);
extern const char *gimple_decl_printable_name (tree, int);
extern tree copy_var_decl (tree, tree, tree);
extern tree create_tmp_var_name (const char *);
extern tree create_tmp_var_raw (tree, const char * = NULL);
extern tree create_tmp_var (tree, const char * = NULL);
extern tree create_tmp_reg (tree, const char * = NULL);
extern tree create_tmp_reg_fn (struct function *, tree, const char *);


extern void extract_ops_from_tree (tree, enum tree_code *, tree *, tree *,
				   tree *);
extern void gimple_cond_get_ops_from_tree (tree, enum tree_code *, tree *,
					   tree *);
extern bool is_gimple_lvalue (tree);
extern bool is_gimple_condexpr (tree);
extern bool is_gimple_condexpr_for_cond (tree);
extern bool is_gimple_address (const_tree);
extern bool is_gimple_invariant_address (const_tree);
extern bool is_gimple_ip_invariant_address (const_tree);
extern bool is_gimple_min_invariant (const_tree);
extern bool is_gimple_ip_invariant (const_tree);
extern bool is_gimple_reg (tree);
extern bool is_gimple_val (tree);
extern bool is_gimple_asm_val (tree);
extern bool is_gimple_min_lval (tree);
extern bool is_gimple_call_addr (tree);
extern bool is_gimple_mem_ref_addr (tree);
extern void flush_mark_addressable_queue (void);
extern void mark_addressable (tree);
extern bool is_gimple_reg_rhs (tree);

/* Return true if a conversion from either type of TYPE1 and TYPE2
   to the other is not required.  Otherwise return false.  */

static inline bool
types_compatible_p (tree type1, tree type2)
{
  return (type1 == type2
	  || (useless_type_conversion_p (type1, type2)
	      && useless_type_conversion_p (type2, type1)));
}

/* Return true if TYPE is a suitable type for a scalar register variable.  */

static inline bool
is_gimple_reg_type (tree type)
{
  return !AGGREGATE_TYPE_P (type);
}

/* Return true if T is a variable.  */

static inline bool
is_gimple_variable (tree t)
{
  return (TREE_CODE (t) == VAR_DECL
	  || TREE_CODE (t) == PARM_DECL
	  || TREE_CODE (t) == RESULT_DECL
	  || TREE_CODE (t) == SSA_NAME);
}

/*  Return true if T is a GIMPLE identifier (something with an address).  */

static inline bool
is_gimple_id (tree t)
{
  return (is_gimple_variable (t)
	  || TREE_CODE (t) == FUNCTION_DECL
	  || TREE_CODE (t) == LABEL_DECL
	  || TREE_CODE (t) == CONST_DECL
	  /* Allow string constants, since they are addressable.  */
	  || TREE_CODE (t) == STRING_CST);
}

/* Return true if OP, an SSA name or a DECL is a virtual operand.  */

static inline bool
virtual_operand_p (tree op)
{
  if (TREE_CODE (op) == SSA_NAME)
    return SSA_NAME_IS_VIRTUAL_OPERAND (op);

  if (TREE_CODE (op) == VAR_DECL)
    return VAR_DECL_IS_VIRTUAL_OPERAND (op);

  return false;
}

/*  Return true if T is something whose address can be taken.  */

static inline bool
is_gimple_addressable (tree t)
{
  return (is_gimple_id (t) || handled_component_p (t)
	  || TREE_CODE (t) == TARGET_MEM_REF
	  || TREE_CODE (t) == MEM_REF);
}

/* Return true if T is a valid gimple constant.  */

static inline bool
is_gimple_constant (const_tree t)
{
  switch (TREE_CODE (t))
    {
    case INTEGER_CST:
    case POLY_INT_CST:
    case REAL_CST:
    case FIXED_CST:
    case COMPLEX_CST:
    case VECTOR_CST:
    case STRING_CST:
      return true;

    default:
      return false;
    }
}

/* A wrapper around extract_ops_from_tree with 3 ops, for callers which
   expect to see only a maximum of two operands.  */

static inline void
extract_ops_from_tree (tree expr, enum tree_code *code, tree *op0,
		       tree *op1)
{
  tree op2;
  extract_ops_from_tree (expr, code, op0, op1, &op2);
  gcc_assert (op2 == NULL_TREE);
}

/* Given a valid GIMPLE_CALL function address return the FUNCTION_DECL
   associated with the callee if known.  Otherwise return NULL_TREE.  */

static inline tree
gimple_call_addr_fndecl (const_tree fn)
{
  if (fn && TREE_CODE (fn) == ADDR_EXPR)
    {
      tree fndecl = TREE_OPERAND (fn, 0);
      if (TREE_CODE (fndecl) == MEM_REF
	  && TREE_CODE (TREE_OPERAND (fndecl, 0)) == ADDR_EXPR
	  && integer_zerop (TREE_OPERAND (fndecl, 1)))
	fndecl = TREE_OPERAND (TREE_OPERAND (fndecl, 0), 0);
      if (TREE_CODE (fndecl) == FUNCTION_DECL)
	return fndecl;
    }
  return NULL_TREE;
}

#endif /* GCC_GIMPLE_EXPR_H */
