/* Dead-code elimination pass for the GNU compiler.
- Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
Written by Jeffrey D. Oldham <oldham@codesourcery.com>.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC 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 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.
-GNU CC is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+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 GNU CC; see the file COPYING. If not, write to the Free
+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. */
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,
+ PARAMS ((struct edge_list *el, dominance_info pdom,
control_dependent_block_to_edge_map cdbte));
static void find_control_dependence
- PARAMS ((struct edge_list *el, int edge_index, int *pdom,
+ PARAMS ((struct edge_list *el, int edge_index, dominance_info pdom,
control_dependent_block_to_edge_map cdbte));
static basic_block find_pdom
- PARAMS ((int *pdom, basic_block block));
+ PARAMS ((dominance_info pdom, basic_block block));
static int inherently_necessary_register_1
PARAMS ((rtx *current_rtx, void *data));
static int inherently_necessary_register
static void
find_all_control_dependences (el, pdom, cdbte)
struct edge_list *el;
- int *pdom;
+ dominance_info pdom;
control_dependent_block_to_edge_map cdbte;
{
int i;
find_control_dependence (el, edge_index, pdom, cdbte)
struct edge_list *el;
int edge_index;
- int *pdom;
+ dominance_info pdom;
control_dependent_block_to_edge_map cdbte;
{
basic_block current_block;
abort ();
ending_block =
(INDEX_EDGE_PRED_BB (el, edge_index) == ENTRY_BLOCK_PTR)
- ? BASIC_BLOCK (0)
+ ? ENTRY_BLOCK_PTR->next_bb
: find_pdom (pdom, INDEX_EDGE_PRED_BB (el, edge_index));
for (current_block = INDEX_EDGE_SUCC_BB (el, edge_index);
static basic_block
find_pdom (pdom, block)
- int *pdom;
+ dominance_info pdom;
basic_block block;
{
if (!block)
abort ();
if (block == ENTRY_BLOCK_PTR)
- return BASIC_BLOCK (0);
- else if (block == EXIT_BLOCK_PTR || pdom[block->index] == EXIT_BLOCK)
+ return ENTRY_BLOCK_PTR->next_bb;
+ else if (block == EXIT_BLOCK_PTR)
return EXIT_BLOCK_PTR;
else
- return BASIC_BLOCK (pdom[block->index]);
+ {
+ basic_block bb = get_immediate_dominator (pdom, block);
+ if (!bb)
+ return EXIT_BLOCK_PTR;
+ return bb;
+ }
}
/* Determine if the given CURRENT_RTX uses a hard register not
rtx dest;
void *data;
{
- int *inherently_necessary_set_p = (int *)data;
+ int *inherently_necessary_set_p = (int *) data;
while (GET_CODE (dest) == SUBREG
|| GET_CODE (dest) == STRICT_LOW_PART
return !0;
else
switch (GET_CODE (x))
- {
+ {
case CALL_INSN:
case BARRIER:
+ case PREFETCH:
return !0;
case CODE_LABEL:
case NOTE:
}
default:
/* Found an impossible insn type. */
- abort();
+ abort ();
break;
}
}
delete_insn_bb (insn)
rtx insn;
{
- basic_block bb;
if (!insn)
abort ();
if (! INSN_P (insn))
return;
- bb = BLOCK_FOR_INSN (insn);
- if (!bb)
- abort ();
- if (bb->head == bb->end)
- {
- /* Delete the insn by converting it to a note. */
- PUT_CODE (insn, NOTE);
- NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
- return;
- }
- else if (insn == bb->head)
- bb->head = NEXT_INSN (insn);
- else if (insn == bb->end)
- bb->end = PREV_INSN (insn);
delete_insn (insn);
}
\f
void
ssa_eliminate_dead_code ()
{
- int i;
rtx insn;
+ basic_block bb;
/* 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;
+ dominance_info 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);
+ cdbte = control_dependent_block_to_edge_map_create (last_basic_block);
/* 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();
+ pdom = calculate_dominance_info (CDI_POST_DOMINATORS);
+ el = create_edge_list ();
find_all_control_dependences (el, pdom, cdbte);
/* Find inherently necessary instructions. */
remove_edge (temp);
}
- /* Create an edge from this block to the post dominator.
+ /* Create an edge from this block to the post dominator.
What about the PHI nodes at the target? */
- make_edge (NULL, bb, pdom_bb, 0);
+ make_edge (bb, pdom_bb, 0);
/* Third, transform this insn into an unconditional
jump to the label for the immediate postdominator. */
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++)
+ FOR_EACH_BB (bb)
{
- basic_block bb = BASIC_BLOCK (i);
-
if (bb->succ == NULL)
{
rtx next = NEXT_INSN (bb->end);
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);