// Implementation of basic-block-related functions for RTL SSA      -*- C++ -*-
// Copyright (C) 2020-2023 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/>.

#define INCLUDE_ALGORITHM
#define INCLUDE_FUNCTIONAL
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "rtl.h"
#include "df.h"
#include "rtl-ssa.h"
#include "rtl-ssa/internals.h"
#include "rtl-ssa/internals.inl"
#include "cfganal.h"
#include "cfgrtl.h"
#include "predict.h"
#include "domwalk.h"

using namespace rtl_ssa;

// Prepare to build information for a function in which all register numbers
// are less than NUM_REGS and all basic block indices are less than
// NUM_BB_INDICES
function_info::build_info::build_info (unsigned int num_regs,
				       unsigned int num_bb_indices)
  : current_bb (nullptr),
    current_ebb (nullptr),
    last_access (num_regs + 1),
    ebb_live_in_for_debug (nullptr),
    potential_phi_regs (num_regs),
    bb_phis (num_bb_indices),
    bb_mem_live_out (num_bb_indices),
    bb_to_rpo (num_bb_indices)
{
  last_access.safe_grow_cleared (num_regs + 1);

  bitmap_clear (potential_phi_regs);

  // These arrays shouldn't need to be initialized, since we'll always
  // write to an entry before reading from it.  But poison the contents
  // when checking, just to make sure we don't accidentally use an
  // uninitialized value.
  bb_phis.quick_grow (num_bb_indices);
  bb_mem_live_out.quick_grow (num_bb_indices);
  bb_to_rpo.quick_grow (num_bb_indices);
  if (flag_checking)
    {
      // Can't do this for bb_phis because it has a constructor.
      memset (bb_mem_live_out.address (), 0xaf,
	      num_bb_indices * sizeof (bb_mem_live_out[0]));
      memset (bb_to_rpo.address (), 0xaf,
	      num_bb_indices * sizeof (bb_to_rpo[0]));
    }

  // Start off with an empty set of phi nodes for each block.
  for (bb_phi_info &info : bb_phis)
    bitmap_initialize (&info.regs, &bitmap_default_obstack);
}

function_info::build_info::~build_info ()
{
  for (bb_phi_info &info : bb_phis)
    bitmap_release (&info.regs);
}

// A dom_walker for populating the basic blocks.
class function_info::bb_walker : public dom_walker
{
public:
  bb_walker (function_info *, build_info &);
  edge before_dom_children (basic_block) final override;
  void after_dom_children (basic_block) final override;

private:
  // Information about the function we're building.
  function_info *m_function;
  build_info &m_bi;

  // We should treat the exit block as being the last child of this one.
  // See the comment in the constructor for more information.
  basic_block m_exit_block_dominator;
};

// Prepare to walk the blocks in FUNCTION using BI.
function_info::bb_walker::bb_walker (function_info *function, build_info &bi)
  : dom_walker (CDI_DOMINATORS, ALL_BLOCKS, bi.bb_to_rpo.address ()),
    m_function (function),
    m_bi (bi),
    m_exit_block_dominator (nullptr)
{
  // ??? There is no dominance information associated with the exit block,
  // so work out its immediate dominator using predecessor blocks.  We then
  // walk the exit block just before popping its immediate dominator.
  edge e;
  edge_iterator ei;
  FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (m_function->m_fn)->preds)
    if (m_exit_block_dominator)
      m_exit_block_dominator
	= nearest_common_dominator (CDI_DOMINATORS,
				    m_exit_block_dominator, e->src);
    else
      m_exit_block_dominator = e->src;

  // If the exit block is unreachable, process it last.
  if (!m_exit_block_dominator)
    m_exit_block_dominator = ENTRY_BLOCK_PTR_FOR_FN (m_function->m_fn);
}

edge
function_info::bb_walker::before_dom_children (basic_block bb)
{
  m_function->start_block (m_bi, m_function->bb (bb));
  return nullptr;
}

void
function_info::bb_walker::after_dom_children (basic_block bb)
{
  // See the comment in the constructor for details.
  if (bb == m_exit_block_dominator)
    {
      before_dom_children (EXIT_BLOCK_PTR_FOR_FN (m_function->m_fn));
      after_dom_children (EXIT_BLOCK_PTR_FOR_FN (m_function->m_fn));
    }
  m_function->end_block (m_bi, m_function->bb (bb));
}

// See the comment above the declaration.
void
bb_info::print_identifier (pretty_printer *pp) const
{
  char tmp[3 * sizeof (index ()) + 3];
  snprintf (tmp, sizeof (tmp), "bb%d", index ());
  pp_string (pp, tmp);
  if (ebb_info *ebb = this->ebb ())
    {
      pp_space (pp);
      pp_left_bracket (pp);
      ebb->print_identifier (pp);
      pp_right_bracket (pp);
    }
}

// See the comment above the declaration.
void
bb_info::print_full (pretty_printer *pp) const
{
  pp_string (pp, "basic block ");
  print_identifier (pp);
  pp_colon (pp);

  auto print_insn = [pp](const char *header, const insn_info *insn)
    {
      pp_newline_and_indent (pp, 2);
      pp_string (pp, header);
      pp_newline_and_indent (pp, 2);
      if (insn)
	pp_insn (pp, insn);
      else
	pp_string (pp, "<uninitialized>");
      pp_indentation (pp) -= 4;
    };

  print_insn ("head:", head_insn ());

  pp_newline (pp);
  pp_newline_and_indent (pp, 2);
  pp_string (pp, "contents:");
  if (!head_insn ())
    {
      pp_newline_and_indent (pp, 2);
      pp_string (pp, "<uninitialized>");
      pp_indentation (pp) -= 2;
    }
  else if (auto insns = real_insns ())
    {
      bool is_first = true;
      for (const insn_info *insn : insns)
	{
	  if (is_first)
	    is_first = false;
	  else
	    pp_newline (pp);
	  pp_newline_and_indent (pp, 2);
	  pp_insn (pp, insn);
	  pp_indentation (pp) -= 2;
	}
    }
  else
    {
      pp_newline_and_indent (pp, 2);
      pp_string (pp, "none");
      pp_indentation (pp) -= 2;
    }
  pp_indentation (pp) -= 2;

  pp_newline (pp);
  print_insn ("end:", end_insn ());
}

// See the comment above the declaration.
void
ebb_call_clobbers_info::print_summary (pretty_printer *pp) const
{
  pp_string (pp, "call clobbers for ABI ");
  if (m_abi)
    pp_decimal_int (pp, m_abi->id ());
  else
    pp_string (pp, "<null>");
}

// See the comment above the declaration.
void
ebb_call_clobbers_info::print_full (pretty_printer *pp) const
{
  print_summary (pp);
  pp_colon (pp);
  pp_newline_and_indent (pp, 2);
  auto print_node = [](pretty_printer *pp,
		       const insn_call_clobbers_note *note)
    {
      if (insn_info *insn = note->insn ())
	insn->print_identifier_and_location (pp);
      else
	pp_string (pp, "<null>");
    };
  print (pp, root (), print_node);
  pp_indentation (pp) -= 2;
}

// See the comment above the declaration.
void
ebb_info::print_identifier (pretty_printer *pp) const
{
  // first_bb is populated by the constructor and so should always
  // be nonnull.
  auto index = first_bb ()->index ();
  char tmp[3 * sizeof (index) + 4];
  snprintf (tmp, sizeof (tmp), "ebb%d", index);
  pp_string (pp, tmp);
}

// See the comment above the declaration.
void
ebb_info::print_full (pretty_printer *pp) const
{
  pp_string (pp, "extended basic block ");
  print_identifier (pp);
  pp_colon (pp);

  pp_newline_and_indent (pp, 2);
  if (insn_info *phi_insn = this->phi_insn ())
    {
      phi_insn->print_identifier_and_location (pp);
      pp_colon (pp);
      if (auto phis = this->phis ())
	{
	  bool is_first = true;
	  for (const phi_info *phi : phis)
	    {
	      if (is_first)
		is_first = false;
	      else
		pp_newline (pp);
	      pp_newline_and_indent (pp, 2);
	      pp_access (pp, phi, PP_ACCESS_SETTER);
	      pp_indentation (pp) -= 2;
	    }
	}
      else
	{
	  pp_newline_and_indent (pp, 2);
	  pp_string (pp, "no phi nodes");
	  pp_indentation (pp) -= 2;
	}
    }
  else
    pp_string (pp, "no phi insn");
  pp_indentation (pp) -= 2;

  for (const bb_info *bb : bbs ())
    {
      pp_newline (pp);
      pp_newline_and_indent (pp, 2);
      pp_bb (pp, bb);
      pp_indentation (pp) -= 2;
    }

  for (ebb_call_clobbers_info *ecc : call_clobbers ())
    {
      pp_newline (pp);
      pp_newline_and_indent (pp, 2);
      pp_ebb_call_clobbers (pp, ecc);
      pp_indentation (pp) -= 2;
    }
}

// Add a dummy use to mark that DEF is live out of BB's EBB at the end of BB.
void
function_info::add_live_out_use (bb_info *bb, set_info *def)
{
  // There is nothing to do if DEF is an artificial definition at the end
  // of BB.  In that case the definitino is rooted at the end of the block
  // and we wouldn't gain anything by inserting a use immediately after it.
  // If we did want to insert a use, we'd need to associate it with a new
  // instruction that comes after bb->end_insn ().
  if (def->insn () == bb->end_insn ())
    return;

  // If the end of the block already has an artificial use, that use
  // acts to make DEF live at the appropriate point.
  use_info *use = def->last_nondebug_insn_use ();
  if (use && use->insn () == bb->end_insn ())
    return;

  // Currently there is no need to maintain a backward link from the end
  // instruction to the list of live-out uses.  Such a list would be
  // expensive to update if it was represented using the usual insn_info
  // access arrays.
  use = allocate<use_info> (bb->end_insn (), def->resource (), def);
  use->set_is_live_out_use (true);
  add_use (use);
}

// Return true if all nondebug uses of DEF are live-out uses.
static bool
all_uses_are_live_out_uses (set_info *def)
{
  for (use_info *use : def->all_uses ())
    if (!use->is_in_debug_insn () && !use->is_live_out_use ())
      return false;
  return true;
}

// SET, if nonnull, is a definition of something that is live out from BB.
// Return the live-out value itself.
set_info *
function_info::live_out_value (bb_info *bb, set_info *set)
{
  // Degenerate phis only exist to provide a definition for uses in the
  // same EBB.  The live-out value is the same as the live-in value.
  if (auto *phi = safe_dyn_cast<phi_info *> (set))
    if (phi->is_degenerate ())
      {
	set = phi->input_value (0);

	// Remove the phi if it turned out to be useless.  This is
	// mainly useful for memory, because we don't know ahead of time
	// whether a block will use memory or not.
	if (bb == bb->ebb ()->last_bb () && all_uses_are_live_out_uses (phi))
	  replace_phi (phi, set);
      }

  return set;
}

// Add PHI to EBB and enter it into the function's hash table.
void
function_info::append_phi (ebb_info *ebb, phi_info *phi)
{
  phi_info *first_phi = ebb->first_phi ();
  if (first_phi)
    first_phi->set_prev_phi (phi);
  phi->set_next_phi (first_phi);
  ebb->set_first_phi (phi);
  add_def (phi);
}

// Remove PHI from its current position in the SSA graph.
void
function_info::remove_phi (phi_info *phi)
{
  phi_info *next = phi->next_phi ();
  phi_info *prev = phi->prev_phi ();

  if (next)
    next->set_prev_phi (prev);

  if (prev)
    prev->set_next_phi (next);
  else
    phi->ebb ()->set_first_phi (next);

  remove_def (phi);
  phi->clear_phi_links ();
}

// Remove PHI from the SSA graph and free its memory.
void
function_info::delete_phi (phi_info *phi)
{
  gcc_assert (!phi->has_any_uses ());

  // Remove the inputs to the phi.
  for (use_info *input : phi->inputs ())
    remove_use (input);

  remove_phi (phi);

  phi->set_next_phi (m_free_phis);
  m_free_phis = phi;
}

// If possible, remove PHI and replace all uses with NEW_VALUE.
void
function_info::replace_phi (phi_info *phi, set_info *new_value)
{
  auto update_use = [&](use_info *use)
    {
      remove_use (use);
      use->set_def (new_value);
      add_use (use);
    };

  if (new_value)
    for (use_info *use : phi->nondebug_insn_uses ())
      if (!use->is_live_out_use ())
	{
	  // We need to keep the phi around for its local uses.
	  // Turn it into a degenerate phi, if it isn't already.
	  use_info *use = phi->input_use (0);
	  if (use->def () != new_value)
	    update_use (use);

	  if (phi->is_degenerate ())
	    return;

	  phi->make_degenerate (use);

	  // Redirect all phi users to NEW_VALUE.
	  while (use_info *phi_use = phi->last_phi_use ())
	    update_use (phi_use);

	  return;
	}

  // Replace the uses.  We can discard uses that only existed for the
  // sake of marking live-out values, since the resource is now transparent
  // in the phi's EBB.
  while (use_info *use = phi->last_use ())
    if (use->is_live_out_use ())
      remove_use (use);
    else
      update_use (use);

  delete_phi (phi);
}

// Create and return a phi node for EBB.  RESOURCE is the resource that
// the phi node sets (and thus that all the inputs set too).  NUM_INPUTS
// is the number of inputs, which is 1 for a degenerate phi.  INPUTS[I]
// is a set_info that gives the value of input I, or null if the value
// is either unknown or uninitialized.  If NUM_INPUTS > 1, this array
// is allocated on the main obstack and can be reused for the use array.
//
// Add the created phi node to its basic block and enter it into the
// function's hash table.
phi_info *
function_info::create_phi (ebb_info *ebb, resource_info resource,
			   access_info **inputs, unsigned int num_inputs)
{
  phi_info *phi = m_free_phis;
  if (phi)
    {
      m_free_phis = phi->next_phi ();
      *phi = phi_info (ebb->phi_insn (), resource, phi->uid ());
    }
  else
    {
      phi = allocate<phi_info> (ebb->phi_insn (), resource, m_next_phi_uid);
      m_next_phi_uid += 1;
    }

  // Convert the array of set_infos into an array of use_infos.  Also work
  // out what mode the phi should have.
  machine_mode new_mode = resource.mode;
  for (unsigned int i = 0; i < num_inputs; ++i)
    {
      auto *input = safe_as_a<set_info *> (inputs[i]);
      auto *use = allocate<use_info> (phi, resource, input);
      add_use (use);
      inputs[i] = use;
      if (input)
	new_mode = combine_modes (new_mode, input->mode ());
    }

  phi->set_inputs (use_array (inputs, num_inputs));
  phi->set_mode (new_mode);

  append_phi (ebb, phi);

  return phi;
}

// Create and return a degenerate phi for EBB whose input comes from DEF.
// This is used in cases where DEF is known to be available on entry to
// EBB but was not previously used within it.  If DEF is for a register,
// there are two cases:
//
// (1) DEF was already live on entry to EBB but was previously transparent
//     within it.
//
// (2) DEF was not previously live on entry to EBB and is being made live
//     by this update.
//
// At the moment, this function only handles the case in which EBB has a
// single predecessor block and DEF is defined in that block's EBB.
phi_info *
function_info::create_degenerate_phi (ebb_info *ebb, set_info *def)
{
  access_info *input = def;
  phi_info *phi = create_phi (ebb, def->resource (), &input, 1);
  if (def->is_reg ())
    {
      unsigned int regno = def->regno ();

      // Find the single predecessor mentioned above.
      basic_block pred_cfg_bb = single_pred (ebb->first_bb ()->cfg_bb ());
      bb_info *pred_bb = this->bb (pred_cfg_bb);

      if (!bitmap_set_bit (DF_LR_IN (ebb->first_bb ()->cfg_bb ()), regno))
	{
	  // The register was not previously live on entry to EBB and
	  // might not have been live on exit from PRED_BB either.
	  if (bitmap_set_bit (DF_LR_OUT (pred_cfg_bb), regno))
	    add_live_out_use (pred_bb, def);
	}
      else
	{
	  // The register was previously live in to EBB.  Add live-out uses
	  // at the appropriate points.
	  insn_info *next_insn = nullptr;
	  if (def_info *next_def = phi->next_def ())
	    next_insn = next_def->insn ();
	  for (bb_info *bb : ebb->bbs ())
	    {
	      if ((next_insn && *next_insn <= *bb->end_insn ())
		  || !bitmap_bit_p (DF_LR_OUT (bb->cfg_bb ()), regno))
		break;
	      add_live_out_use (bb, def);
	    }
	}
    }
  return phi;
}

// Create a bb_info for CFG_BB, given that no such structure currently exists.
bb_info *
function_info::create_bb_info (basic_block cfg_bb)
{
  bb_info *bb = allocate<bb_info> (cfg_bb);
  gcc_checking_assert (!m_bbs[cfg_bb->index]);
  m_bbs[cfg_bb->index] = bb;
  return bb;
}

// Add BB to the end of the list of blocks.
void
function_info::append_bb (bb_info *bb)
{
  if (m_last_bb)
    m_last_bb->set_next_bb (bb);
  else
    m_first_bb = bb;
  bb->set_prev_bb (m_last_bb);
  m_last_bb = bb;
}

// Calculate BI.potential_phi_regs and BI.potential_phi_regs_for_debug.
void
function_info::calculate_potential_phi_regs (build_info &bi)
{
  auto *lr_info = DF_LR_BB_INFO (ENTRY_BLOCK_PTR_FOR_FN (m_fn));
  bool is_debug = MAY_HAVE_DEBUG_INSNS;
  for (unsigned int regno = 0; regno < m_num_regs; ++regno)
    if (regno >= DF_REG_SIZE (DF)
	// Exclude registers that have a single definition that dominates
	// all uses.  If the definition does not dominate all uses,
	// the register will be exposed upwards to the entry block but
	// will not be defined by the entry block.
	|| DF_REG_DEF_COUNT (regno) > 1
	|| (!bitmap_bit_p (&lr_info->def, regno)
	    && bitmap_bit_p (&lr_info->out, regno)))
      {
	bitmap_set_bit (bi.potential_phi_regs, regno);
	if (is_debug)
	  bitmap_set_bit (bi.potential_phi_regs_for_debug, regno);
      }
}

// Called while building SSA form using BI.  Decide where phi nodes
// should be placed for each register and initialize BI.bb_phis accordingly.
void
function_info::place_phis (build_info &bi)
{
  unsigned int num_bb_indices = last_basic_block_for_fn (m_fn);

  // Calculate dominance frontiers.
  auto_vec<bitmap_head> frontiers;
  frontiers.safe_grow (num_bb_indices);
  for (unsigned int i = 0; i < num_bb_indices; ++i)
    bitmap_initialize (&frontiers[i], &bitmap_default_obstack);
  compute_dominance_frontiers (frontiers.address ());

  // In extreme cases, the number of live-in registers can be much
  // greater than the number of phi nodes needed in a block (see PR98863).
  // Try to reduce the number of operations involving live-in sets by using
  // PENDING as a staging area: registers in PENDING need phi nodes if
  // they are live on entry to the corresponding block, but do not need
  // phi nodes otherwise.
  auto_vec<bitmap_head> unfiltered;
  unfiltered.safe_grow (num_bb_indices);
  for (unsigned int i = 0; i < num_bb_indices; ++i)
    bitmap_initialize (&unfiltered[i], &bitmap_default_obstack);

  // If block B1 defines R and if B2 is in the dominance frontier of B1,
  // queue a possible phi node for R in B2.
  auto_bitmap worklist;
  for (unsigned int b1 = 0; b1 < num_bb_indices; ++b1)
    {
      // Only access DF information for blocks that are known to exist.
      if (bitmap_empty_p (&frontiers[b1]))
	continue;

      bitmap b1_def = &DF_LR_BB_INFO (BASIC_BLOCK_FOR_FN (m_fn, b1))->def;
      bitmap_iterator bmi;
      unsigned int b2;
      EXECUTE_IF_SET_IN_BITMAP (&frontiers[b1], 0, b2, bmi)
	if (bitmap_ior_into (&unfiltered[b2], b1_def)
	    && !bitmap_empty_p (&frontiers[b2]))
	  // Propagate the (potential) new phi node definitions in B2.
	  bitmap_set_bit (worklist, b2);
    }

  while (!bitmap_empty_p (worklist))
    {
      unsigned int b1 = bitmap_first_set_bit (worklist);
      bitmap_clear_bit (worklist, b1);

      // Restrict the phi nodes to registers that are live on entry to
      // the block.
      bitmap b1_in = DF_LR_IN (BASIC_BLOCK_FOR_FN (m_fn, b1));
      bitmap b1_phis = &bi.bb_phis[b1].regs;
      if (!bitmap_ior_and_into (b1_phis, &unfiltered[b1], b1_in))
	continue;

      // If block B1 has a phi node for R and if B2 is in the dominance
      // frontier of B1, queue a possible phi node for R in B2.
      bitmap_iterator bmi;
      unsigned int b2;
      EXECUTE_IF_SET_IN_BITMAP (&frontiers[b1], 0, b2, bmi)
	if (bitmap_ior_into (&unfiltered[b2], b1_phis)
	    && !bitmap_empty_p (&frontiers[b2]))
	  bitmap_set_bit (worklist, b2);
    }

  basic_block cfg_bb;
  FOR_ALL_BB_FN (cfg_bb, m_fn)
    {
      // Calculate the set of phi nodes for blocks that don't have any
      // dominance frontiers.  We only need to do this once per block.
      unsigned int i = cfg_bb->index;
      bb_phi_info &phis = bi.bb_phis[i];
      if (bitmap_empty_p (&frontiers[i]))
	bitmap_and (&phis.regs, &unfiltered[i], DF_LR_IN (cfg_bb));

      // Create an array that contains all phi inputs for this block.
      // See the comment above the member variables for more information.
      phis.num_phis = bitmap_count_bits (&phis.regs);
      phis.num_preds = EDGE_COUNT (cfg_bb->preds);
      unsigned int num_inputs = phis.num_phis * phis.num_preds;
      if (num_inputs != 0)
	{
	  phis.inputs = XOBNEWVEC (&m_temp_obstack, set_info *, num_inputs);
	  memset (phis.inputs, 0, num_inputs * sizeof (phis.inputs[0]));
	}
    }

  // Free the temporary bitmaps.
  for (unsigned int i = 0; i < num_bb_indices; ++i)
    {
      bitmap_release (&frontiers[i]);
      bitmap_release (&unfiltered[i]);
    }
}

// Called while building SSA form using BI, with BI.current_bb being
// the entry block.
//
// Create the entry block instructions and their definitions.  The only
// useful instruction is the end instruction, which carries definitions
// for the values that are live on entry to the function.  However, it
// seems simpler to create a head instruction too, rather than force all
// users of the block information to treat the entry block as a special case.
void
function_info::add_entry_block_defs (build_info &bi)
{
  bb_info *bb = bi.current_bb;
  basic_block cfg_bb = bi.current_bb->cfg_bb ();
  auto *lr_info = DF_LR_BB_INFO (cfg_bb);

  bb->set_head_insn (append_artificial_insn (bb));
  insn_info *insn = append_artificial_insn (bb);
  bb->set_end_insn (insn);

  start_insn_accesses ();

  // Using LR to derive the liveness information means that we create an
  // entry block definition for upwards exposed registers.  These registers
  // are sometimes genuinely uninitialized.  However, some targets also
  // create a pseudo PIC base register and only initialize it later.
  // Handling that case correctly seems more important than optimizing
  // uninitialized uses.
  unsigned int regno;
  bitmap_iterator in_bi;
  EXECUTE_IF_SET_IN_BITMAP (&lr_info->out, 0, regno, in_bi)
    {
      auto *set = allocate<set_info> (insn, full_register (regno));
      append_def (set);
      m_temp_defs.safe_push (set);
      bi.record_reg_def (set);
    }

  // Create a definition that reflects the state of memory on entry to
  // the function.
  auto *set = allocate<set_info> (insn, memory);
  append_def (set);
  m_temp_defs.safe_push (set);
  bi.record_mem_def (set);

  finish_insn_accesses (insn);
}

// Lazily calculate the value of BI.ebb_live_in_for_debug for BI.current_ebb.
void
function_info::calculate_ebb_live_in_for_debug (build_info &bi)
{
  gcc_checking_assert (bitmap_empty_p (bi.tmp_ebb_live_in_for_debug));
  bi.ebb_live_in_for_debug = bi.tmp_ebb_live_in_for_debug;
  bitmap_and (bi.ebb_live_in_for_debug, bi.potential_phi_regs_for_debug,
	      DF_LR_IN (bi.current_ebb->first_bb ()->cfg_bb ()));
  bitmap_tree_view (bi.ebb_live_in_for_debug);
}

// Called while building SSA form using BI.  Create phi nodes for the
// current EBB.
void
function_info::add_phi_nodes (build_info &bi)
{
  ebb_info *ebb = bi.current_ebb;
  basic_block cfg_bb = ebb->first_bb ()->cfg_bb ();

  // Create the register phis for this EBB.
  bb_phi_info &phis = bi.bb_phis[cfg_bb->index];
  unsigned int num_preds = phis.num_preds;
  unsigned int regno;
  bitmap_iterator in_bi;
  EXECUTE_IF_SET_IN_BITMAP (&phis.regs, 0, regno, in_bi)
    {
      gcc_checking_assert (bitmap_bit_p (bi.potential_phi_regs, regno));

      // Create an array of phi inputs, to be filled in later.
      auto *inputs = XOBNEWVEC (&m_obstack, access_info *, num_preds);
      memset (inputs, 0, sizeof (access_info *) * num_preds);

      // Later code works out the correct mode of the phi.  Use BLKmode
      // as a placeholder for now.
      phi_info *phi = create_phi (ebb, { E_BLKmode, regno },
				  inputs, num_preds);
      bi.record_reg_def (phi);
    }

  bitmap_copy (bi.ebb_def_regs, &phis.regs);

  // Collect the live-in memory definitions and record whether they're
  // all the same.
  m_temp_defs.reserve (num_preds);
  set_info *mem_value = nullptr;
  bool mem_phi_is_degenerate = true;
  edge e;
  edge_iterator ei;
  FOR_EACH_EDGE (e, ei, cfg_bb->preds)
    {
      bb_info *pred_bb = this->bb (e->src);
      if (pred_bb && pred_bb->head_insn ())
	{
	  mem_value = bi.bb_mem_live_out[pred_bb->index ()];
	  m_temp_defs.quick_push (mem_value);
	  if (mem_value != m_temp_defs[0])
	    mem_phi_is_degenerate = false;
	}
      else
	{
	  m_temp_defs.quick_push (nullptr);
	  mem_phi_is_degenerate = false;
	}
    }

  // Create a phi for memory, on the assumption that something in the
  // EBB will need it.
  if (mem_phi_is_degenerate)
    {
      access_info *input[] = { mem_value };
      mem_value = create_phi (ebb, memory, input, 1);
    }
  else
    {
      obstack_grow (&m_obstack, m_temp_defs.address (),
		    num_preds * sizeof (access_info *));
      auto *inputs = static_cast<access_info **> (obstack_finish (&m_obstack));
      mem_value = create_phi (ebb, memory, inputs, num_preds);
    }
  bi.record_mem_def (mem_value);
  m_temp_defs.truncate (0);
}

// Called while building SSA form using BI.
//
// If FLAGS is DF_REF_AT_TOP, create the head insn for BI.current_bb
// and populate its uses and definitions.  If FLAGS is 0, do the same
// for the end insn.
void
function_info::add_artificial_accesses (build_info &bi, df_ref_flags flags)
{
  bb_info *bb = bi.current_bb;
  basic_block cfg_bb = bb->cfg_bb ();
  auto *lr_info = DF_LR_BB_INFO (cfg_bb);
  df_ref ref;

  insn_info *insn;
  if (flags == DF_REF_AT_TOP)
    {
      if (cfg_bb->index == EXIT_BLOCK)
	insn = append_artificial_insn (bb);
      else
	insn = append_artificial_insn (bb, bb_note (cfg_bb));
      bb->set_head_insn (insn);
    }
  else
    {
      insn = append_artificial_insn (bb);
      bb->set_end_insn (insn);
    }

  start_insn_accesses ();

  FOR_EACH_ARTIFICIAL_USE (ref, cfg_bb->index)
    if ((DF_REF_FLAGS (ref) & DF_REF_AT_TOP) == flags)
      {
	unsigned int regno = DF_REF_REGNO (ref);
	machine_mode mode = GET_MODE (DF_REF_REAL_REG (ref));

	// A definition must be available.
	gcc_checking_assert (bitmap_bit_p (&lr_info->in, regno)
			     || (flags != DF_REF_AT_TOP
				 && bitmap_bit_p (&lr_info->def, regno)));
	m_temp_uses.safe_push (create_reg_use (bi, insn, { mode, regno }));
      }

  // Track the return value of memory by adding an artificial use of
  // memory at the end of the exit block.
  if (flags == 0 && cfg_bb->index == EXIT_BLOCK)
    {
      auto *use = allocate<use_info> (insn, memory, bi.current_mem_value ());
      add_use (use);
      m_temp_uses.safe_push (use);
    }

  FOR_EACH_ARTIFICIAL_DEF (ref, cfg_bb->index)
    if ((DF_REF_FLAGS (ref) & DF_REF_AT_TOP) == flags)
      {
	unsigned int regno = DF_REF_REGNO (ref);
	machine_mode mode = GET_MODE (DF_REF_REAL_REG (ref));
	resource_info resource { mode, regno };

	// We rely on the def set being correct.
	gcc_checking_assert (bitmap_bit_p (&lr_info->def, regno));

	// If the value isn't used later in the block and isn't live
	// on exit, we could instead represent the definition as a
	// clobber_info.  However, that case should be relatively
	// rare and set_info is any case more compact than clobber_info.
	set_info *def = allocate<set_info> (insn, resource);
	append_def (def);
	m_temp_defs.safe_push (def);
	bi.record_reg_def (def);
      }

  // Model the effect of a memory clobber on an incoming edge by adding
  // a fake definition of memory at the start of the block.  We don't need
  // to add a use of the phi node because memory is implicitly always live.
  if (flags == DF_REF_AT_TOP && has_abnormal_call_or_eh_pred_edge_p (cfg_bb))
    {
      set_info *def = allocate<set_info> (insn, memory);
      append_def (def);
      m_temp_defs.safe_push (def);
      bi.record_mem_def (def);
    }

  finish_insn_accesses (insn);
}

// Called while building SSA form using BI.  Create insn_infos for all
// relevant instructions in BI.current_bb.
void
function_info::add_block_contents (build_info &bi)
{
  basic_block cfg_bb = bi.current_bb->cfg_bb ();
  rtx_insn *insn;
  FOR_BB_INSNS (cfg_bb, insn)
    if (INSN_P (insn))
      add_insn_to_block (bi, insn);
}

// Called while building SSA form using BI.  Record live-out register values
// in the phi inputs of successor blocks and create live-out uses where
// appropriate.  Record the live-out memory value in BI.bb_mem_live_out.
void
function_info::record_block_live_out (build_info &bi)
{
  bb_info *bb = bi.current_bb;
  ebb_info *ebb = bi.current_ebb;
  basic_block cfg_bb = bb->cfg_bb ();

  // Record the live-out register values in the phi inputs of
  // successor blocks.
  edge e;
  edge_iterator ei;
  FOR_EACH_EDGE (e, ei, cfg_bb->succs)
    {
      bb_phi_info &phis = bi.bb_phis[e->dest->index];
      unsigned int input_i = e->dest_idx * phis.num_phis;
      unsigned int regno;
      bitmap_iterator out_bi;
      EXECUTE_IF_SET_IN_BITMAP (&phis.regs, 0, regno, out_bi)
	{
	  phis.inputs[input_i]
	    = live_out_value (bb, bi.current_reg_value (regno));
	  input_i += 1;
	}
    }

  // Add the set of registers that were defined in this BB to the set
  // of potentially-live registers defined in the EBB.
  bitmap_ior_into (bi.ebb_def_regs, &DF_LR_BB_INFO (cfg_bb)->def);

  // Iterate through the registers in LIVE_OUT and see whether we need
  // to add a live-out use for them.
  auto record_live_out_regs = [&](bitmap live_out)
    {
      unsigned int regno;
      bitmap_iterator out_bi;
      EXECUTE_IF_AND_IN_BITMAP (bi.ebb_def_regs, live_out, 0, regno, out_bi)
	{
	  set_info *value = live_out_value (bb, bi.current_reg_value (regno));
	  if (value && value->ebb () == ebb)
	    add_live_out_use (bb, value);
	}
    };

  if (bb == ebb->last_bb ())
    // All live-out registers might need live-out uses.
    record_live_out_regs (DF_LR_OUT (cfg_bb));
  else
    // Registers might need live-out uses if they are live on entry
    // to a successor block in a different EBB.
    FOR_EACH_EDGE (e, ei, cfg_bb->succs)
      {
	bb_info *dest_bb = this->bb (e->dest);
	if (dest_bb->ebb () != ebb || dest_bb == ebb->first_bb ())
	  record_live_out_regs (DF_LR_IN (e->dest));
      }

  // Record the live-out memory value.
  bi.bb_mem_live_out[cfg_bb->index]
    = live_out_value (bb, bi.current_mem_value ());
}

// Add BB and its contents to the SSA information.
void
function_info::start_block (build_info &bi, bb_info *bb)
{
  ebb_info *ebb = bb->ebb ();

  // We (need to) add all blocks from one EBB before moving on to the next.
  bi.current_bb = bb;
  if (bb == ebb->first_bb ())
    bi.current_ebb = ebb;
  else
    gcc_assert (bi.current_ebb == ebb);

  // Record the start of this block's definitions in the definitions stack.
  bi.old_def_stack_limit.safe_push (bi.def_stack.length ());

  // Add the block itself.
  append_bb (bb);

  // If the block starts an EBB, create the phi insn.  This insn should exist
  // for all EBBs, even if they don't (yet) need phis.
  if (bb == ebb->first_bb ())
    ebb->set_phi_insn (append_artificial_insn (bb));

  if (bb->index () == ENTRY_BLOCK)
    {
      add_entry_block_defs (bi);
      record_block_live_out (bi);
      return;
    }

  if (EDGE_COUNT (bb->cfg_bb ()->preds) == 0)
    {
      // Leave unreachable blocks empty, since there is no useful
      // liveness information for them, and anything they do will
      // be wasted work.  In a cleaned-up cfg, the only unreachable
      // block we should see is the exit block of a noreturn function.
      bb->set_head_insn (append_artificial_insn (bb));
      bb->set_end_insn (append_artificial_insn (bb));
      return;
    }

  // If the block starts an EBB, create the phi nodes.
  if (bb == ebb->first_bb ())
    add_phi_nodes (bi);

  // Process the contents of the block.
  add_artificial_accesses (bi, DF_REF_AT_TOP);
  if (bb->index () != EXIT_BLOCK)
    add_block_contents (bi);
  add_artificial_accesses (bi, df_ref_flags ());
  record_block_live_out (bi);

  // If we needed to calculate a live-in set for debug purposes,
  // reset it to null at the end of the EBB.  Convert the underlying
  // bitmap to an empty list view, ready for the next calculation.
  if (bi.ebb_live_in_for_debug && bb == ebb->last_bb ())
    {
      bitmap_clear (bi.tmp_ebb_live_in_for_debug);
      bitmap_list_view (bi.tmp_ebb_live_in_for_debug);
      bi.ebb_live_in_for_debug = nullptr;
    }
}

// Finish adding BB and the blocks that it dominates to the SSA information.
void
function_info::end_block (build_info &bi, bb_info *bb)
{
  // Restore the register last_access information to the state it was
  // in before we started processing BB.
  unsigned int old_limit = bi.old_def_stack_limit.pop ();
  while (bi.def_stack.length () > old_limit)
    {
      // We pushed a definition in BB if it was the first dominating
      // definition (and so the previous entry was null).  In other
      // cases we pushed the previous dominating definition.
      def_info *def = bi.def_stack.pop ();
      unsigned int regno = def->regno ();
      if (def->bb () == bb)
	def = nullptr;
      bi.last_access[regno + 1] = def;
    }
}

// Finish setting up the phi nodes for each block, now that we've added
// the contents of all blocks.
void
function_info::populate_phi_inputs (build_info &bi)
{
  auto_vec<phi_info *, 32> sorted_phis;
  for (ebb_info *ebb : ebbs ())
    {
      if (!ebb->first_phi ())
	continue;

      // Get a sorted array of EBB's phi nodes.
      basic_block cfg_bb = ebb->first_bb ()->cfg_bb ();
      bb_phi_info &phis = bi.bb_phis[cfg_bb->index];
      sorted_phis.truncate (0);
      for (phi_info *phi : ebb->phis ())
	sorted_phis.safe_push (phi);
      std::sort (sorted_phis.address (),
		 sorted_phis.address () + sorted_phis.length (),
		 compare_access_infos);

      // Set the inputs of the non-degenerate register phis.  All inputs
      // for one edge come before all inputs for the next edge.
      set_info **inputs = phis.inputs;
      unsigned int phi_i = 0;
      bitmap_iterator bmi;
      unsigned int regno;
      EXECUTE_IF_SET_IN_BITMAP (&phis.regs, 0, regno, bmi)
	{
	  // Skip intervening degenerate phis.
	  while (sorted_phis[phi_i]->regno () < regno)
	    phi_i += 1;
	  phi_info *phi = sorted_phis[phi_i];
	  gcc_assert (phi->regno () == regno);
	  for (unsigned int input_i = 0; input_i < phis.num_preds; ++input_i)
	    if (set_info *input = inputs[input_i * phis.num_phis])
	      {
		use_info *use = phi->input_use (input_i);
		gcc_assert (!use->def ());
		use->set_def (input);
		add_use (use);
	      }
	  phi_i += 1;
	  inputs += 1;
	}

      // Fill in the backedge inputs to any memory phi.
      phi_info *mem_phi = sorted_phis.last ();
      if (mem_phi->is_mem () && !mem_phi->is_degenerate ())
	{
	  edge e;
	  edge_iterator ei;
	  FOR_EACH_EDGE (e, ei, cfg_bb->preds)
	    {
	      use_info *use = mem_phi->input_use (e->dest_idx);
	      if (!use->def ())
		{
		  use->set_def (bi.bb_mem_live_out[e->src->index]);
		  add_use (use);
		}
	    }
	}
    }
}

// Return true if it would be better to continue an EBB across NEW_EDGE
// rather than across OLD_EDGE, given that both edges are viable candidates.
// This is not a total ordering.
static bool
better_ebb_edge_p (edge new_edge, edge old_edge)
{
  // Prefer the likeliest edge.
  if (new_edge->probability.initialized_p ()
      && old_edge->probability.initialized_p ()
      && !(old_edge->probability == new_edge->probability))
    return old_edge->probability < new_edge->probability;

  // If both edges are equally likely, prefer a fallthru edge.
  if (new_edge->flags & EDGE_FALLTHRU)
    return true;
  if (old_edge->flags & EDGE_FALLTHRU)
    return false;

  // Otherwise just stick with OLD_EDGE.
  return false;
}

// Pick and return the next basic block in an EBB that currently ends with BB.
// Return null if the EBB must end with BB.
static basic_block
choose_next_block_in_ebb (basic_block bb)
{
  // Although there's nothing in principle wrong with having an EBB that
  // starts with the entry block and includes later blocks, there's not
  // really much point either.  Keeping the entry block separate means
  // that uses of arguments consistently occur through phi nodes, rather
  // than the arguments sometimes appearing to come from an EBB-local
  // definition instead.
  if (bb->index == ENTRY_BLOCK)
    return nullptr;

  bool optimize_for_speed_p = optimize_bb_for_speed_p (bb);
  edge best_edge = nullptr;
  edge e;
  edge_iterator ei;
  FOR_EACH_EDGE (e, ei, bb->succs)
    if (!(e->flags & EDGE_COMPLEX)
	&& e->dest->index != EXIT_BLOCK
	&& single_pred_p (e->dest)
	&& optimize_for_speed_p == optimize_bb_for_speed_p (e->dest)
	&& (!best_edge || better_ebb_edge_p (e, best_edge)))
      best_edge = e;

  return best_edge ? best_edge->dest : nullptr;
}

// Partition the function into extended basic blocks.  Create the
// associated ebb_infos and bb_infos, but don't add the bb_infos
// to the function list yet.
void
function_info::create_ebbs (build_info &bi)
{
  // Compute the starting reverse postorder.  We tweak this later to try
  // to get better EBB assignments.
  auto *postorder = new int[n_basic_blocks_for_fn (m_fn)];
  unsigned int postorder_num
    = pre_and_rev_post_order_compute (nullptr, postorder, true);
  gcc_assert (int (postorder_num) <= n_basic_blocks_for_fn (m_fn));

  // Iterate over the blocks in reverse postorder.  In cases where
  // multiple possible orders exist, prefer orders that chain blocks
  // together into EBBs.  If multiple possible EBBs exist, try to pick
  // the ones that are most likely to be profitable.
  auto_vec<bb_info *, 16> bbs;
  unsigned int next_bb_index = 0;
  for (unsigned int i = 0; i < postorder_num; ++i)
    if (!m_bbs[postorder[i]])
      {
	// Choose and create the blocks that should form the next EBB.
	basic_block cfg_bb = BASIC_BLOCK_FOR_FN (m_fn, postorder[i]);
	do
	  {
	    // Record the chosen block order in a new RPO.
	    bi.bb_to_rpo[cfg_bb->index] = next_bb_index++;
	    bbs.safe_push (create_bb_info (cfg_bb));
	    cfg_bb = choose_next_block_in_ebb (cfg_bb);
	  }
	while (cfg_bb);

	// Create the EBB itself.
	auto *ebb = allocate<ebb_info> (bbs[0], bbs.last ());
	for (bb_info *bb : bbs)
	  bb->set_ebb (ebb);
	bbs.truncate (0);
      }

  delete[] postorder;
}

// Partition the function's blocks into EBBs and build SSA form for all
// EBBs in the function.
void
function_info::process_all_blocks ()
{
  auto temps = temp_watermark ();
  unsigned int num_bb_indices = last_basic_block_for_fn (m_fn);

  build_info bi (m_num_regs, num_bb_indices);

  calculate_potential_phi_regs (bi);
  create_ebbs (bi);
  place_phis (bi);
  bb_walker (this, bi).walk (ENTRY_BLOCK_PTR_FOR_FN (m_fn));
  populate_phi_inputs (bi);

  if (flag_checking)
    {
      // The definition stack should be empty and all register definitions
      // should be back in their original undefined state.
      gcc_assert (bi.def_stack.is_empty ()
		  && bi.old_def_stack_limit.is_empty ());
      for (unsigned int regno = 0; regno < m_num_regs; ++regno)
	gcc_assert (!bi.last_access[regno + 1]);
    }
}

// Print a description of CALL_CLOBBERS to PP.
void
rtl_ssa::pp_ebb_call_clobbers (pretty_printer *pp,
			       const ebb_call_clobbers_info *call_clobbers)
{
  if (!call_clobbers)
    pp_string (pp, "<null>");
  else
    call_clobbers->print_full (pp);
}

// Print a description of BB to PP.
void
rtl_ssa::pp_bb (pretty_printer *pp, const bb_info *bb)
{
  if (!bb)
    pp_string (pp, "<null>");
  else
    bb->print_full (pp);
}

// Print a description of EBB to PP
void
rtl_ssa::pp_ebb (pretty_printer *pp, const ebb_info *ebb)
{
  if (!ebb)
    pp_string (pp, "<null>");
  else
    ebb->print_full (pp);
}

// Print a description of CALL_CLOBBERS to FILE.
void
dump (FILE *file, const ebb_call_clobbers_info *call_clobbers)
{
  dump_using (file, pp_ebb_call_clobbers, call_clobbers);
}

// Print a description of BB to FILE.
void
dump (FILE *file, const bb_info *bb)
{
  dump_using (file, pp_bb, bb);
}

// Print a description of EBB to FILE.
void
dump (FILE *file, const ebb_info *ebb)
{
  dump_using (file, pp_ebb, ebb);
}

// Debug interfaces to the dump routines above.
void debug (const ebb_call_clobbers_info *x) { dump (stderr, x); }
void debug (const bb_info *x) { dump (stderr, x); }
void debug (const ebb_info *x) { dump (stderr, x); }
