/* Classes for purging state at function_points.
   Copyright (C) 2019-2020 Free Software Foundation, Inc.
   Contributed by David Malcolm <dmalcolm@redhat.com>.

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 "tree.h"
#include "timevar.h"
#include "tree-ssa-alias.h"
#include "function.h"
#include "basic-block.h"
#include "gimple.h"
#include "stringpool.h"
#include "tree-vrp.h"
#include "gimple-ssa.h"
#include "tree-ssanames.h"
#include "tree-phinodes.h"
#include "options.h"
#include "ssa-iterators.h"
#include "diagnostic-core.h"
#include "gimple-pretty-print.h"
#include "function.h"
#include "analyzer/analyzer.h"
#include "analyzer/call-string.h"
#include "digraph.h"
#include "ordered-hash-map.h"
#include "cfg.h"
#include "gimple-iterator.h"
#include "cgraph.h"
#include "analyzer/supergraph.h"
#include "analyzer/program-point.h"
#include "analyzer/analyzer-logging.h"
#include "analyzer/state-purge.h"

#if ENABLE_ANALYZER

/* state_purge_map's ctor.  Walk all SSA names in all functions, building
   a state_purge_per_ssa_name instance for each.  */

state_purge_map::state_purge_map (const supergraph &sg,
				  logger *logger)
: log_user (logger), m_sg (sg)
{
  LOG_FUNC (logger);

  auto_timevar tv (TV_ANALYZER_STATE_PURGE);

  cgraph_node *node;
  FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
  {
    function *fun = node->get_fun ();
    if (logger)
      log ("function: %s", function_name (fun));
    tree name;
    unsigned int i;;
    FOR_EACH_SSA_NAME (i, name, fun)
      {
	/* For now, don't bother tracking the .MEM SSA names.  */
	if (tree var = SSA_NAME_VAR (name))
	  if (TREE_CODE (var) == VAR_DECL)
	    if (VAR_DECL_IS_VIRTUAL_OPERAND (var))
	      continue;
	m_map.put (name, new state_purge_per_ssa_name (*this, name, fun));
      }
  }
}

/* state_purge_map's dtor.  */

state_purge_map::~state_purge_map ()
{
  for (iterator iter = m_map.begin (); iter != m_map.end (); ++iter)
    delete (*iter).second;
}

/* state_purge_per_ssa_name's ctor.

   Locate all uses of VAR within FUN.
   Walk backwards from each use, marking program points, until
   we reach the def stmt, populating m_points_needing_var.

   We have to track program points rather than
   just stmts since there could be empty basic blocks on the way.  */

state_purge_per_ssa_name::state_purge_per_ssa_name (const state_purge_map &map,
						    tree name,
						    function *fun)
: m_points_needing_name (), m_name (name), m_fun (fun)
{
  LOG_FUNC (map.get_logger ());

  if (map.get_logger ())
    {
      map.log ("SSA name: %qE within %qD", name, fun->decl);

      /* Show def stmt.  */
      const gimple *def_stmt = SSA_NAME_DEF_STMT (name);
      pretty_printer pp;
      pp_gimple_stmt_1 (&pp, def_stmt, 0, (dump_flags_t)0);
      map.log ("def stmt: %s", pp_formatted_text (&pp));
    }

  auto_vec<function_point> worklist;

  /* Add all immediate uses of name to the worklist.
     Compare with debug_immediate_uses.  */
  imm_use_iterator iter;
  use_operand_p use_p;
  FOR_EACH_IMM_USE_FAST (use_p, iter, name)
    {
      if (USE_STMT (use_p))
	{
	  const gimple *use_stmt = USE_STMT (use_p);
	  if (map.get_logger ())
	    {
	      pretty_printer pp;
	      pp_gimple_stmt_1 (&pp, use_stmt, 0, (dump_flags_t)0);
	      map.log ("used by stmt: %s", pp_formatted_text (&pp));
	    }

	  const supernode *snode
	    = map.get_sg ().get_supernode_for_stmt (use_stmt);

	  /* If it's a use within a phi node, then we care about
	     which in-edge we came from.  */
	  if (use_stmt->code == GIMPLE_PHI)
	    {
	      for (gphi_iterator gpi
		     = const_cast<supernode *> (snode)->start_phis ();
		   !gsi_end_p (gpi); gsi_next (&gpi))
		{
		  gphi *phi = gpi.phi ();
		  if (phi == use_stmt)
		    {
		      /* Find arguments (and thus in-edges) which use NAME.  */
		      for (unsigned arg_idx = 0;
			   arg_idx < gimple_phi_num_args (phi);
			   ++arg_idx)
			{
			  if (name == gimple_phi_arg (phi, arg_idx)->def)
			    {
			      edge in_edge = gimple_phi_arg_edge (phi, arg_idx);
			      const superedge *in_sedge
				= map.get_sg ().get_edge_for_cfg_edge (in_edge);
			      function_point point
				= function_point::before_supernode
				(snode, in_sedge);
			      add_to_worklist (point, &worklist,
					       map.get_logger ());
			      m_points_needing_name.add (point);
			    }
			}
		    }
		}
	    }
	  else
	    {
	      function_point point = before_use_stmt (map, use_stmt);
	      add_to_worklist (point, &worklist, map.get_logger ());
	      m_points_needing_name.add (point);

	      /* We also need to add uses for conditionals and switches,
		 where the stmt "happens" at the after_supernode, for filtering
		 the out-edges.  */
	      if (use_stmt == snode->get_last_stmt ())
		{
		  if (map.get_logger ())
		    map.log ("last stmt in BB");
		  function_point point
		    = function_point::after_supernode (snode);
		  add_to_worklist (point, &worklist, map.get_logger ());
		  m_points_needing_name.add (point);
		}
	      else
		if (map.get_logger ())
		  map.log ("not last stmt in BB");
	    }
	}
    }

  /* Process worklist by walking backwards until we reach the def stmt.  */
  {
    log_scope s (map.get_logger (), "processing worklist");
    while (worklist.length () > 0)
      {
	function_point point = worklist.pop ();
	process_point (point, &worklist, map);
    }
  }

  if (map.get_logger ())
    {
      map.log ("%qE in %qD is needed to process:", name, fun->decl);
      for (point_set_t::iterator iter = m_points_needing_name.begin ();
	   iter != m_points_needing_name.end ();
	   ++iter)
	{
	  map.start_log_line ();
	  map.get_logger ()->log_partial ("  point: ");
	  (*iter).print (map.get_logger ()->get_printer (), format (false));
	  map.end_log_line ();
	}
    }
}

/* Return true if the SSA name is needed at POINT.  */

bool
state_purge_per_ssa_name::needed_at_point_p (const function_point &point) const
{
  return const_cast <point_set_t &> (m_points_needing_name).contains (point);
}

/* Get the function_point representing immediately before USE_STMT.
   Subroutine of ctor.  */

function_point
state_purge_per_ssa_name::before_use_stmt (const state_purge_map &map,
					   const gimple *use_stmt)
{
  gcc_assert (use_stmt->code != GIMPLE_PHI);

  const supernode *supernode
    = map.get_sg ().get_supernode_for_stmt (use_stmt);
  unsigned int stmt_idx = supernode->get_stmt_index (use_stmt);
  return function_point::before_stmt (supernode, stmt_idx);
}

/* Add POINT to *WORKLIST if the point has not already been seen.
   Subroutine of ctor.  */

void
state_purge_per_ssa_name::add_to_worklist (const function_point &point,
					   auto_vec<function_point> *worklist,
					   logger *logger)
{
  LOG_FUNC (logger);
  if (logger)
    {
      logger->start_log_line ();
      logger->log_partial ("point: '");
      point.print (logger->get_printer (), format (false));
      logger->log_partial ("' for worklist for %qE", m_name);
      logger->end_log_line ();
    }

  gcc_assert (point.get_function () == m_fun);
  if (point.get_from_edge ())
    gcc_assert (point.get_from_edge ()->get_kind () == SUPEREDGE_CFG_EDGE);

  if (m_points_needing_name.contains (point))
    {
      if (logger)
	logger->log ("already seen for %qE", m_name);
    }
  else
    {
      if (logger)
	logger->log ("not seen; adding to worklist for %qE", m_name);
      m_points_needing_name.add (point);
      worklist->safe_push (point);
    }
}

/* Process POINT, popped from WORKLIST.
   Iterate over predecessors of POINT, adding to WORKLIST.  */

void
state_purge_per_ssa_name::process_point (const function_point &point,
					 auto_vec<function_point> *worklist,
					 const state_purge_map &map)
{
  logger *logger = map.get_logger ();
  LOG_FUNC (logger);
  if (logger)
    {
      logger->start_log_line ();
      logger->log_partial ("considering point: '");
      point.print (logger->get_printer (), format (false));
      logger->log_partial ("' for %qE", m_name);
      logger->end_log_line ();
    }

  gimple *def_stmt = SSA_NAME_DEF_STMT (m_name);

  const supernode *snode = point.get_supernode ();

  switch (point.get_kind ())
    {
    default:
      gcc_unreachable ();

    case PK_ORIGIN:
      break;

    case PK_BEFORE_SUPERNODE:
      {
	for (gphi_iterator gpi
	       = const_cast<supernode *> (snode)->start_phis ();
	     !gsi_end_p (gpi); gsi_next (&gpi))
	  {
	    gphi *phi = gpi.phi ();
	    if (phi == def_stmt)
	      {
		if (logger)
		  logger->log ("def stmt within phis; terminating");
		return;
	      }
	  }

	/* Add given pred to worklist.  */
	if (point.get_from_edge ())
	  {
	    gcc_assert (point.get_from_edge ()->m_src);
	    add_to_worklist
	      (function_point::after_supernode (point.get_from_edge ()->m_src),
	       worklist, logger);
	  }
	else
	  {
	    /* Add any intraprocedually edge for a call.  */
	    if (snode->m_returning_call)
	      {
		cgraph_edge *cedge
		  = supergraph_call_edge (snode->m_fun,
					  snode->m_returning_call);
		gcc_assert (cedge);
		superedge *sedge
		  = map.get_sg ().get_intraprocedural_edge_for_call (cedge);
		gcc_assert (sedge);
		add_to_worklist
		  (function_point::after_supernode (sedge->m_src),
		   worklist, logger);
	      }
	  }
      }
      break;

    case PK_BEFORE_STMT:
      {
	if (def_stmt == point.get_stmt ())
	  {
	    if (logger)
	      logger->log ("def stmt; terminating");
	    return;
	  }
	if (point.get_stmt_idx () > 0)
	  add_to_worklist (function_point::before_stmt
			     (snode, point.get_stmt_idx () - 1),
			   worklist, logger);
	else
	{
	  /* Add before_supernode to worklist.  This captures the in-edge,
	     so we have to do it once per in-edge.  */
	  unsigned i;
	  superedge *pred;
	  FOR_EACH_VEC_ELT (snode->m_preds, i, pred)
	    add_to_worklist (function_point::before_supernode (snode,
							       pred),
			     worklist, logger);
	}
      }
      break;

    case PK_AFTER_SUPERNODE:
      {
	if (snode->m_stmts.length ())
	  add_to_worklist
	    (function_point::before_stmt (snode,
					  snode->m_stmts.length () - 1),
	     worklist, logger);
	else
	  {
	    /* Add before_supernode to worklist.  This captures the in-edge,
	       so we have to do it once per in-edge.  */
	    unsigned i;
	    superedge *pred;
	    FOR_EACH_VEC_ELT (snode->m_preds, i, pred)
	      add_to_worklist (function_point::before_supernode (snode,
								 pred),
			       worklist, logger);
	    /* If it's the initial BB, add it, to ensure that we
	       have "before supernode" for the initial ENTRY block, and don't
	       erroneously purge SSA names for initial values of parameters.  */
	    if (snode->entry_p ())
	      {
		add_to_worklist
		  (function_point::before_supernode (snode, NULL),
		   worklist, logger);
	      }
	  }
      }
      break;
    }
}

/* class state_purge_annotator : public dot_annotator.  */

/* Implementation of dot_annotator::add_node_annotations vfunc for
   state_purge_annotator.

   Add an additional record showing which names are purged on entry
   to the supernode N.  */

bool
state_purge_annotator::add_node_annotations (graphviz_out *gv,
					     const supernode &n,
					     bool within_table) const
{
  if (m_map == NULL)
    return false;

  if (within_table)
    return false;

  pretty_printer *pp = gv->get_pp ();

   pp_printf (pp, "annotation_for_node_%i", n.m_index);
   pp_printf (pp, " [shape=none,margin=0,style=filled,fillcolor=%s,label=\"",
	      "lightblue");
   pp_write_text_to_stream (pp);

   // FIXME: passing in a NULL in-edge means we get no hits
   function_point before_supernode
     (function_point::before_supernode (&n, NULL));

   for (state_purge_map::iterator iter = m_map->begin ();
	iter != m_map->end ();
	++iter)
     {
       tree name = (*iter).first;
       state_purge_per_ssa_name *per_name_data = (*iter).second;
       if (per_name_data->get_function () == n.m_fun)
	 {
	   if (per_name_data->needed_at_point_p (before_supernode))
	     pp_printf (pp, "%qE needed here", name);
	   else
	     pp_printf (pp, "%qE not needed here", name);
	 }
       pp_newline (pp);
     }

   pp_string (pp, "\"];\n\n");
   pp_flush (pp);
   return false;
}

/* Print V to GV as a comma-separated list in braces within a <TR>,
   titling it with TITLE.

   Subroutine of state_purge_annotator::add_stmt_annotations.  */

static void
print_vec_of_names (graphviz_out *gv, const char *title,
		    const auto_vec<tree> &v)
{
  pretty_printer *pp = gv->get_pp ();
  tree name;
  unsigned i;
  gv->begin_trtd ();
  pp_printf (pp, "%s: {", title);
  FOR_EACH_VEC_ELT (v, i, name)
    {
      if (i > 0)
	pp_string (pp, ", ");
      pp_printf (pp, "%qE", name);
    }
  pp_printf (pp, "}");
  pp_write_text_as_html_like_dot_to_stream (pp);
  gv->end_tdtr ();
  pp_newline (pp);
}

/* Implementation of dot_annotator::add_stmt_annotations for
   state_purge_annotator.

   Add text showing which names are purged at STMT.  */

void
state_purge_annotator::add_stmt_annotations (graphviz_out *gv,
					     const gimple *stmt,
					     bool within_row) const
{
  if (within_row)
    return;

  if (m_map == NULL)
    return;

  if (stmt->code == GIMPLE_PHI)
    return;

  pretty_printer *pp = gv->get_pp ();

  pp_newline (pp);

  const supernode *supernode = m_map->get_sg ().get_supernode_for_stmt (stmt);
  unsigned int stmt_idx = supernode->get_stmt_index (stmt);
  function_point before_stmt
    (function_point::before_stmt (supernode, stmt_idx));

  auto_vec<tree> needed;
  auto_vec<tree> not_needed;
  for (state_purge_map::iterator iter = m_map->begin ();
       iter != m_map->end ();
       ++iter)
    {
      tree name = (*iter).first;
      state_purge_per_ssa_name *per_name_data = (*iter).second;
      if (per_name_data->get_function () == supernode->m_fun)
	{
	  if (per_name_data->needed_at_point_p (before_stmt))
	    needed.safe_push (name);
	  else
	    not_needed.safe_push (name);
	}
    }

  print_vec_of_names (gv, "needed here", needed);
  print_vec_of_names (gv, "not needed here", not_needed);
}

#endif /* #if ENABLE_ANALYZER */
