/* Generic dominator tree walker
   Copyright (C) 2003-2021 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 (__builtin_expect (n == 2, true))
    {
      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 (__builtin_expect (n == 3, true))
    {
      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)
{
}

/* 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_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);
}
