/* Support routines for Value Range Propagation (VRP).
   Copyright (C) 2005-2019 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/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "tree.h"
#include "gimple.h"
#include "tree-pass.h"
#include "ssa.h"
#include "gimple-pretty-print.h"
#include "cfganal.h"
#include "gimple-fold.h"
#include "tree-eh.h"
#include "gimple-iterator.h"
#include "tree-cfg.h"
#include "tree-ssa-loop-manip.h"
#include "tree-ssa-loop.h"
#include "cfgloop.h"
#include "tree-scalar-evolution.h"
#include "tree-ssa-propagate.h"
#include "alloc-pool.h"
#include "domwalk.h"
#include "tree-cfgcleanup.h"
#include "vr-values.h"
#include "gimple-ssa-evrp-analyze.h"

evrp_range_analyzer::evrp_range_analyzer (bool update_global_ranges)
  : stack (10), m_update_global_ranges (update_global_ranges)
{
  edge e;
  edge_iterator ei;
  basic_block bb;
  FOR_EACH_BB_FN (bb, cfun)
    {
      bb->flags &= ~BB_VISITED;
      FOR_EACH_EDGE (e, ei, bb->preds)
        e->flags |= EDGE_EXECUTABLE;
    }
  vr_values = new class vr_values;
}

/* Push an unwinding marker onto the unwinding stack.  */

void
evrp_range_analyzer::push_marker ()
{
  stack.safe_push (std::make_pair (NULL_TREE, (value_range *)NULL));
}

/* Analyze ranges as we enter basic block BB.  */

void
evrp_range_analyzer::enter (basic_block bb)
{
  if (!optimize)
    return;
  push_marker ();
  record_ranges_from_incoming_edge (bb);
  record_ranges_from_phis (bb);
  bb->flags |= BB_VISITED;
}

/* Find new range for NAME such that (OP CODE LIMIT) is true.  */
value_range *
evrp_range_analyzer::try_find_new_range (tree name,
				    tree op, tree_code code, tree limit)
{
  value_range vr;
  const value_range *old_vr = get_value_range (name);

  /* Discover VR when condition is true.  */
  vr_values->extract_range_for_var_from_comparison_expr (name, code, op,
							 limit, &vr);
  /* If we found any usable VR, set the VR to ssa_name and create a
     PUSH old value in the stack with the old VR.  */
  if (!vr.undefined_p () && !vr.varying_p ())
    {
      if (old_vr->kind () == vr.kind ()
	  && vrp_operand_equal_p (old_vr->min (), vr.min ())
	  && vrp_operand_equal_p (old_vr->max (), vr.max ()))
	return NULL;
      value_range *new_vr = vr_values->allocate_value_range ();
      new_vr->move (&vr);
      return new_vr;
    }
  return NULL;
}

/* For LHS record VR in the SSA info.  */
void
evrp_range_analyzer::set_ssa_range_info (tree lhs, value_range *vr)
{
  gcc_assert (m_update_global_ranges);

  /* Set the SSA with the value range.  */
  if (INTEGRAL_TYPE_P (TREE_TYPE (lhs)))
    {
      if (vr->constant_p ())
	set_range_info (lhs, vr->kind (),
			wi::to_wide (vr->min ()),
			wi::to_wide (vr->max ()));
    }
  else if (POINTER_TYPE_P (TREE_TYPE (lhs))
	   && range_includes_zero_p (vr) == 0)
    set_ptr_nonnull (lhs);
}

/* Return true if all uses of NAME are dominated by STMT or feed STMT
   via a chain of single immediate uses.  */

static bool
all_uses_feed_or_dominated_by_stmt (tree name, gimple *stmt)
{
  use_operand_p use_p, use2_p;
  imm_use_iterator iter;
  basic_block stmt_bb = gimple_bb (stmt);

  FOR_EACH_IMM_USE_FAST (use_p, iter, name)
    {
      gimple *use_stmt = USE_STMT (use_p), *use_stmt2;
      if (use_stmt == stmt
	  || is_gimple_debug (use_stmt)
	  || (gimple_bb (use_stmt) != stmt_bb
	      && dominated_by_p (CDI_DOMINATORS,
				 gimple_bb (use_stmt), stmt_bb)))
	continue;
      while (use_stmt != stmt
	     && is_gimple_assign (use_stmt)
	     && TREE_CODE (gimple_assign_lhs (use_stmt)) == SSA_NAME
	     && single_imm_use (gimple_assign_lhs (use_stmt),
				&use2_p, &use_stmt2))
	use_stmt = use_stmt2;
      if (use_stmt != stmt)
	return false;
    }
  return true;
}

void
evrp_range_analyzer::record_ranges_from_incoming_edge (basic_block bb)
{
  edge pred_e = single_pred_edge_ignoring_loop_edges (bb, false);
  if (pred_e)
    {
      gimple *stmt = last_stmt (pred_e->src);
      tree op0 = NULL_TREE;

      if (stmt
	  && gimple_code (stmt) == GIMPLE_COND
	  && (op0 = gimple_cond_lhs (stmt))
	  && TREE_CODE (op0) == SSA_NAME
	  && (INTEGRAL_TYPE_P (TREE_TYPE (gimple_cond_lhs (stmt)))
	      || POINTER_TYPE_P (TREE_TYPE (gimple_cond_lhs (stmt)))))
	{
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    {
	      fprintf (dump_file, "Visiting controlling predicate ");
	      print_gimple_stmt (dump_file, stmt, 0);
	    }
	  /* Entering a new scope.  Try to see if we can find a VR
	     here.  */
	  tree op1 = gimple_cond_rhs (stmt);
	  if (TREE_OVERFLOW_P (op1))
	    op1 = drop_tree_overflow (op1);
	  tree_code code = gimple_cond_code (stmt);

	  auto_vec<assert_info, 8> asserts;
	  register_edge_assert_for (op0, pred_e, code, op0, op1, asserts);
	  if (TREE_CODE (op1) == SSA_NAME)
	    register_edge_assert_for (op1, pred_e, code, op0, op1, asserts);

	  auto_vec<std::pair<tree, value_range *>, 8> vrs;
	  for (unsigned i = 0; i < asserts.length (); ++i)
	    {
	      value_range *vr = try_find_new_range (asserts[i].name,
						    asserts[i].expr,
						    asserts[i].comp_code,
						    asserts[i].val);
	      if (vr)
		vrs.safe_push (std::make_pair (asserts[i].name, vr));
	    }

	  /* If pred_e is really a fallthru we can record value ranges
	     in SSA names as well.  */
	  bool is_fallthru = assert_unreachable_fallthru_edge_p (pred_e);

	  /* Push updated ranges only after finding all of them to avoid
	     ordering issues that can lead to worse ranges.  */
	  for (unsigned i = 0; i < vrs.length (); ++i)
	    {
	      /* But make sure we do not weaken ranges like when
	         getting first [64, +INF] and then ~[0, 0] from
		 conditions like (s & 0x3cc0) == 0).  */
	      const value_range *old_vr = get_value_range (vrs[i].first);
	      value_range_base tem (old_vr->kind (), old_vr->min (),
				    old_vr->max ());
	      tem.intersect (vrs[i].second);
	      if (tem.equal_p (*old_vr))
		{
		  vr_values->free_value_range (vrs[i].second);
		  continue;
		}
	      push_value_range (vrs[i].first, vrs[i].second);
	      if (is_fallthru
		  && m_update_global_ranges
		  && all_uses_feed_or_dominated_by_stmt (vrs[i].first, stmt))
		{
		  set_ssa_range_info (vrs[i].first, vrs[i].second);
		  maybe_set_nonzero_bits (pred_e, vrs[i].first);
		}
	    }
	}
    }
}

void
evrp_range_analyzer::record_ranges_from_phis (basic_block bb)
{
  /* Visit PHI stmts and discover any new VRs possible.  */
  bool has_unvisited_preds = false;
  edge_iterator ei;
  edge e;
  FOR_EACH_EDGE (e, ei, bb->preds)
    if (e->flags & EDGE_EXECUTABLE
	&& !(e->src->flags & BB_VISITED))
      {
	has_unvisited_preds = true;
	break;
      }

  for (gphi_iterator gpi = gsi_start_phis (bb);
       !gsi_end_p (gpi); gsi_next (&gpi))
    {
      gphi *phi = gpi.phi ();
      tree lhs = PHI_RESULT (phi);
      if (virtual_operand_p (lhs))
	continue;

      /* Skips floats and other things we can't represent in a
	 range.  */
      if (!value_range_base::supports_type_p (TREE_TYPE (lhs)))
	continue;

      value_range vr_result;
      bool interesting = stmt_interesting_for_vrp (phi);
      if (!has_unvisited_preds && interesting)
	vr_values->extract_range_from_phi_node (phi, &vr_result);
      else
	{
	  vr_result.set_varying (TREE_TYPE (lhs));
	  /* When we have an unvisited executable predecessor we can't
	     use PHI arg ranges which may be still UNDEFINED but have
	     to use VARYING for them.  But we can still resort to
	     SCEV for loop header PHIs.  */
	  class loop *l;
	  if (scev_initialized_p ()
	      && interesting
	      && (l = loop_containing_stmt (phi))
	      && l->header == gimple_bb (phi))
	  vr_values->adjust_range_with_scev (&vr_result, l, phi, lhs);
	}
      vr_values->update_value_range (lhs, &vr_result);

      /* Set the SSA with the value range.  */
      if (m_update_global_ranges)
	set_ssa_range_info (lhs, &vr_result);
    }
}

/* Record ranges from STMT into our VR_VALUES class.  If TEMPORARY is
   true, then this is a temporary equivalence and should be recorded
   into the unwind table.  Othewise record the equivalence into the
   global table.  */

void
evrp_range_analyzer::record_ranges_from_stmt (gimple *stmt, bool temporary)
{
  tree output = NULL_TREE;

  if (!optimize)
    return;

  if (dyn_cast <gcond *> (stmt))
    ;
  else if (stmt_interesting_for_vrp (stmt))
    {
      edge taken_edge;
      value_range vr;
      vr_values->extract_range_from_stmt (stmt, &taken_edge, &output, &vr);
      if (output)
	{
	  /* Set the SSA with the value range.  There are two cases to
	     consider.  First (the the most common) is we are processing
	     STMT in a context where its resulting range globally holds
	     and thus it can be reflected into the global ranges and need
	     not be unwound as we leave scope.

	     The second case occurs if we are processing a statement in
	     a context where the resulting range must not be reflected
	     into the global tables and must be unwound as we leave
	     the current context.  This happens in jump threading for
	     example.  */
	  if (!temporary)
	    {
	      /* Case one.  We can just update the underlying range
		 information as well as the global information.  */
	      vr_values->update_value_range (output, &vr);
	      if (m_update_global_ranges)
		set_ssa_range_info (output, &vr);
	    }
	  else
	    {
	      /* We're going to need to unwind this range.  We cannot
		 use VR as that's a stack object.  We have to allocate
		 a new range and push the old range onto the stack.  We
		 also have to be very careful about sharing the underlying
		 bitmaps.  Ugh.  */
	      value_range *new_vr = vr_values->allocate_value_range ();
	      new_vr->set (vr.kind (), vr.min (), vr.max ());
	      vr.equiv_clear ();
	      push_value_range (output, new_vr);
	    }
	}
      else
	vr_values->set_defs_to_varying (stmt);
    }
  else
    vr_values->set_defs_to_varying (stmt);

  /* See if we can derive a range for any of STMT's operands.  */
  tree op;
  ssa_op_iter i;
  FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_USE)
    {
      tree value;
      enum tree_code comp_code;

      /* If OP is used in such a way that we can infer a value
         range for it, and we don't find a previous assertion for
         it, create a new assertion location node for OP.  */
      if (infer_value_range (stmt, op, &comp_code, &value))
	{
	  /* If we are able to infer a nonzero value range for OP,
	     then walk backwards through the use-def chain to see if OP
	     was set via a typecast.
	     If so, then we can also infer a nonzero value range
	     for the operand of the NOP_EXPR.  */
	  if (comp_code == NE_EXPR && integer_zerop (value))
	    {
	      tree t = op;
	      gimple *def_stmt = SSA_NAME_DEF_STMT (t);
	      while (is_gimple_assign (def_stmt)
		     && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt))
		     && TREE_CODE
			  (gimple_assign_rhs1 (def_stmt)) == SSA_NAME
		     && POINTER_TYPE_P
			  (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
		{
		  t = gimple_assign_rhs1 (def_stmt);
		  def_stmt = SSA_NAME_DEF_STMT (t);

		  /* Add VR when (T COMP_CODE value) condition is
		     true.  */
		  value_range *op_range
		    = try_find_new_range (t, t, comp_code, value);
		  if (op_range)
		    push_value_range (t, op_range);
		}
	    }
	  /* Add VR when (OP COMP_CODE value) condition is true.  */
	  value_range *op_range = try_find_new_range (op, op,
						      comp_code, value);
	  if (op_range)
	    push_value_range (op, op_range);
	}
    }
}

/* Unwind recorded ranges to their most recent state.  */

void
evrp_range_analyzer::pop_to_marker (void)
{
  gcc_checking_assert (!stack.is_empty ());
  while (stack.last ().first != NULL_TREE)
    pop_value_range ();
  stack.pop ();
}

/* Restore/pop VRs valid only for BB when we leave BB.  */

void
evrp_range_analyzer::leave (basic_block bb ATTRIBUTE_UNUSED)
{
  if (!optimize)
    return;
  pop_to_marker ();
}


/* Push the Value Range of VAR to the stack and update it with new VR.  */

void
evrp_range_analyzer::push_value_range (tree var, value_range *vr)
{
  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "pushing new range for ");
      print_generic_expr (dump_file, var);
      fprintf (dump_file, ": ");
      dump_value_range (dump_file, vr);
      fprintf (dump_file, "\n");
    }
  value_range *old_vr = vr_values->swap_vr_value (var, vr);
  stack.safe_push (std::make_pair (var, old_vr));
}

/* Pop a Value Range from the vrp_stack.  */

void
evrp_range_analyzer::pop_value_range ()
{
  std::pair<tree, value_range *> e = stack.pop ();
  tree var = e.first;
  value_range *vr = e.second;
  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "popping range for ");
      print_generic_expr (dump_file, var);
      fprintf (dump_file, ", restoring ");
      dump_value_range (dump_file, vr);
      fprintf (dump_file, "\n");
    }
  /* We saved off a lattice entry, now give it back and release
     the one we popped.  */
  value_range *popped_vr = vr_values->swap_vr_value (var, vr);
  if (popped_vr)
    vr_values->free_value_range (popped_vr);
}
