/* Support routines for Value Range Propagation (VRP).
   Copyright (C) 2016-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_VR_VALUES_H
#define GCC_VR_VALUES_H

#include "value-range-equiv.h"
#include "value-query.h"

// Abstract class to return a range for a given SSA.

// Class to simplify a statement using range information.

class simplify_using_ranges
{
public:
  simplify_using_ranges (class range_query *query = NULL);
  ~simplify_using_ranges ();
  void set_range_query (class range_query *q) { query = q; }

  bool simplify (gimple_stmt_iterator *);

  // ?? These should be cleaned, merged, and made private.
  tree vrp_evaluate_conditional (tree_code, tree, tree, gimple *);
  void vrp_visit_cond_stmt (gcond *, edge *);
  tree vrp_evaluate_conditional_warnv_with_ops (gimple *stmt, enum tree_code,
						tree, tree, bool,
						bool *, bool *);

private:
  bool simplify_truth_ops_using_ranges (gimple_stmt_iterator *, gimple *);
  bool simplify_div_or_mod_using_ranges (gimple_stmt_iterator *, gimple *);
  bool simplify_abs_using_ranges (gimple_stmt_iterator *, gimple *);
  bool simplify_bit_ops_using_ranges (gimple_stmt_iterator *, gimple *);
  bool simplify_min_or_max_using_ranges (gimple_stmt_iterator *, gimple *);
  bool simplify_cond_using_ranges_1 (gcond *);
  bool fold_cond (gcond *);
  bool simplify_switch_using_ranges (gswitch *);
  bool simplify_float_conversion_using_ranges (gimple_stmt_iterator *,
					       gimple *);
  bool simplify_internal_call_using_ranges (gimple_stmt_iterator *, gimple *);

  bool two_valued_val_range_p (tree, tree *, tree *, gimple *);
  bool op_with_boolean_value_range_p (tree, gimple *);
  tree compare_name_with_value (enum tree_code, tree, tree, bool *, bool,
				gimple *);
  tree compare_names (enum tree_code, tree, tree, bool *, gimple *s);
  const value_range_equiv *get_vr_for_comparison (int, value_range_equiv *,
						  gimple *s);
  tree vrp_evaluate_conditional_warnv_with_ops_using_ranges (enum tree_code,
							     tree, tree,
							     bool *, gimple *s);
  void cleanup_edges_and_switches (void);

  /* Vectors of edges that need removing and switch statements that
     need updating.  It is expected that a pass using the simplification
     routines will, at the end of the pass, clean up the edges and
     switch statements.  The class dtor will try to detect cases
     that do not follow that expectation.  */
  struct switch_update {
    gswitch *stmt;
    tree vec;
  };

  vec<edge> to_remove_edges;
  vec<switch_update> to_update_switch_stmts;
  class range_query *query;
};

/* The VR_VALUES class holds the current view of range information
   for all the SSA_NAMEs in the IL.

   It can be used to hold context sensitive range information during
   a dominator walk or it may be used to hold range information in the
   standard VRP pass as ranges are propagated through the lattice to a
   steady state.

   This information is independent of the range information that gets
   attached to SSA_NAMEs.  A pass such as VRP may choose to transfer
   the global information it produces into global range information that
   gets attached to an SSA_NAME.  It's unclear how useful that global
   information will be in a world where we can compute context sensitive
   range information fast or perform on-demand queries.  */
class vr_values : public range_query
{
 public:
  vr_values (void);
  ~vr_values (void);

  virtual bool range_of_expr (irange &r, tree expr, gimple *stmt) OVERRIDE;
  virtual tree value_of_expr (tree, gimple * = NULL) OVERRIDE;
  virtual tree value_on_edge (edge, tree) OVERRIDE;
  virtual tree value_of_stmt (gimple *, tree = NULL_TREE) OVERRIDE;
  virtual const value_range_equiv *get_value_range (const_tree,
						    gimple * = NULL) OVERRIDE;
  void set_vr_value (tree, value_range_equiv *);
  value_range_equiv *swap_vr_value (tree, value_range_equiv *);

  void set_def_to_varying (const_tree);
  void set_defs_to_varying (gimple *);
  bool update_value_range (const_tree, value_range_equiv *);
  tree op_with_constant_singleton_value_range (tree);
  void adjust_range_with_scev (value_range_equiv *, class loop *,
			       gimple *, tree);
  virtual void dump (FILE *) OVERRIDE;

  void extract_range_for_var_from_comparison_expr (tree, enum tree_code,
						   tree, tree,
						   value_range_equiv *);
  void extract_range_from_phi_node (gphi *, value_range_equiv *);
  void extract_range_basic (value_range_equiv *, gimple *);
  void extract_range_from_stmt (gimple *, edge *, tree *, value_range_equiv *);

  /* Indicate that propagation through the lattice is complete.  */
  void set_lattice_propagation_complete (void) { values_propagated = true; }

  /* Allocate a new value_range object.  */
  value_range_equiv *allocate_value_range_equiv (void)
    { return range_query::allocate_value_range_equiv (); }
  void free_value_range (value_range_equiv *vr)
    { free_value_range_equiv (vr); }

 private:
  value_range_equiv *get_lattice_entry (const_tree);
  bool vrp_stmt_computes_nonzero (gimple *);
  void extract_range_from_assignment (value_range_equiv *, gassign *);
  void extract_range_from_assert (value_range_equiv *, tree);
  void extract_range_from_ssa_name (value_range_equiv *, tree);
  void extract_range_from_binary_expr (value_range_equiv *, enum tree_code,
				       tree, tree, tree);
  void extract_range_from_unary_expr (value_range_equiv *, enum tree_code,
				      tree, tree);
  void extract_range_from_cond_expr (value_range_equiv *, gassign *);
  void extract_range_from_comparison (value_range_equiv *, gimple *);
  void vrp_visit_assignment_or_call (gimple*, tree *, value_range_equiv *);
  void vrp_visit_switch_stmt (gswitch *, edge *);
  bool extract_range_from_ubsan_builtin (value_range_equiv *, gimple *);

  /* This probably belongs in the lattice rather than in here.  */
  bool values_propagated;

  /* Allocations for equivalences all come from this obstack.  */
  bitmap_obstack vrp_equiv_obstack;

  /* Value range array.  After propagation, VR_VALUE[I] holds the range
     of values that SSA name N_I may take.  */
  unsigned int num_vr_values;
  value_range_equiv **vr_value;

  /* For a PHI node which sets SSA name N_I, VR_COUNTS[I] holds the
     number of executable edges we saw the last time we visited the
     node.  */
  int *vr_phi_edge_counts;
  simplify_using_ranges simplifier;
};

extern tree get_output_for_vrp (gimple *);

extern bool range_fits_type_p (const value_range *vr,
			       unsigned dest_precision, signop dest_sgn);
extern bool bounds_of_var_in_loop (tree *min, tree *max, range_query *,
				   class loop *loop, gimple *stmt, tree var);

#endif /* GCC_VR_VALUES_H */
