/* Dead-code elimination pass for the GNU compiler.
   Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
   Written by Jeffrey D. Oldham <oldham@codesourcery.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 2, 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 COPYING.  If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.  */

/* Dead-code elimination is the removal of instructions which have no
   impact on the program's output.  "Dead instructions" have no impact
   on the program's output, while "necessary instructions" may have
   impact on the output.

   The algorithm consists of three phases:
   1) marking as necessary all instructions known to be necessary,
      e.g., writing a value to memory,
   2) propagating necessary instructions, e.g., the instructions
      giving values to operands in necessary instructions, and
   3) removing dead instructions (except replacing dead conditionals
      with unconditional jumps).

   Side Effects:
   The last step can require adding labels, deleting insns, and
   modifying basic block structures.  Some conditional jumps may be
   converted to unconditional jumps so the control-flow graph may be
   out-of-date.

   Edges from some infinite loops to the exit block can be added to
   the control-flow graph, but will be removed after this pass is
   complete.

   It Does Not Perform:
   We decided to not simultaneously perform jump optimization and dead
   loop removal during dead-code elimination.  Thus, all jump
   instructions originally present remain after dead-code elimination
   but 1) unnecessary conditional jump instructions are changed to
   unconditional jump instructions and 2) all unconditional jump
   instructions remain.

   Assumptions:
   1) SSA has been performed.
   2) The basic block and control-flow graph structures are accurate.
   3) The flow graph permits constructing an edge_list.
   4) note rtxes should be saved.

   Unfinished:
   When replacing unnecessary conditional jumps with unconditional
   jumps, the control-flow graph is not updated.  It should be.

   References:
   Building an Optimizing Compiler
   Robert Morgan
   Butterworth-Heinemann, 1998
   Section 8.9
*/

#include "config.h"
#include "system.h"

#include "rtl.h"
#include "hard-reg-set.h"
#include "basic-block.h"
#include "ssa.h"
#include "insn-config.h"
#include "recog.h"
#include "output.h"


/* A map from blocks to the edges on which they are control dependent.  */
typedef struct {
  /* An dynamically allocated array.  The Nth element corresponds to
     the block with index N + 2.  The Ith bit in the bitmap is set if
     that block is dependent on the Ith edge.  */
  bitmap *data;
  /* The number of elements in the array.  */
  int length;
} control_dependent_block_to_edge_map_s, *control_dependent_block_to_edge_map;

/* Local function prototypes.  */
static control_dependent_block_to_edge_map control_dependent_block_to_edge_map_create
  PARAMS((size_t num_basic_blocks));
static void set_control_dependent_block_to_edge_map_bit
  PARAMS ((control_dependent_block_to_edge_map c, basic_block bb,
	   int edge_index));
static void control_dependent_block_to_edge_map_free
  PARAMS ((control_dependent_block_to_edge_map c));
static void find_all_control_dependences
  PARAMS ((struct edge_list *el, int *pdom,
	   control_dependent_block_to_edge_map cdbte));
static void find_control_dependence
  PARAMS ((struct edge_list *el, int edge_index, int *pdom,
	   control_dependent_block_to_edge_map cdbte));
static basic_block find_pdom
  PARAMS ((int *pdom, basic_block block));
static int inherently_necessary_register_1
  PARAMS ((rtx *current_rtx, void *data));
static int inherently_necessary_register
  PARAMS ((rtx current_rtx));
static int find_inherently_necessary
  PARAMS ((rtx current_rtx));
static int propagate_necessity_through_operand
  PARAMS ((rtx *current_rtx, void *data));
static void note_inherently_necessary_set
  PARAMS ((rtx, rtx, void *));

/* Unnecessary insns are indicated using insns' in_struct bit.  */

/* Indicate INSN is dead-code; returns nothing.  */
#define KILL_INSN(INSN)		INSN_DEAD_CODE_P(INSN) = 1
/* Indicate INSN is necessary, i.e., not dead-code; returns nothing.  */
#define RESURRECT_INSN(INSN)	INSN_DEAD_CODE_P(INSN) = 0
/* Return nonzero if INSN is unnecessary.  */
#define UNNECESSARY_P(INSN)	INSN_DEAD_CODE_P(INSN)
static void mark_all_insn_unnecessary
  PARAMS ((void));
/* Execute CODE with free variable INSN for all unnecessary insns in
   an unspecified order, producing no output.  */
#define EXECUTE_IF_UNNECESSARY(INSN, CODE)	\
{								\
  rtx INSN;							\
								\
  for (INSN = get_insns (); INSN != NULL_RTX; INSN = NEXT_INSN (INSN))	\
    if (INSN_DEAD_CODE_P (INSN)) {				\
      CODE;							\
    }								\
}
/* Find the label beginning block BB.  */
static rtx find_block_label
  PARAMS ((basic_block bb));
/* Remove INSN, updating its basic block structure.  */
static void delete_insn_bb
  PARAMS ((rtx insn));

/* Recording which blocks are control dependent on which edges.  We
   expect each block to be control dependent on very few edges so we
   use a bitmap for each block recording its edges.  An array holds
   the bitmap.  Its position 0 entry holds the bitmap for block
   INVALID_BLOCK+1 so that all blocks, including the entry and exit
   blocks can participate in the data structure.  */

/* Create a control_dependent_block_to_edge_map, given the number
   NUM_BASIC_BLOCKS of non-entry, non-exit basic blocks, e.g.,
   n_basic_blocks.  This memory must be released using
   control_dependent_block_to_edge_map_free ().  */

static control_dependent_block_to_edge_map
control_dependent_block_to_edge_map_create (num_basic_blocks)
     size_t num_basic_blocks;
{
  int i;
  control_dependent_block_to_edge_map c
    = xmalloc (sizeof (control_dependent_block_to_edge_map_s));
  c->length = num_basic_blocks - (INVALID_BLOCK+1);
  c->data = xmalloc ((size_t) c->length*sizeof (bitmap));
  for (i = 0; i < c->length; ++i)
    c->data[i] = BITMAP_XMALLOC ();

  return c;
}

/* Indicate block BB is control dependent on an edge with index
   EDGE_INDEX in the mapping C of blocks to edges on which they are
   control-dependent.  */

static void
set_control_dependent_block_to_edge_map_bit (c, bb, edge_index)
     control_dependent_block_to_edge_map c;
     basic_block bb;
     int edge_index;
{
  if (bb->index - (INVALID_BLOCK+1) >= c->length)
    abort ();

  bitmap_set_bit (c->data[bb->index - (INVALID_BLOCK+1)],
		  edge_index);
}

/* Execute CODE for each edge (given number EDGE_NUMBER within the
   CODE) for which the block containing INSN is control dependent,
   returning no output.  CDBTE is the mapping of blocks to edges on
   which they are control-dependent.  */

#define EXECUTE_IF_CONTROL_DEPENDENT(CDBTE, INSN, EDGE_NUMBER, CODE) \
	EXECUTE_IF_SET_IN_BITMAP \
	  (CDBTE->data[BLOCK_NUM (INSN) - (INVALID_BLOCK+1)], 0, \
	  EDGE_NUMBER, CODE)

/* Destroy a control_dependent_block_to_edge_map C.  */

static void
control_dependent_block_to_edge_map_free (c)
     control_dependent_block_to_edge_map c;
{
  int i;
  for (i = 0; i < c->length; ++i)
    BITMAP_XFREE (c->data[i]);
  free ((PTR) c);
}

/* Record all blocks' control dependences on all edges in the edge
   list EL, ala Morgan, Section 3.6.  The mapping PDOM of blocks to
   their postdominators are used, and results are stored in CDBTE,
   which should be empty.  */

static void
find_all_control_dependences (el, pdom, cdbte)
   struct edge_list *el;
   int *pdom;
   control_dependent_block_to_edge_map cdbte;
{
  int i;

  for (i = 0; i < NUM_EDGES (el); ++i)
    find_control_dependence (el, i, pdom, cdbte);
}

/* Determine all blocks' control dependences on the given edge with
   edge_list EL index EDGE_INDEX, ala Morgan, Section 3.6.  The
   mapping PDOM of blocks to their postdominators are used, and
   results are stored in CDBTE, which is assumed to be initialized
   with zeros in each (block b', edge) position.  */

static void
find_control_dependence (el, edge_index, pdom, cdbte)
   struct edge_list *el;
   int edge_index;
   int *pdom;
   control_dependent_block_to_edge_map cdbte;
{
  basic_block current_block;
  basic_block ending_block;

  if (INDEX_EDGE_PRED_BB (el, edge_index) == EXIT_BLOCK_PTR)
    abort ();
  ending_block =
    (INDEX_EDGE_PRED_BB (el, edge_index) == ENTRY_BLOCK_PTR)
    ? BASIC_BLOCK (0)
    : find_pdom (pdom, INDEX_EDGE_PRED_BB (el, edge_index));

  for (current_block = INDEX_EDGE_SUCC_BB (el, edge_index);
       current_block != ending_block && current_block != EXIT_BLOCK_PTR;
       current_block = find_pdom (pdom, current_block))
    {
      set_control_dependent_block_to_edge_map_bit (cdbte,
						   current_block,
						   edge_index);
    }
}

/* Find the immediate postdominator PDOM of the specified basic block
   BLOCK.  This function is necessary because some blocks have
   negative numbers.  */

static basic_block
find_pdom (pdom, block)
     int *pdom;
     basic_block block;
{
  if (!block)
    abort ();
  if (block->index == INVALID_BLOCK)
    abort ();

  if (block == ENTRY_BLOCK_PTR)
    return BASIC_BLOCK (0);
  else if (block == EXIT_BLOCK_PTR || pdom[block->index] == EXIT_BLOCK)
    return EXIT_BLOCK_PTR;
  else
    return BASIC_BLOCK (pdom[block->index]);
}

/* Determine if the given CURRENT_RTX uses a hard register not
   converted to SSA.  Returns nonzero only if it uses such a hard
   register.  DATA is not used.

   The program counter (PC) is not considered inherently necessary
   since code should be position-independent and thus not depend on
   particular PC values.  */

static int
inherently_necessary_register_1 (current_rtx, data)
     rtx *current_rtx;
     void *data ATTRIBUTE_UNUSED;
{
  rtx x = *current_rtx;

  if (x == NULL_RTX)
    return 0;
  switch (GET_CODE (x))
    {
    case CLOBBER:
      /* Do not traverse the rest of the clobber.  */
      return -1;
      break;
    case PC:
      return 0;
      break;
    case REG:
      if (CONVERT_REGISTER_TO_SSA_P (REGNO (x)) || x == pc_rtx)
	return 0;
      else
	return !0;
      break;
    default:
      return 0;
      break;
    }
}

/* Return nonzero if the insn CURRENT_RTX is inherently necessary.  */

static int
inherently_necessary_register (current_rtx)
     rtx current_rtx;
{
  return for_each_rtx (&current_rtx,
		       &inherently_necessary_register_1, NULL);
}


/* Called via note_stores for each store in an insn.  Note whether
   or not a particular store is inherently necessary.  Store a
   nonzero value in inherently_necessary_p if such a store is found.  */

static void
note_inherently_necessary_set (dest, set, data)
     rtx set ATTRIBUTE_UNUSED;
     rtx dest;
     void *data;
{
  int *inherently_necessary_set_p = (int *) data;

  while (GET_CODE (dest) == SUBREG
	 || GET_CODE (dest) == STRICT_LOW_PART
	 || GET_CODE (dest) == ZERO_EXTRACT
	 || GET_CODE (dest) == SIGN_EXTRACT)
    dest = XEXP (dest, 0);

  if (GET_CODE (dest) == MEM
      || GET_CODE (dest) == UNSPEC
      || GET_CODE (dest) == UNSPEC_VOLATILE)
    *inherently_necessary_set_p = 1;
}

/* Mark X as inherently necessary if appropriate.  For example,
   function calls and storing values into memory are inherently
   necessary.  This function is to be used with for_each_rtx ().
   Return nonzero iff inherently necessary.  */

static int
find_inherently_necessary (x)
     rtx x;
{
  if (x == NULL_RTX)
    return 0;
  else if (inherently_necessary_register (x))
    return !0;
  else
    switch (GET_CODE (x))
      {  
      case CALL_INSN:
      case BARRIER:
      case PREFETCH:
	return !0;
      case CODE_LABEL:
      case NOTE:
	return 0;
      case JUMP_INSN:
	return JUMP_TABLE_DATA_P (x) || computed_jump_p (x) != 0;
      case INSN:
	{
	  int inherently_necessary_set = 0;
	  note_stores (PATTERN (x),
		       note_inherently_necessary_set,
		       &inherently_necessary_set);

	  /* If we found an inherently necessary set or an asm
	     instruction, then we consider this insn inherently
	     necessary.  */
	  return (inherently_necessary_set
		  || GET_CODE (PATTERN (x)) == ASM_INPUT
		  || asm_noperands (PATTERN (x)) >= 0);
	}
      default:
	/* Found an impossible insn type.  */
	abort ();
	break;
      }
}

/* Propagate necessity through REG and SUBREG operands of CURRENT_RTX.
   This function is called with for_each_rtx () on necessary
   instructions.  The DATA must be a varray of unprocessed
   instructions.  */

static int
propagate_necessity_through_operand (current_rtx, data)
     rtx *current_rtx;
     void *data;
{
  rtx x = *current_rtx;
  varray_type *unprocessed_instructions = (varray_type *) data;

  if (x == NULL_RTX)
    return 0;
  switch ( GET_CODE (x))
    {
    case REG:
      if (CONVERT_REGISTER_TO_SSA_P (REGNO (x)))
	{
	  rtx insn = VARRAY_RTX (ssa_definition, REGNO (x));
	  if (insn != NULL_RTX && UNNECESSARY_P (insn))
	    {
	      RESURRECT_INSN (insn);
	      VARRAY_PUSH_RTX (*unprocessed_instructions, insn);
	    }
	}
      return 0;

    default:
      return 0;
    }
}

/* Indicate all insns initially assumed to be unnecessary.  */

static void
mark_all_insn_unnecessary ()
{
  rtx insn;
  for (insn = get_insns (); insn != NULL_RTX; insn = NEXT_INSN (insn))
    KILL_INSN (insn);
}

/* Find the label beginning block BB, adding one if necessary.  */

static rtx
find_block_label (bb)
     basic_block bb;
{
  rtx insn = bb->head;
  if (LABEL_P (insn))
    return insn;
  else
    {
      rtx new_label = emit_label_before (gen_label_rtx (), insn);
      if (insn == bb->head)
	bb->head = new_label;
      return new_label;
    }
}

/* Remove INSN, updating its basic block structure.  */

static void
delete_insn_bb (insn)
     rtx insn;
{
  if (!insn)
    abort ();

  /* Do not actually delete anything that is not an INSN.

     We can get here because we only consider INSNs as
     potentially necessary.  We leave it to later passes
     to remove unnecessary notes, unused labels, etc.  */
  if (! INSN_P (insn))
    return;

  delete_insn (insn);
}

/* Perform the dead-code elimination.  */

void
ssa_eliminate_dead_code ()
{
  int i;
  rtx insn;
  /* Necessary instructions with operands to explore.  */
  varray_type unprocessed_instructions;
  /* Map element (b,e) is nonzero if the block is control dependent on
     edge.  "cdbte" abbreviates control dependent block to edge.  */
  control_dependent_block_to_edge_map cdbte;
 /* Element I is the immediate postdominator of block I.  */
  int *pdom;
  struct edge_list *el;

  int max_insn_uid = get_max_uid ();

  /* Initialize the data structures.  */
  mark_all_insn_unnecessary ();
  VARRAY_RTX_INIT (unprocessed_instructions, 64,
		   "unprocessed instructions");
  cdbte = control_dependent_block_to_edge_map_create (n_basic_blocks);

  /* Prepare for use of BLOCK_NUM ().  */
  connect_infinite_loops_to_exit ();
   /* Be careful not to clear the added edges.  */
  compute_bb_for_insn (max_insn_uid);

  /* Compute control dependence.  */
  pdom = (int *) xmalloc (n_basic_blocks * sizeof (int));
  for (i = 0; i < n_basic_blocks; ++i)
    pdom[i] = INVALID_BLOCK;
  calculate_dominance_info (pdom, NULL, CDI_POST_DOMINATORS);
  /* Assume there is a path from each node to the exit block.  */
  for (i = 0; i < n_basic_blocks; ++i)
    if (pdom[i] == INVALID_BLOCK)
      pdom[i] = EXIT_BLOCK;
  el = create_edge_list ();
  find_all_control_dependences (el, pdom, cdbte);

  /* Find inherently necessary instructions.  */
  for (insn = get_insns (); insn != NULL_RTX; insn = NEXT_INSN (insn))
    if (find_inherently_necessary (insn))
      {
	RESURRECT_INSN (insn);
	VARRAY_PUSH_RTX (unprocessed_instructions, insn);
      }

  /* Propagate necessity using the operands of necessary instructions.  */
  while (VARRAY_ACTIVE_SIZE (unprocessed_instructions) > 0)
    {
      rtx current_instruction;
      int edge_number;

      current_instruction = VARRAY_TOP_RTX (unprocessed_instructions);
      VARRAY_POP (unprocessed_instructions);

      /* Make corresponding control dependent edges necessary.  */
      /* Assume the only JUMP_INSN is the block's last insn.  It appears
	 that the last instruction of the program need not be a
	 JUMP_INSN.  */

      if (INSN_P (current_instruction)
	  && !JUMP_TABLE_DATA_P (current_instruction))
	{
	  /* Notes and labels contain no interesting operands.  */
	  EXECUTE_IF_CONTROL_DEPENDENT
	    (cdbte, current_instruction, edge_number,
	    {
	      rtx jump_insn = (INDEX_EDGE_PRED_BB (el, edge_number))->end;
	      if (GET_CODE (jump_insn) == JUMP_INSN
		  && UNNECESSARY_P (jump_insn))
		{
		  RESURRECT_INSN (jump_insn);
		  VARRAY_PUSH_RTX (unprocessed_instructions, jump_insn);
		}
	    });

	  /* Propagate through the operands.  */
	  for_each_rtx (&current_instruction,
			&propagate_necessity_through_operand,
			(PTR) &unprocessed_instructions);

	  /* PHI nodes are somewhat special in that each PHI alternative
	     has data and control dependencies.  The data dependencies
	     are handled via propagate_necessity_through_operand.  We
	     handle the control dependency here.

	     We consider the control dependent edges leading to the
	     predecessor block associated with each PHI alternative
	     as necessary.  */
	  if (PHI_NODE_P (current_instruction))
	    {
	      rtvec phi_vec = XVEC (SET_SRC (PATTERN (current_instruction)), 0);
	      int num_elem = GET_NUM_ELEM (phi_vec);
	      int v;

	      for (v = num_elem - 2; v >= 0; v -= 2)
		{
		  basic_block bb;

		  bb = BASIC_BLOCK (INTVAL (RTVEC_ELT (phi_vec, v + 1)));
		  EXECUTE_IF_CONTROL_DEPENDENT
		    (cdbte, bb->end, edge_number,
		    {
		      rtx jump_insn;

		      jump_insn = (INDEX_EDGE_PRED_BB (el, edge_number))->end;
		      if (((GET_CODE (jump_insn) == JUMP_INSN))
			  && UNNECESSARY_P (jump_insn))
			{
			  RESURRECT_INSN (jump_insn);
			  VARRAY_PUSH_RTX (unprocessed_instructions, jump_insn);
			}
		    });

		}
	    }
	}
    }

  /* Remove the unnecessary instructions.  */
  EXECUTE_IF_UNNECESSARY (insn,
  {
    if (any_condjump_p (insn))
      {
	basic_block bb = BLOCK_FOR_INSN (insn);
	basic_block pdom_bb = find_pdom (pdom, bb);
	rtx lbl;
	edge e;

	/* Egad.  The immediate post dominator is the exit block.  We
	   would like to optimize this conditional jump to jump directly
	   to the exit block.  That can be difficult as we may not have
	   a suitable CODE_LABEL that allows us to fall unmolested into
	   the exit block.

	   So, we just delete the conditional branch by turning it into
	   a deleted note.   That is safe, but just not as optimal as
	   it could be.  */
	if (pdom_bb == EXIT_BLOCK_PTR)
	  {
	    /* Since we're going to just delete the branch, we need
	       look at all the edges and remove all those which are not
	       a fallthru edge.  */
	    e = bb->succ;
	    while (e)
	      {
		edge temp = e;

		e = e->succ_next;
		if ((temp->flags & EDGE_FALLTHRU) == 0)
		  {
		    /* We've found a non-fallthru edge, find any PHI nodes
		       at the target and clean them up.  */
		    if (temp->dest != EXIT_BLOCK_PTR)
		      {
		        rtx insn
			  = first_insn_after_basic_block_note (temp->dest);

		        while (PHI_NODE_P (insn))
			  {
			    remove_phi_alternative (PATTERN (insn), temp->src);
			    insn = NEXT_INSN (insn);
			  }
		      }

		    remove_edge (temp);
		  }
	      }

	    /* Now "delete" the conditional jump.  */
	    PUT_CODE (insn, NOTE);
	    NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
	    continue;
	  }

	/* We've found a conditional branch that is unnecessary.

	   First, remove all outgoing edges from this block, updating
	   PHI nodes as appropriate.  */
	e = bb->succ;
	while (e)
	  {
	    edge temp = e;

	    e = e->succ_next;

	    if (temp->flags & EDGE_ABNORMAL)
	      continue;

	    /* We found an edge that is not executable.  First simplify
	       the PHI nodes in the target block.  */
	    if (temp->dest != EXIT_BLOCK_PTR)
	      {
		rtx insn = first_insn_after_basic_block_note (temp->dest);

		while (PHI_NODE_P (insn))
		  {
		    remove_phi_alternative (PATTERN (insn), temp->src);
		    insn = NEXT_INSN (insn);
		  }
	      }

	    remove_edge (temp);
	  }

	/* Create an edge from this block to the post dominator.  
	   What about the PHI nodes at the target?  */
	make_edge (bb, pdom_bb, 0);

	/* Third, transform this insn into an unconditional
	   jump to the label for the immediate postdominator.  */
	lbl = find_block_label (pdom_bb);
	SET_SRC (PATTERN (insn)) = gen_rtx_LABEL_REF (VOIDmode, lbl);
	INSN_CODE (insn) = -1;
	JUMP_LABEL (insn) = lbl;
	LABEL_NUSES (lbl)++;

	/* A barrier must follow any unconditional jump.  Barriers
	   are not in basic blocks so this must occur after
	   deleting the conditional jump.  */
	emit_barrier_after (insn);
      }
    else if (!JUMP_P (insn))
      delete_insn_bb (insn);
  });
  
  /* Remove fake edges from the CFG.  */
  remove_fake_edges ();

  /* Find any blocks with no successors and ensure they are followed
     by a BARRIER.  delete_insn has the nasty habit of deleting barriers
     when deleting insns.  */
  for (i = 0; i < n_basic_blocks; i++)
    {
      basic_block bb = BASIC_BLOCK (i);

      if (bb->succ == NULL)
	{
	  rtx next = NEXT_INSN (bb->end);

	  if (!next || GET_CODE (next) != BARRIER)
	    emit_barrier_after (bb->end);
	}
    }
  /* Release allocated memory.  */
  for (insn = get_insns (); insn != NULL_RTX; insn = NEXT_INSN (insn))
    RESURRECT_INSN (insn);
  if (VARRAY_ACTIVE_SIZE (unprocessed_instructions) != 0)
    abort ();
  VARRAY_FREE (unprocessed_instructions);
  control_dependent_block_to_edge_map_free (cdbte);
  free ((PTR) pdom);
  free_edge_list (el);
}
