/* 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"

class evrp_folder : public substitute_and_fold_engine
{
 public:
  tree get_value (tree) FINAL OVERRIDE;
  evrp_folder (class vr_values *vr_values_) : vr_values (vr_values_) { }
  bool simplify_stmt_using_ranges (gimple_stmt_iterator *gsi)
    { return vr_values->simplify_stmt_using_ranges (gsi); }
  class vr_values *vr_values;

 private:
  DISABLE_COPY_AND_ASSIGN (evrp_folder);
};

tree
evrp_folder::get_value (tree op)
{
  return vr_values->op_with_constant_singleton_value_range (op);
}

/* evrp_dom_walker visits the basic blocks in the dominance order and set
   the Value Ranges (VR) for SSA_NAMEs in the scope.  Use this VR to
   discover more VRs.  */

class evrp_dom_walker : public dom_walker
{
public:
  evrp_dom_walker ()
    : dom_walker (CDI_DOMINATORS),
      evrp_range_analyzer (true),
      evrp_folder (evrp_range_analyzer.get_vr_values ())
    {
      need_eh_cleanup = BITMAP_ALLOC (NULL);
    }
  ~evrp_dom_walker ()
    {
      BITMAP_FREE (need_eh_cleanup);
    }
  virtual edge before_dom_children (basic_block);
  virtual void after_dom_children (basic_block);
  void cleanup (void);

 private:
  DISABLE_COPY_AND_ASSIGN (evrp_dom_walker);
  bitmap need_eh_cleanup;
  auto_vec<gimple *> stmts_to_fixup;
  auto_vec<gimple *> stmts_to_remove;

  class evrp_range_analyzer evrp_range_analyzer;
  class evrp_folder evrp_folder;
};

edge
evrp_dom_walker::before_dom_children (basic_block bb)
{
  if (dump_file && (dump_flags & TDF_DETAILS))
    fprintf (dump_file, "Visiting BB%d\n", bb->index);

  evrp_range_analyzer.enter (bb);

  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;

      const value_range_equiv *vr = evrp_range_analyzer.get_value_range (lhs);
      /* Mark PHIs whose lhs we fully propagate for removal.  */
      tree val;
      if (vr->singleton_p (&val) && may_propagate_copy (lhs, val))
	{
	  stmts_to_remove.safe_push (phi);
	  continue;
	}
    }

  edge taken_edge = NULL;

  /* Visit all other stmts and discover any new VRs possible.  */
  for (gimple_stmt_iterator gsi = gsi_start_bb (bb);
       !gsi_end_p (gsi); gsi_next (&gsi))
    {
      gimple *stmt = gsi_stmt (gsi);
      tree output = NULL_TREE;
      gimple *old_stmt = stmt;
      bool was_noreturn = (is_gimple_call (stmt)
			   && gimple_call_noreturn_p (stmt));

      if (dump_file && (dump_flags & TDF_DETAILS))
	{
	  fprintf (dump_file, "Visiting stmt ");
	  print_gimple_stmt (dump_file, stmt, 0);
	}

      evrp_range_analyzer.record_ranges_from_stmt (stmt, false);

      if (gcond *cond = dyn_cast <gcond *> (stmt))
	{
	  evrp_range_analyzer.vrp_visit_cond_stmt (cond, &taken_edge);
	  if (taken_edge)
	    {
	      if (taken_edge->flags & EDGE_TRUE_VALUE)
		gimple_cond_make_true (cond);
	      else if (taken_edge->flags & EDGE_FALSE_VALUE)
		gimple_cond_make_false (cond);
	      else
		gcc_unreachable ();
	      update_stmt (stmt);
	    }
	}
      else if (stmt_interesting_for_vrp (stmt))
	{
	  output = get_output_for_vrp (stmt);
	  if (output)
	    {
	      const value_range_equiv *vr
		= evrp_range_analyzer.get_value_range (output);

	      /* Mark stmts whose output we fully propagate for removal.  */
	      tree val;
	      if (vr->singleton_p (&val)
		  && may_propagate_copy (output, val)
		  && !stmt_could_throw_p (cfun, stmt)
		  && !gimple_has_side_effects (stmt))
		{
		  stmts_to_remove.safe_push (stmt);
		  continue;
		}
	    }
	}

      /* Try folding stmts with the VR discovered.  */
      bool did_replace = evrp_folder.replace_uses_in (stmt);
      gimple_stmt_iterator prev_gsi = gsi;
      gsi_prev (&prev_gsi);
      if (fold_stmt (&gsi, follow_single_use_edges)
	  || did_replace)
	{
	  stmt = gsi_stmt (gsi);
	  update_stmt (stmt);
	  did_replace = true;
	}
      if (evrp_folder.simplify_stmt_using_ranges (&gsi))
	{
	  stmt = gsi_stmt (gsi);
	  update_stmt (stmt);
	  did_replace = true;
	}

      if (did_replace)
	{
	  /* If we wound up generating new stmts during folding
	     drop all their defs to VARYING.  We can't easily
	     process them because we've already instantiated
	     ranges on uses on STMT that only hold after it.  */
	  if (gsi_end_p (prev_gsi))
	    prev_gsi = gsi_start_bb (bb);
	  else
	    gsi_next (&prev_gsi);
	  while (gsi_stmt (prev_gsi) != gsi_stmt (gsi))
	    {
	      evrp_range_analyzer.get_vr_values ()
		->set_defs_to_varying (gsi_stmt (prev_gsi));
	      gsi_next (&prev_gsi);
	    }

	  /* If we cleaned up EH information from the statement,
	     remove EH edges.  */
	  if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt))
	    bitmap_set_bit (need_eh_cleanup, bb->index);

	  /* If we turned a not noreturn call into a noreturn one
	     schedule it for fixup.  */
	  if (!was_noreturn
	      && is_gimple_call (stmt)
	      && gimple_call_noreturn_p (stmt))
	    stmts_to_fixup.safe_push (stmt);

	  if (gimple_assign_single_p (stmt))
	    {
	      tree rhs = gimple_assign_rhs1 (stmt);
	      if (TREE_CODE (rhs) == ADDR_EXPR)
		recompute_tree_invariant_for_addr_expr (rhs);
	    }
	}
    }

  /* Visit BB successor PHI nodes and replace PHI args.  */
  edge e;
  edge_iterator ei;
  FOR_EACH_EDGE (e, ei, bb->succs)
    {
      for (gphi_iterator gpi = gsi_start_phis (e->dest);
	   !gsi_end_p (gpi); gsi_next (&gpi))
	{
	  gphi *phi = gpi.phi ();
	  use_operand_p use_p = PHI_ARG_DEF_PTR_FROM_EDGE (phi, e);
	  tree arg = USE_FROM_PTR (use_p);
	  if (TREE_CODE (arg) != SSA_NAME
	      || virtual_operand_p (arg))
	    continue;
	  const value_range_equiv
	    *vr = evrp_range_analyzer.get_value_range (arg);
	  tree val;
	  if (vr->singleton_p (&val) && may_propagate_copy (arg, val))
	    propagate_value (use_p, val);
	}
    }
 
  return taken_edge;
}

void
evrp_dom_walker::after_dom_children (basic_block bb)
{
  evrp_range_analyzer.leave (bb);
}

/* Perform any cleanups after the main phase of EVRP has completed.  */

void
evrp_dom_walker::cleanup (void)
{
  if (dump_file)
    {
      fprintf (dump_file, "\nValue ranges after Early VRP:\n\n");
      evrp_range_analyzer.dump_all_value_ranges (dump_file);
      fprintf (dump_file, "\n");
    }

  /* Remove stmts in reverse order to make debug stmt creation possible.  */
  while (! stmts_to_remove.is_empty ())
    {
      gimple *stmt = stmts_to_remove.pop ();
      if (dump_file && dump_flags & TDF_DETAILS)
	{
	  fprintf (dump_file, "Removing dead stmt ");
	  print_gimple_stmt (dump_file, stmt, 0);
	  fprintf (dump_file, "\n");
	}
      gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
      if (gimple_code (stmt) == GIMPLE_PHI)
	remove_phi_node (&gsi, true);
      else
	{
	  unlink_stmt_vdef (stmt);
	  gsi_remove (&gsi, true);
	  release_defs (stmt);
	}
    }

  if (!bitmap_empty_p (need_eh_cleanup))
    gimple_purge_all_dead_eh_edges (need_eh_cleanup);

  /* Fixup stmts that became noreturn calls.  This may require splitting
     blocks and thus isn't possible during the dominator walk.  Do this
     in reverse order so we don't inadvertedly remove a stmt we want to
     fixup by visiting a dominating now noreturn call first.  */
  while (!stmts_to_fixup.is_empty ())
    {
      gimple *stmt = stmts_to_fixup.pop ();
      fixup_noreturn_call (stmt);
    }

  evrp_folder.vr_values->cleanup_edges_and_switches ();
}

/* Main entry point for the early vrp pass which is a simplified non-iterative
   version of vrp where basic blocks are visited in dominance order.  Value
   ranges discovered in early vrp will also be used by ipa-vrp.  */

static unsigned int
execute_early_vrp ()
{
  /* Ideally this setup code would move into the ctor for the dominator
     walk.  However, this setup can change the number of blocks which
     invalidates the internal arrays that are set up by the dominator
     walker.  */
  loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS);
  rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
  scev_initialize ();
  calculate_dominance_info (CDI_DOMINATORS);

  /* Walk stmts in dominance order and propagate VRP.  */
  evrp_dom_walker walker;
  walker.walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
  walker.cleanup ();

  scev_finalize ();
  loop_optimizer_finalize ();
  return 0;
}

namespace {

const pass_data pass_data_early_vrp =
{
  GIMPLE_PASS, /* type */
  "evrp", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_TREE_EARLY_VRP, /* tv_id */
  PROP_ssa, /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  ( TODO_cleanup_cfg | TODO_update_ssa | TODO_verify_all ),
};

class pass_early_vrp : public gimple_opt_pass
{
public:
  pass_early_vrp (gcc::context *ctxt)
    : gimple_opt_pass (pass_data_early_vrp, ctxt)
    {}

  /* opt_pass methods: */
  opt_pass * clone () { return new pass_early_vrp (m_ctxt); }
  virtual bool gate (function *)
    {
      return flag_tree_vrp != 0;
    }
  virtual unsigned int execute (function *)
    { return execute_early_vrp (); }

}; // class pass_vrp
} // anon namespace

gimple_opt_pass *
make_pass_early_vrp (gcc::context *ctxt)
{
  return new pass_early_vrp (ctxt);
}

