/* Generic dominator tree walker
   Copyright (C) 2003-2022 Free Software Foundation, Inc.
   Contributed by Diego Novillo <dnovillo@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 "backend.h"
#include "cfganal.h"
#include "domwalk.h"
#include "dumpfile.h"

/* This file implements a generic walker for dominator trees.

  To understand the dominator walker one must first have a grasp of dominators,
  immediate dominators and the dominator tree.

  Dominators
    A block B1 is said to dominate B2 if every path from the entry to B2 must
    pass through B1.  Given the dominance relationship, we can proceed to
    compute immediate dominators.  Note it is not important whether or not
    our definition allows a block to dominate itself.

  Immediate Dominators:
    Every block in the CFG has no more than one immediate dominator.  The
    immediate dominator of block BB must dominate BB and must not dominate
    any other dominator of BB and must not be BB itself.

  Dominator tree:
    If we then construct a tree where each node is a basic block and there
    is an edge from each block's immediate dominator to the block itself, then
    we have a dominator tree.


  [ Note this walker can also walk the post-dominator tree, which is
    defined in a similar manner.  i.e., block B1 is said to post-dominate
    block B2 if all paths from B2 to the exit block must pass through
    B1.  ]

  For example, given the CFG

                   1
                   |
                   2
                  / \
                 3   4
                    / \
       +---------->5   6
       |          / \ /
       |    +--->8   7
       |    |   /    |
       |    +--9    11
       |      /      |
       +--- 10 ---> 12


  We have a dominator tree which looks like

                   1
                   |
                   2
                  / \
                 /   \
                3     4
                   / / \ \
                   | | | |
                   5 6 7 12
                   |   |
                   8   11
                   |
                   9
                   |
                  10



  The dominator tree is the basis for a number of analysis, transformation
  and optimization algorithms that operate on a semi-global basis.

  The dominator walker is a generic routine which visits blocks in the CFG
  via a depth first search of the dominator tree.  In the example above
  the dominator walker might visit blocks in the following order
  1, 2, 3, 4, 5, 8, 9, 10, 6, 7, 11, 12.

  The dominator walker has a number of callbacks to perform actions
  during the walk of the dominator tree.  There are two callbacks
  which walk statements, one before visiting the dominator children,
  one after visiting the dominator children.  There is a callback
  before and after each statement walk callback.  In addition, the
  dominator walker manages allocation/deallocation of data structures
  which are local to each block visited.

  The dominator walker is meant to provide a generic means to build a pass
  which can analyze or transform/optimize a function based on walking
  the dominator tree.  One simply fills in the dominator walker data
  structure with the appropriate callbacks and calls the walker.

  We currently use the dominator walker to prune the set of variables
  which might need PHI nodes (which can greatly improve compile-time
  performance in some cases).

  We also use the dominator walker to rewrite the function into SSA form
  which reduces code duplication since the rewriting phase is inherently
  a walk of the dominator tree.

  And (of course), we use the dominator walker to drive our dominator
  optimizer, which is a semi-global optimizer.

  TODO:

    Walking statements is based on the block statement iterator abstraction,
    which is currently an abstraction over walking tree statements.  Thus
    the dominator walker is currently only useful for trees.  */

static int
cmp_bb_postorder (const void *a, const void *b, void *data)
{
  basic_block bb1 = *(const basic_block *)(a);
  basic_block bb2 = *(const basic_block *)(b);
  int *bb_postorder = (int *)data;
  /* Place higher completion number first (pop off lower number first).  */
  return bb_postorder[bb2->index] - bb_postorder[bb1->index];
}

/* Permute array BBS of N basic blocks in postorder,
   i.e. by descending number in BB_POSTORDER array.  */

static void
sort_bbs_postorder (basic_block *bbs, int n, int *bb_postorder)
{
  if (LIKELY (n == 2))
    {
      basic_block bb0 = bbs[0], bb1 = bbs[1];
      if (bb_postorder[bb0->index] < bb_postorder[bb1->index])
	bbs[0] = bb1, bbs[1] = bb0;
    }
  else if (LIKELY (n == 3))
    {
      basic_block bb0 = bbs[0], bb1 = bbs[1], bb2 = bbs[2];
      if (bb_postorder[bb0->index] < bb_postorder[bb1->index])
	std::swap (bb0, bb1);
      if (bb_postorder[bb1->index] < bb_postorder[bb2->index])
	{
	  std::swap (bb1, bb2);
	  if (bb_postorder[bb0->index] < bb_postorder[bb1->index])
	    std::swap (bb0, bb1);
	}
      bbs[0] = bb0, bbs[1] = bb1, bbs[2] = bb2;
    }
  else
    gcc_sort_r (bbs, n, sizeof *bbs, cmp_bb_postorder, bb_postorder);
}

/* Set EDGE_EXECUTABLE on every edge within FN's CFG.  */

void
set_all_edges_as_executable (function *fn)
{
  basic_block bb;
  FOR_ALL_BB_FN (bb, fn)
    {
      edge_iterator ei;
      edge e;
      FOR_EACH_EDGE (e, ei, bb->succs)
	e->flags |= EDGE_EXECUTABLE;
    }
}

/* Constructor for a dom walker.  */

dom_walker::dom_walker (cdi_direction direction,
			enum reachability reachability,
			int *bb_index_to_rpo)
  : m_dom_direction (direction),
    m_reachability (reachability),
    m_user_bb_to_rpo (bb_index_to_rpo != NULL),
    m_unreachable_dom (NULL),
    m_bb_to_rpo (bb_index_to_rpo == (int *)(uintptr_t)-1
		 ? NULL : bb_index_to_rpo)
{
}

/* Destructor.  */

dom_walker::~dom_walker ()
{
  if (! m_user_bb_to_rpo)
    free (m_bb_to_rpo);
}

/* Return TRUE if BB is reachable, false otherwise.  */

bool
dom_walker::bb_reachable (struct function *fun, basic_block bb)
{
  /* If we're not skipping unreachable blocks, then assume everything
     is reachable.  */
  if (m_reachability == ALL_BLOCKS)
    return true;

  /* If any of the predecessor edges that do not come from blocks dominated
     by us are still marked as possibly executable consider this block
     reachable.  */
  bool reachable = false;
  if (!m_unreachable_dom)
    {
      reachable = bb == ENTRY_BLOCK_PTR_FOR_FN (fun);
      edge_iterator ei;
      edge e;
      FOR_EACH_EDGE (e, ei, bb->preds)
	if (!dominated_by_p (CDI_DOMINATORS, e->src, bb))
	  reachable |= (e->flags & EDGE_EXECUTABLE);
    }

  return reachable;
}

/* BB has been determined to be unreachable.  Propagate that property
   to incoming and outgoing edges of BB as appropriate.  */

void
dom_walker::propagate_unreachable_to_edges (basic_block bb,
					    FILE *dump_file,
					    dump_flags_t dump_flags)
{
  if (dump_file && (dump_flags & TDF_DETAILS))
    fprintf (dump_file, "Marking all outgoing edges of unreachable "
	     "BB %d as not executable\n", bb->index);

  edge_iterator ei;
  edge e;
  FOR_EACH_EDGE (e, ei, bb->succs)
    e->flags &= ~EDGE_EXECUTABLE;

  FOR_EACH_EDGE (e, ei, bb->preds)
    {
      if (dominated_by_p (CDI_DOMINATORS, e->src, bb))
	{
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    fprintf (dump_file, "Marking backedge from BB %d into "
		     "unreachable BB %d as not executable\n",
		     e->src->index, bb->index);
	  e->flags &= ~EDGE_EXECUTABLE;
	}
    }

  if (!m_unreachable_dom)
    m_unreachable_dom = bb;
}

const edge dom_walker::STOP = (edge)-1;

/* Recursively walk the dominator tree.
   BB is the basic block we are currently visiting.  */

void
dom_walker::walk (basic_block bb)
{
  /* Compute the basic-block index to RPO mapping lazily.  */
  if (!m_user_bb_to_rpo
      && !m_bb_to_rpo
      && m_dom_direction == CDI_DOMINATORS)
    {
      int *postorder = XNEWVEC (int, n_basic_blocks_for_fn (cfun));
      int postorder_num = pre_and_rev_post_order_compute (NULL, postorder,
							  true);
      m_bb_to_rpo = XNEWVEC (int, last_basic_block_for_fn (cfun));
      for (int i = 0; i < postorder_num; ++i)
	m_bb_to_rpo[postorder[i]] = i;
      free (postorder);
    }

  /* Set up edge flags if need be.  */
  if (m_reachability == REACHABLE_BLOCKS)
    set_all_edges_as_executable (cfun);

  basic_block dest;
  basic_block *worklist = XNEWVEC (basic_block,
				   n_basic_blocks_for_fn (cfun) * 2);
  int sp = 0;

  while (true)
    {
      /* Don't worry about unreachable blocks.  */
      if (EDGE_COUNT (bb->preds) > 0
	  || bb == ENTRY_BLOCK_PTR_FOR_FN (cfun)
	  || bb == EXIT_BLOCK_PTR_FOR_FN (cfun))
	{
	  edge taken_edge = NULL;

	  /* Callback for subclasses to do custom things before we have walked
	     the dominator children, but before we walk statements.  */
	  if (this->bb_reachable (cfun, bb))
	    {
	      taken_edge = before_dom_children (bb);
	      if (taken_edge && taken_edge != STOP)
		{
		  edge_iterator ei;
		  edge e;
		  FOR_EACH_EDGE (e, ei, bb->succs)
		    if (e != taken_edge)
		      e->flags &= ~EDGE_EXECUTABLE;
		}
	    }
	  else
	    propagate_unreachable_to_edges (bb, dump_file, dump_flags);

	  /* Mark the current BB to be popped out of the recursion stack
	     once children are processed.  */
	  worklist[sp++] = bb;
	  worklist[sp++] = NULL;

	  /* If the callback returned NONE then we are supposed to
	     stop and not even propagate EDGE_EXECUTABLE further.  */
	  if (taken_edge != STOP)
	    {
	      int saved_sp = sp;
	      for (dest = first_dom_son (m_dom_direction, bb);
		   dest; dest = next_dom_son (m_dom_direction, dest))
		worklist[sp++] = dest;
	      /* Sort worklist after RPO order if requested.  */
	      if (sp - saved_sp > 1
		  && m_dom_direction == CDI_DOMINATORS
		  && m_bb_to_rpo)
		sort_bbs_postorder (&worklist[saved_sp], sp - saved_sp,
				    m_bb_to_rpo);
	    }
	}
      /* NULL is used to mark pop operations in the recursion stack.  */
      while (sp > 0 && !worklist[sp - 1])
	{
	  --sp;
	  bb = worklist[--sp];

	  /* Callback allowing subclasses to do custom things after we have
	     walked dominator children, but before we walk statements.  */
	  if (bb_reachable (cfun, bb))
	    after_dom_children (bb);
	  else if (m_unreachable_dom == bb)
	    m_unreachable_dom = NULL;
	}
      if (sp)
	bb = worklist[--sp];
      else
	break;
    }
  free (worklist);
}
