/* Header file for gimple decl, type and expressions.
   Copyright (C) 2013-2014 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 bool gimple_can_coalesce_p (tree, tree);
extern tree create_tmp_var_name (const char *);
extern tree create_tmp_var_raw (tree, const char *);
extern tree create_tmp_var (tree, const char *);
extern tree create_tmp_reg (tree, const char *);
extern tree create_tmp_reg_fn (struct function *, tree, const char *);


extern void extract_ops_from_tree_1 (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_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 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)
    {
      op = SSA_NAME_VAR (op);
      if (!op)
	return false;
    }

  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) == 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 REAL_CST:
    case FIXED_CST:
    case STRING_CST:
    case COMPLEX_CST:
    case VECTOR_CST:
      return true;

    default:
      return false;
    }
}

/* A wrapper around extract_ops_from_tree_1, 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_1 (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 */
