/* Fixing up location_t values of supernodes.
   Copyright (C) 2025-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/>.  */

#define INCLUDE_DEQUE
#include "analyzer/common.h"

#include "timevar.h"

#include "analyzer/supergraph.h"
#include "analyzer/analyzer-logging.h"
#include "analyzer/supergraph-manipulation.h"

#if ENABLE_ANALYZER

namespace ana {

namespace {

class location_fixer
{
public:
  location_fixer (supergraph &sg,
		  ana::logger *logger)
  : m_logger (logger),
    m_stats ()
  {
    for (auto node : sg.m_nodes)
      if (node->m_loc == UNKNOWN_LOCATION)
	m_worklist.ensure_node_queued (node, logger);
  }

  /* High level ops.  */

  supernode *
  pop_next_node_in_queue ()
  {
    return m_worklist.pop ();
  }

  void
  consider_node (supernode *node)
  {
    m_stats.m_num_iterations++;

    log_nesting_level sentinel (m_logger, "considering SN: %i", node->m_id);

    /* Already have a location for this node.  */
    if (useful_location_p (node->m_loc))
      return;

    /* For snodes with UNKNOWN_LOCATION with a single in-edge, try to
       propagate the location from it.  */
    if (node->m_preds.length () == 1)
      {
	auto in_edge = node->m_preds[0];
	if (useful_location_p (in_edge->m_src->m_loc))
	  {
	    node->m_loc = in_edge->m_src->m_loc;
	    m_stats.m_num_copies++;
	    if (m_logger)
	      m_logger->log ("copying location 0x%lx from SN %i to SN %i",
			     node->m_loc,
			     in_edge->m_src->m_id, node->m_id);
	    for (auto out_edge : node->m_succs)
	      m_worklist.ensure_node_queued (out_edge->m_dest, m_logger);
	  }
      }
  }

private:
  supergraph_manipulation::worklist m_worklist;
  ana::logger *m_logger;
  struct stats
  {
    stats () = default;

    void log (ana::logger &logger)
    {
      logger.log ("# iterations taken: " HOST_SIZE_T_PRINT_UNSIGNED,
		  (fmt_size_t)m_num_iterations);
      logger.log ("# locations copied: " HOST_SIZE_T_PRINT_UNSIGNED,
		  (fmt_size_t)m_num_copies);
    }

    size_t m_num_iterations;
    size_t m_num_copies;

  } m_stats;
};

} // anonymous namespace

void
supergraph::fixup_locations (logger *logger)
{
  auto_timevar tv (TV_ANALYZER_SUPERGRAPH_FIXUP_LOCATIONS);
  LOG_SCOPE (logger);

  location_fixer opt (*this, logger);
  while (supernode *node = opt.pop_next_node_in_queue ())
    opt.consider_node (node);
}

} // namespace ana

#endif /* #if ENABLE_ANALYZER */
