/* Paths within an exploded_graph.
   Copyright (C) 2019-2026 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 "analyzer/common.h"

#include "analyzer/exploded-path.h"

#if ENABLE_ANALYZER

namespace ana {

// struct diagnostic_state

void
diagnostic_state::dump_to_pp (pretty_printer *pp) const
{
  pp_printf (pp, "%s: {", m_debug_desc.c_str ());
  if (m_region_holding_value)
    {
      pp_string (pp, "region holding value: ");
      m_region_holding_value->dump_to_pp (pp, false);
    }
  pp_string (pp, "}");
}

void
diagnostic_state::dump () const
{
  tree_dump_pretty_printer pp (stderr);
  dump_to_pp (&pp);
  pp_newline (&pp);
}

/* class exploded_path.  */

/* Look for the last use of SEARCH_STMT within this path.
   If found write the edge's index to *OUT_IDX and return true, otherwise
   return false.  */

bool
exploded_path::find_stmt_backwards (const gimple *search_stmt,
				    int *out_idx) const
{
  for (int i = m_elements.size () - 1; i >= 0; --i)
    {
      const element_t *element = &m_elements[i];
      const exploded_edge *eedge = element->m_eedge;
      if (search_stmt->code == GIMPLE_PHI)
	{
	  /* Each phis_for_edge_op instance handles multiple phi stmts
	     at once, so we have to special-case the search for a phi stmt.  */
	  if (auto op = eedge->maybe_get_op ())
	    if (auto phis_op = op->dyn_cast_phis_for_edge_op ())
	      if (phis_op->defines_ssa_name_p (gimple_phi_result (search_stmt)))
		{
		  *out_idx = i;
		  return true;
		}
	}
      else
	{
	  /* Non-phi stmt.  */
	  if (const gimple *stmt = eedge->maybe_get_stmt ())
	    if (stmt == search_stmt)
	      {
		*out_idx = i;
		return true;
	      }
	}
    }
  return false;
}

/* Get the final exploded_node in this path, which must be non-empty.  */

exploded_node *
exploded_path::get_final_enode () const
{
  gcc_assert (m_elements.size () > 0);
  return m_elements.back ().m_eedge->m_dest;
}

/* Check state along this path, returning true if it is feasible.
   If OUT is non-NULL, and the path is infeasible, write a new
   feasibility_problem to *OUT.  */

bool
exploded_path::feasible_p (logger *logger,
			   std::unique_ptr<feasibility_problem> *out,
			   engine *eng, const exploded_graph *eg) const
{
  LOG_SCOPE (logger);

  feasibility_state state (eng->get_model_manager (),
			   eg->get_supergraph ());

  /* Traverse the path, updating this state.  */
  for (unsigned edge_idx = 0; edge_idx < m_elements.size (); ++edge_idx)
    {
      const exploded_edge *eedge = m_elements[edge_idx].m_eedge;
      if (logger)
	logger->log ("considering edge %i: EN:%i -> EN:%i",
		     edge_idx,
		     eedge->m_src->m_index,
		     eedge->m_dest->m_index);

      std::unique_ptr <rejected_constraint> rc;
      if (!state.maybe_update_for_edge (logger, eedge, nullptr, &rc))
	{
	  gcc_assert (rc);
	  if (out)
	    *out = std::make_unique<feasibility_problem> (edge_idx, *eedge,
							  std::move (rc));
	  return false;
	}

      if (logger)
	{
	  logger->log ("state after edge %i: EN:%i -> EN:%i",
		       edge_idx,
		       eedge->m_src->m_index,
		       eedge->m_dest->m_index);
	  logger->start_log_line ();
	  state.get_model ().dump_to_pp (logger->get_printer (), true, false);
	  logger->end_log_line ();
	}
    }

  return true;
}

/* Dump this path in multiline form to PP.
   If EXT_STATE is non-NULL, then show the nodes.  */

void
exploded_path::dump_to_pp (pretty_printer *pp,
			   const extrinsic_state *ext_state) const
{
  for (unsigned i = 0; i < m_elements.size (); ++i)
    {
      const element_t &element = m_elements[i];
      const exploded_edge *eedge = element.m_eedge;
      pp_printf (pp, "m_elements[%i]: EN %i -> EN %i",
		 i,
		 eedge->m_src->m_index,
		 eedge->m_dest->m_index);
      if (element.m_state_transition)
	{
	  pp_string (pp, " {");
	  element.m_state_transition->dump_to_pp (pp);
	  pp_string (pp, "}");
	}
      pp_newline (pp);

      if (ext_state)
	eedge->m_dest->dump_to_pp (pp, *ext_state);
    }
}

/* Dump this path in multiline form to FP.  */

void
exploded_path::dump (FILE *fp, const extrinsic_state *ext_state) const
{
  tree_dump_pretty_printer pp (fp);
  dump_to_pp (&pp, ext_state);
}

/* Dump this path in multiline form to stderr.  */

DEBUG_FUNCTION void
exploded_path::dump (const extrinsic_state *ext_state) const
{
  dump (stderr, ext_state);
}

/* Dump this path verbosely to FILENAME.  */

void
exploded_path::dump_to_file (const char *filename,
			     const extrinsic_state &ext_state) const
{
  FILE *fp = fopen (filename, "w");
  if (!fp)
    return;
  pretty_printer pp;
  pp_format_decoder (&pp) = default_tree_printer;
  pp.set_output_stream (fp);
  dump_to_pp (&pp, &ext_state);
  pp_flush (&pp);
  fclose (fp);
}

/* Print a multiline form of this path to LOGGER, prefixing it with DESC.  */

void
exploded_path::maybe_log (logger *logger, const char *desc) const
{
  if (!logger)
    return;
  logger->start_log_line ();
  logger->log_partial ("%s: ", desc);
  logger->end_log_line ();
  for (unsigned idx = 0; idx < m_elements.size (); idx++)
    {
      const exploded_edge &eedge = *m_elements[idx].m_eedge;
      const exploded_node *src_node = eedge.m_src;
      const program_point &src_point = src_node->get_point ();
      const exploded_node *dst_node = eedge.m_dest;
      const program_point &dst_point = dst_node->get_point ();

      pretty_printer *pp = logger->get_printer ();
      logger->start_log_line ();
      pp_printf (pp, "  [%i] EN %i -> EN %i: ",
		 idx,
		 src_node->m_index,
		 dst_node->m_index);
      src_point.print (pp, format (false));
      pp_string (pp, " -> ");
      dst_point.print (pp, format (false));
      if (auto state_trans = m_elements[idx].m_state_transition.get ())
	{
	  pp_string (pp, " {");
	  state_trans->dump_to_pp (pp);
	  pp_string (pp, "}");
	}
      logger->end_log_line ();
    }
}

void
exploded_path::reverse ()
{
  std::reverse (m_elements.begin (), m_elements.end ());
}

} // namespace ana

#endif /* #if ENABLE_ANALYZER */
