/* Chains of recurrences.
   Copyright (C) 2003-2023 Free Software Foundation, Inc.
   Contributed by Sebastian Pop <pop@cri.ensmp.fr>

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_TREE_CHREC_H
#define GCC_TREE_CHREC_H

/* The following trees are unique elements.  Thus the comparison of another
   element to these elements should be done on the pointer to these trees,
   and not on their value.

   extern tree chrec_not_analyzed_yet;
   extern tree chrec_dont_know;
   extern tree chrec_known;

   chrec_not_analyzed_yet is NULL_TREE and the others are defined
   in global_trees[].  */

/* After having added an automatically generated element, please
   include it in the following function.  */

inline bool
automatically_generated_chrec_p (const_tree chrec)
{
  return (chrec == chrec_dont_know
	  || chrec == chrec_known);
}

/* The tree nodes aka. CHRECs.  */

inline bool
tree_is_chrec (const_tree expr)
{
  if (TREE_CODE (expr) == POLYNOMIAL_CHREC
      || automatically_generated_chrec_p (expr))
    return true;
  else
    return false;
}


enum ev_direction {EV_DIR_GROWS, EV_DIR_DECREASES, EV_DIR_UNKNOWN};
enum ev_direction scev_direction (const_tree);

/* Chrec folding functions.  */
extern tree chrec_fold_plus (tree, tree, tree);
extern tree chrec_fold_minus (tree, tree, tree);
extern tree chrec_fold_multiply (tree, tree, tree);
extern tree chrec_convert (tree, tree, gimple *, bool = true, tree = NULL);
extern tree chrec_convert_rhs (tree, tree, gimple *);
extern tree chrec_convert_aggressive (tree, tree, bool *);

/* Operations.  */
extern tree chrec_apply (unsigned, tree, tree);
extern tree chrec_apply_map (tree, vec<tree> );
extern tree chrec_replace_initial_condition (tree, tree);
extern tree initial_condition (tree);
extern tree initial_condition_in_loop_num (tree, unsigned);
extern tree evolution_part_in_loop_num (tree, unsigned);
extern tree hide_evolution_in_other_loops_than_loop (tree, unsigned);
extern tree reset_evolution_in_loop (unsigned, tree, tree);
extern tree chrec_merge (tree, tree);
extern void for_each_scev_op (tree *, bool (*) (tree *, void *), void *);
extern bool convert_affine_scev (class loop *, tree, tree *, tree *, gimple *,
				 bool, tree = NULL);

/* Observers.  */
extern bool eq_evolutions_p (const_tree, const_tree);
extern bool is_multivariate_chrec (const_tree);
extern bool chrec_contains_symbols (const_tree, class loop * = NULL);
extern bool chrec_contains_symbols_defined_in_loop (const_tree, unsigned);
extern bool chrec_contains_undetermined (const_tree);
extern bool tree_contains_chrecs (const_tree, int *);
extern bool evolution_function_is_affine_multivariate_p (const_tree, int);
extern bool evolution_function_is_univariate_p (const_tree, int = 0);
extern unsigned nb_vars_in_chrec (tree);
extern bool evolution_function_is_invariant_p (tree, int);
extern bool scev_is_linear_expression (tree);
extern bool evolution_function_right_is_integer_cst (const_tree);

/* Determines whether CHREC is equal to zero.  */

inline bool
chrec_zerop (const_tree chrec)
{
  if (chrec == NULL_TREE)
    return false;

  if (TREE_CODE (chrec) == INTEGER_CST)
    return integer_zerop (chrec);

  return false;
}

/* Determines whether CHREC is a loop invariant with respect to LOOP_NUM.
   Set the result in RES and return true when the property can be computed.  */

inline bool
no_evolution_in_loop_p (tree chrec, unsigned loop_num, bool *res)
{
  tree scev;

  if (chrec == chrec_not_analyzed_yet
      || chrec == chrec_dont_know
      || chrec_contains_symbols_defined_in_loop (chrec, loop_num))
    return false;

  STRIP_NOPS (chrec);
  scev = hide_evolution_in_other_loops_than_loop (chrec, loop_num);
  *res = !tree_contains_chrecs (scev, NULL);
  return true;
}

/* Build a polynomial chain of recurrence.  */

inline tree
build_polynomial_chrec (unsigned loop_num,
			tree left,
			tree right)
{
  bool val;

  if (left == chrec_dont_know
      || right == chrec_dont_know)
    return chrec_dont_know;

  if (!no_evolution_in_loop_p (left, loop_num, &val)
      || !val)
    return chrec_dont_know;

  /* Types of left and right sides of a chrec should be compatible, but
     pointer CHRECs are special in that the evolution is of ptroff type.  */
  if (POINTER_TYPE_P (TREE_TYPE (left)))
    gcc_checking_assert (ptrofftype_p (TREE_TYPE (right)));
  else
    {
      /* Pointer types should occur only on the left hand side, i.e. in
	 the base of the chrec, and not in the step.  */
      gcc_checking_assert (!POINTER_TYPE_P (TREE_TYPE (right))
			   && types_compatible_p (TREE_TYPE (left),
						  TREE_TYPE (right)));
    }

  if (chrec_zerop (right))
    return left;

  tree chrec = build2 (POLYNOMIAL_CHREC, TREE_TYPE (left), left, right);
  CHREC_VARIABLE (chrec) = loop_num;
  return chrec;
}

/* Determines whether the expression CHREC is a constant.  */

inline bool
evolution_function_is_constant_p (const_tree chrec)
{
  if (chrec == NULL_TREE)
    return false;

  return is_gimple_min_invariant (chrec);
}

/* Determine whether CHREC is an affine evolution function in LOOPNUM.  */

inline bool
evolution_function_is_affine_in_loop (const_tree chrec, int loopnum)
{
  if (chrec == NULL_TREE)
    return false;

  switch (TREE_CODE (chrec))
    {
    case POLYNOMIAL_CHREC:
      if (evolution_function_is_invariant_p (CHREC_LEFT (chrec), loopnum)
	  && evolution_function_is_invariant_p (CHREC_RIGHT (chrec), loopnum))
	return true;
      else
	return false;

    default:
      return false;
    }
}

/* Determine whether CHREC is an affine evolution function or not.  */

inline bool
evolution_function_is_affine_p (const_tree chrec)
{
  return chrec
    && TREE_CODE (chrec) == POLYNOMIAL_CHREC
    && evolution_function_is_invariant_p (CHREC_RIGHT (chrec),
					  CHREC_VARIABLE (chrec))
    && (TREE_CODE (CHREC_RIGHT (chrec)) != POLYNOMIAL_CHREC
	|| evolution_function_is_affine_p (CHREC_RIGHT (chrec)));
}

/* Determines whether EXPR does not contains chrec expressions.  */

inline bool
tree_does_not_contain_chrecs (const_tree expr)
{
  return !tree_contains_chrecs (expr, NULL);
}

/* Returns the type of the chrec.  */

inline tree
chrec_type (const_tree chrec)
{
  if (automatically_generated_chrec_p (chrec))
    return NULL_TREE;

  return TREE_TYPE (chrec);
}

inline tree
chrec_fold_op (enum tree_code code, tree type, tree op0, tree op1)
{
  switch (code)
    {
    case PLUS_EXPR:
      return chrec_fold_plus (type, op0, op1);

    case MINUS_EXPR:
      return chrec_fold_minus (type, op0, op1);

    case MULT_EXPR:
      return chrec_fold_multiply (type, op0, op1);

    default:
      gcc_unreachable ();
    }

}

#endif  /* GCC_TREE_CHREC_H  */
