This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
More cfg*.c cleanups
- From: kenner at vlsi1 dot ultra dot nyu dot edu (Richard Kenner)
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 24 Dec 01 10:46:14 EST
- Subject: More cfg*.c cleanups
Again, nothing functional and tested on alphaebv56-dec-osf4.0c.
Mon Dec 24 10:24:59 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* rtl.h (in_expr_list_p): New declaration.
* rtlanal.c (in_expr_list_p): New function.
* cfgcleanup.c: Reformatting and minor code rearrangement.
* cfglayout.c, cfgloop.c, cfgrtl.c: Likewise.
*** cfgcleanup.c 2001/12/20 17:01:25 1.27
--- cfgcleanup.c 2001/12/24 14:32:28
*************** Software Foundation, 59 Temple Place - S
*** 48,52 ****
/* cleanup_cfg maintains following flags for each basic block. */
! enum bb_flags {
/* Set if life info needs to be recomputed for given BB. */
BB_UPDATE_LIFE = 1,
--- 48,54 ----
/* cleanup_cfg maintains following flags for each basic block. */
!
! enum bb_flags
! {
/* Set if life info needs to be recomputed for given BB. */
BB_UPDATE_LIFE = 1,
*************** enum bb_flags {
*** 54,66 ****
forwarder_block_p calls. */
BB_FORWARDER_BLOCK = 2
! };
! #define BB_FLAGS(bb) (enum bb_flags)(bb)->aux
! #define BB_SET_FLAG(bb,flag) \
! (bb)->aux = (void *) (long) ((enum bb_flags)(bb)->aux | (flag))
! #define BB_CLEAR_FLAG(bb,flag) \
! (bb)->aux = (void *) (long) ((enum bb_flags)(bb)->aux & ~(flag))
! #define FORWARDER_BLOCK_P(bb) (BB_FLAGS(bb) & BB_FORWARDER_BLOCK)
static bool try_crossjump_to_edge PARAMS ((int, edge, edge));
--- 56,68 ----
forwarder_block_p calls. */
BB_FORWARDER_BLOCK = 2
! };
! #define BB_FLAGS(BB) (enum bb_flags) (BB)->aux
! #define BB_SET_FLAG(BB, FLAG) \
! (BB)->aux = (void *) (long) ((enum bb_flags) (BB)->aux | (FLAG))
! #define BB_CLEAR_FLAG(BB, FLAG) \
! (BB)->aux = (void *) (long) ((enum bb_flags) (BB)->aux & ~(FLAG))
! #define FORWARDER_BLOCK_P(BB) (BB_FLAGS (BB) & BB_FORWARDER_BLOCK)
static bool try_crossjump_to_edge PARAMS ((int, edge, edge));
*************** notice_new_block (bb)
*** 97,100 ****
--- 99,103 ----
if (!bb)
return;
+
BB_SET_FLAG (bb, BB_UPDATE_LIFE);
if (forwarder_block_p (bb))
*************** try_simplify_condjump (cbranch_block)
*** 184,187 ****
--- 187,191 ----
/* Attempt to prove that operation is NOOP using CSElib or mark the effect
on register. Used by jump threading. */
+
static bool
mark_effect (exp, nonequal)
*************** mark_effect (exp, nonequal)
*** 197,200 ****
--- 201,205 ----
CLEAR_REGNO_REG_SET (nonequal, REGNO (XEXP (exp, 0)));
return false;
+
case SET:
if (rtx_equal_for_cselib_p (SET_DEST (exp), SET_SRC (exp)))
*************** mark_effect (exp, nonequal)
*** 204,207 ****
--- 209,213 ----
SET_REGNO_REG_SET (nonequal, REGNO (SET_SRC (exp)));
return false;
+
default:
return false;
*************** thread_jump (mode, e, b)
*** 282,289 ****
nonequal = BITMAP_XMALLOC();
CLEAR_REG_SET (nonequal);
/* Now assume that we've continued by the edge E to B and continue
processing as if it were same basic block.
-
Our goal is to prove that whole block is an NOOP. */
for (insn = NEXT_INSN (b->head); insn != b->end && !failed;
insn = NEXT_INSN (insn))
--- 288,296 ----
nonequal = BITMAP_XMALLOC();
CLEAR_REG_SET (nonequal);
+
/* Now assume that we've continued by the edge E to B and continue
processing as if it were same basic block.
Our goal is to prove that whole block is an NOOP. */
+
for (insn = NEXT_INSN (b->head); insn != b->end && !failed;
insn = NEXT_INSN (insn))
*************** thread_jump (mode, e, b)
*** 301,304 ****
--- 308,312 ----
failed |= mark_effect (pat, nonequal);
}
+
cselib_process_insn (insn);
}
*************** try_forward_edges (mode, b)
*** 341,345 ****
edge e, next, threaded_edge;
! for (e = b->succ; e ; e = next)
{
basic_block target, first;
--- 349,353 ----
edge e, next, threaded_edge;
! for (e = b->succ; e; e = next)
{
basic_block target, first;
*************** try_forward_edges (mode, b)
*** 373,376 ****
--- 381,385 ----
new_target = target->succ->dest;
}
+
/* Allow to thread only over one edge at time to simplify updating
of probabilities. */
*************** try_forward_edges (mode, b)
*** 384,387 ****
--- 393,397 ----
}
}
+
if (!new_target)
break;
*************** try_forward_edges (mode, b)
*** 401,405 ****
insn = NEXT_INSN (insn);
! for (;insn && GET_CODE (insn) != CODE_LABEL && !INSN_P (insn);
insn = NEXT_INSN (insn))
if (GET_CODE (insn) == NOTE
--- 411,415 ----
insn = NEXT_INSN (insn);
! for (; insn && GET_CODE (insn) != CODE_LABEL && !INSN_P (insn);
insn = NEXT_INSN (insn))
if (GET_CODE (insn) == NOTE
*************** try_forward_edges (mode, b)
*** 410,413 ****
--- 420,424 ----
break;
}
+
counter++;
target = new_target;
*************** try_forward_edges (mode, b)
*** 439,446 ****
{
if (rtl_dump_file)
! fprintf (rtl_dump_file, "Forwarding edge %i->%i to %i failed.\n",
b->index, e->dest->index, target->index);
continue;
}
/* We successfully forwarded the edge. Now update profile
data: for each edge we traversed in the chain, remove
--- 450,459 ----
{
if (rtl_dump_file)
! fprintf (rtl_dump_file,
! "Forwarding edge %i->%i to %i failed.\n",
b->index, e->dest->index, target->index);
continue;
}
+
/* We successfully forwarded the edge. Now update profile
data: for each edge we traversed in the chain, remove
*************** try_forward_edges (mode, b)
*** 457,460 ****
--- 470,474 ----
{
edge t;
+
first->count -= edge_count;
first->succ->count -= edge_count;
*************** try_forward_edges (mode, b)
*** 464,467 ****
--- 478,482 ----
else
t = first->succ;
+
first = t->dest;
}
*************** merge_blocks_move_predecessor_nojumps (a
*** 554,561 ****
if (rtl_dump_file)
! {
! fprintf (rtl_dump_file, "Moved block %d before %d and merged.\n",
! a->index, b->index);
! }
/* Swap the records for the two blocks around. Although we are deleting B,
--- 569,574 ----
if (rtl_dump_file)
! fprintf (rtl_dump_file, "Moved block %d before %d and merged.\n",
! a->index, b->index);
/* Swap the records for the two blocks around. Although we are deleting B,
*************** merge_blocks_move_successor_nojumps (a,
*** 624,631 ****
if (rtl_dump_file)
! {
! fprintf (rtl_dump_file, "Moved block %d after %d and merged.\n",
! b->index, a->index);
! }
}
--- 637,642 ----
if (rtl_dump_file)
! fprintf (rtl_dump_file, "Moved block %d after %d and merged.\n",
! b->index, a->index);
}
*************** merge_blocks (e, b, c, mode)
*** 661,671 ****
if (rtl_dump_file)
! {
! fprintf (rtl_dump_file, "Merged %d and %d without moving.\n",
! b->index, c->index);
! }
return true;
}
/* Otherwise we will need to move code around. Do that only if expensive
transformations are allowed. */
--- 672,681 ----
if (rtl_dump_file)
! fprintf (rtl_dump_file, "Merged %d and %d without moving.\n",
! b->index, c->index);
return true;
}
+
/* Otherwise we will need to move code around. Do that only if expensive
transformations are allowed. */
*************** merge_blocks (e, b, c, mode)
*** 690,693 ****
--- 700,704 ----
if (tmp_edge->flags & EDGE_FALLTHRU)
break;
+
c_has_outgoing_fallthru = (tmp_edge != NULL);
*************** merge_blocks (e, b, c, mode)
*** 695,698 ****
--- 706,710 ----
if (tmp_edge->flags & EDGE_FALLTHRU)
break;
+
b_has_incoming_fallthru = (tmp_edge != NULL);
b_fallthru_edge = tmp_edge;
*************** merge_blocks (e, b, c, mode)
*** 715,718 ****
--- 727,731 ----
{
basic_block bb;
+
if (b_fallthru_edge->src == ENTRY_BLOCK_PTR)
return false;
*************** merge_blocks (e, b, c, mode)
*** 723,729 ****
--- 736,744 ----
BB_SET_FLAG (b_fallthru_edge->src, BB_UPDATE_LIFE);
}
+
merge_blocks_move_predecessor_nojumps (b, c);
return true;
}
+
return false;
}
*************** insns_match_p (mode, i1, i2)
*** 826,831 ****
--- 841,848 ----
}
}
+
return false;
}
+
return true;
}
*************** flow_find_cross_jump (mode, bb1, bb2, f1
*** 858,861 ****
--- 875,879 ----
i1 = PREV_INSN (i1);
}
+
i2 = bb2->end;
if (onlyjump_p (i2)
*************** flow_find_cross_jump (mode, bb1, bb2, f1
*** 874,877 ****
--- 892,896 ----
while (!active_insn_p (i1) && i1 != bb1->head)
i1 = PREV_INSN (i1);
+
while (!active_insn_p (i2) && i2 != bb2->head)
i2 = PREV_INSN (i2);
*************** flow_find_cross_jump (mode, bb1, bb2, f1
*** 906,909 ****
--- 925,929 ----
ninsns++;
}
+
i1 = PREV_INSN (i1);
i2 = PREV_INSN (i2);
*************** flow_find_cross_jump (mode, bb1, bb2, f1
*** 911,921 ****
#ifdef HAVE_cc0
! if (ninsns)
! {
! /* Don't allow the insn after a compare to be shared by
! cross-jumping unless the compare is also shared. */
! if (reg_mentioned_p (cc0_rtx, last1) && ! sets_cc0_p (last1))
! last1 = afterlast1, last2 = afterlast2, ninsns--;
! }
#endif
--- 931,938 ----
#ifdef HAVE_cc0
! /* Don't allow the insn after a compare to be shared by
! cross-jumping unless the compare is also shared. */
! if (ninsns && reg_mentioned_p (cc0_rtx, last1) && ! sets_cc0_p (last1))
! last1 = afterlast1, last2 = afterlast2, ninsns--;
#endif
*************** flow_find_cross_jump (mode, bb1, bb2, f1
*** 927,934 ****
--- 944,954 ----
while (last1 != bb1->head && !active_insn_p (PREV_INSN (last1)))
last1 = PREV_INSN (last1);
+
if (last1 != bb1->head && GET_CODE (PREV_INSN (last1)) == CODE_LABEL)
last1 = PREV_INSN (last1);
+
while (last2 != bb2->head && !active_insn_p (PREV_INSN (last2)))
last2 = PREV_INSN (last2);
+
if (last2 != bb2->head && GET_CODE (PREV_INSN (last2)) == CODE_LABEL)
last2 = PREV_INSN (last2);
*************** outgoing_edges_match (mode, bb1, bb2)
*** 961,970 ****
if (bb1->succ && !bb1->succ->succ_next
&& !(bb1->succ->flags & (EDGE_COMPLEX | EDGE_FAKE)))
! {
! if (! bb2->succ || bb2->succ->succ_next
! || (bb2->succ->flags & (EDGE_COMPLEX | EDGE_FAKE)))
! return false;
! return true;
! }
/* Match conditional jumps - this may get tricky when fallthru and branch
--- 981,986 ----
if (bb1->succ && !bb1->succ->succ_next
&& !(bb1->succ->flags & (EDGE_COMPLEX | EDGE_FAKE)))
! return (bb2->succ && !bb2->succ->succ_next
! && (bb2->succ->flags & (EDGE_COMPLEX | EDGE_FAKE)) == 0);
/* Match conditional jumps - this may get tricky when fallthru and branch
*************** outgoing_edges_match (mode, bb1, bb2)
*** 997,1000 ****
--- 1013,1017 ----
if (FORWARDER_BLOCK_P (f1->dest))
f1 = f1->dest->succ;
+
if (FORWARDER_BLOCK_P (f2->dest))
f2 = f2->dest->succ;
*************** outgoing_edges_match (mode, bb1, bb2)
*** 1029,1032 ****
--- 1046,1050 ----
else
code2 = GET_CODE (cond2);
+
if (code2 == UNKNOWN)
return false;
*************** outgoing_edges_match (mode, bb1, bb2)
*** 1053,1056 ****
--- 1071,1075 ----
rtx note1, note2;
int prob1, prob2;
+
note1 = find_reg_note (bb1->end, REG_BR_PROB, 0);
note2 = find_reg_note (bb2->end, REG_BR_PROB, 0);
*************** outgoing_edges_match (mode, bb1, bb2)
*** 1068,1071 ****
--- 1087,1091 ----
return false;
}
+
else if (note1 || note2)
return false;
*************** outgoing_edges_match (mode, bb1, bb2)
*** 1097,1102 ****
--- 1117,1124 ----
if (e1->flags & EDGE_EH)
nehedges1++;
+
if (e2->flags & EDGE_EH)
nehedges2++;
+
if (e1->flags & EDGE_FALLTHRU)
fallthru1 = e1;
*************** outgoing_edges_match (mode, bb1, bb2)
*** 1104,1113 ****
fallthru2 = e2;
}
/* If number of edges of various types does not match, fail. */
! if (e1 || e2)
! return false;
! if (nehedges1 != nehedges2)
! return false;
! if ((fallthru1 != 0) != (fallthru2 != 0))
return false;
--- 1126,1134 ----
fallthru2 = e2;
}
+
/* If number of edges of various types does not match, fail. */
! if (e1 || e2
! || nehedges1 != nehedges2
! || (fallthru1 != 0) != (fallthru2 != 0))
return false;
*************** outgoing_edges_match (mode, bb1, bb2)
*** 1119,1125 ****
--- 1140,1148 ----
basic_block d2 = (forwarder_block_p (fallthru2->dest)
? fallthru2->dest->succ->dest: fallthru2->dest);
+
if (d1 != d2)
return false;
}
+
/* In case we do have EH edges, ensure we are in the same region. */
if (nehedges1)
*************** outgoing_edges_match (mode, bb1, bb2)
*** 1127,1133 ****
--- 1150,1158 ----
rtx n1 = find_reg_note (bb1->end, REG_EH_REGION, 0);
rtx n2 = find_reg_note (bb2->end, REG_EH_REGION, 0);
+
if (XEXP (n1, 0) != XEXP (n2, 0))
return false;
}
+
/* We don't need to match the rest of edges as above checks should be enought
to ensure that they are equivalent. */
*************** try_crossjump_to_edge (mode, e1, e2)
*** 1160,1174 ****
&& !src1->pred->pred_next
&& FORWARDER_BLOCK_P (src1))
! {
! e1 = src1->pred;
! src1 = e1->src;
! }
if (src2->pred
&& !src2->pred->pred_next
&& FORWARDER_BLOCK_P (src2))
! {
! e2 = src2->pred;
! src2 = e2->src;
! }
/* Nothing to do if we reach ENTRY, or a common source block. */
--- 1185,1194 ----
&& !src1->pred->pred_next
&& FORWARDER_BLOCK_P (src1))
! e1 = src1->pred, src1 = e1->src;
!
if (src2->pred
&& !src2->pred->pred_next
&& FORWARDER_BLOCK_P (src2))
! e2 = src2->pred, src2 = e2->src;
/* Nothing to do if we reach ENTRY, or a common source block. */
*************** try_crossjump_to_edge (mode, e1, e2)
*** 1182,1185 ****
--- 1202,1206 ----
&& FORWARDER_BLOCK_P (e1->dest->succ->dest))
return false;
+
if (FORWARDER_BLOCK_P (e2->dest)
&& FORWARDER_BLOCK_P (e2->dest->succ->dest))
*************** try_crossjump_to_edge (mode, e1, e2)
*** 1227,1230 ****
--- 1248,1252 ----
if (FORWARDER_BLOCK_P (d))
d = d->succ->dest;
+
for (s2 = src1->succ; ; s2 = s2->succ_next)
{
*************** try_crossjump_to_edge (mode, e1, e2)
*** 1235,1238 ****
--- 1257,1261 ----
break;
}
+
s->count += s2->count;
*************** try_crossjump_to_edge (mode, e1, e2)
*** 1246,1249 ****
--- 1269,1273 ----
s->dest->frequency += EDGE_FREQUENCY (s);
}
+
if (FORWARDER_BLOCK_P (s2->dest))
{
*************** try_crossjump_to_edge (mode, e1, e2)
*** 1252,1262 ****
s2->dest->frequency -= EDGE_FREQUENCY (s);
}
if (!redirect_to->frequency && !src1->frequency)
s->probability = (s->probability + s2->probability) / 2;
else
! s->probability =
! ((s->probability * redirect_to->frequency +
! s2->probability * src1->frequency)
! / (redirect_to->frequency + src1->frequency));
}
--- 1276,1287 ----
s2->dest->frequency -= EDGE_FREQUENCY (s);
}
+
if (!redirect_to->frequency && !src1->frequency)
s->probability = (s->probability + s2->probability) / 2;
else
! s->probability
! = ((s->probability * redirect_to->frequency +
! s2->probability * src1->frequency)
! / (redirect_to->frequency + src1->frequency));
}
*************** try_crossjump_to_edge (mode, e1, e2)
*** 1270,1273 ****
--- 1295,1299 ----
if (GET_CODE (newpos1) == CODE_LABEL)
newpos1 = NEXT_INSN (newpos1);
+
if (GET_CODE (newpos1) == NOTE)
newpos1 = NEXT_INSN (newpos1);
*************** try_optimize_cfg (mode)
*** 1410,1414 ****
has only one successor, and the successor has only one predecessor,
they may be combined. */
-
do
{
--- 1436,1439 ----
*************** try_optimize_cfg (mode)
*** 1432,1435 ****
--- 1457,1461 ----
if (rtl_dump_file)
fprintf (rtl_dump_file, "Deleting block %i.\n", b->index);
+
flow_delete_block (b);
changed = true;
*************** try_optimize_cfg (mode)
*** 1456,1459 ****
--- 1482,1486 ----
{
rtx label = b->head;
+
b->head = NEXT_INSN (b->head);
delete_insn_chain (label, label);
*************** try_optimize_cfg (mode)
*** 1476,1479 ****
--- 1503,1507 ----
fprintf (rtl_dump_file, "Deleting fallthru block %i.\n",
b->index);
+
c = BASIC_BLOCK (b->index ? b->index - 1 : 1);
redirect_edge_succ_nodup (b->pred, b->succ->dest);
*************** try_optimize_cfg (mode)
*** 1555,1558 ****
--- 1583,1587 ----
{
bool found = 0;
+
blocks = sbitmap_alloc (n_basic_blocks);
sbitmap_zero (blocks);
*************** try_optimize_cfg (mode)
*** 1563,1566 ****
--- 1592,1596 ----
SET_BIT (blocks, i);
}
+
if (found)
update_life_info (blocks, UPDATE_LIFE_GLOBAL,
*************** try_optimize_cfg (mode)
*** 1569,1572 ****
--- 1599,1603 ----
sbitmap_free (blocks);
}
+
for (i = 0; i < n_basic_blocks; i++)
BASIC_BLOCK (i)->aux = NULL;
*** cfglayout.c 2001/11/16 20:15:26 1.4
--- cfglayout.c 2001/12/24 14:32:36
***************
*** 2,21 ****
Copyright (C) 2000, 2001 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 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. */
#include "config.h"
--- 2,21 ----
Copyright (C) 2000, 2001 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 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. */
#include "config.h"
***************
*** 31,37 ****
/* The contents of the current function definition are allocated
! in this obstack, and all are freed at the end of the function.
! For top-level functions, this is temporary_obstack.
! Separate obstacks are made for nested functions. */
extern struct obstack flow_obstack;
--- 31,35 ----
/* The contents of the current function definition are allocated
! in this obstack, and all are freed at the end of the function. */
extern struct obstack flow_obstack;
*************** skip_insns_after_block (bb)
*** 127,131 ****
next_head = BASIC_BLOCK (bb->index + 1)->head;
! for (last_insn = insn = bb->end; (insn = NEXT_INSN (insn)); )
{
if (insn == next_head)
--- 125,129 ----
next_head = BASIC_BLOCK (bb->index + 1)->head;
! for (last_insn = insn = bb->end; (insn = NEXT_INSN (insn)) != 0; )
{
if (insn == next_head)
*************** skip_insns_after_block (bb)
*** 173,177 ****
break;
}
! /* It is possible to hit contradicting sequence. For instance:
jump_insn
--- 171,176 ----
break;
}
!
! /* It is possible to hit contradictory sequence. For instance:
jump_insn
*************** skip_insns_after_block (bb)
*** 179,200 ****
barrier
! Where barrier belongs to jump_insn, but the note does not.
! This can be created by removing the basic block originally
! following NOTE_INSN_LOOP_BEG.
- In such case reorder the notes. */
for (insn = last_insn; insn != bb->end; insn = prev)
{
! prev = PREV_INSN (insn);
! if (GET_CODE (insn) == NOTE)
! switch (NOTE_LINE_NUMBER (insn))
! {
case NOTE_INSN_LOOP_END:
case NOTE_INSN_BLOCK_END:
case NOTE_INSN_DELETED:
case NOTE_INSN_DELETED_LABEL:
! continue;
default:
! reorder_insns (insn, insn, last_insn);
}
}
--- 178,198 ----
barrier
! Where barrier belongs to jump_insn, but the note does not. This can be
! created by removing the basic block originally following
! NOTE_INSN_LOOP_BEG. In such case reorder the notes. */
for (insn = last_insn; insn != bb->end; insn = prev)
{
! prev = PREV_INSN (insn);
! if (GET_CODE (insn) == NOTE)
! switch (NOTE_LINE_NUMBER (insn))
! {
case NOTE_INSN_LOOP_END:
case NOTE_INSN_BLOCK_END:
case NOTE_INSN_DELETED:
case NOTE_INSN_DELETED_LABEL:
! continue;
default:
! reorder_insns (insn, insn, last_insn);
}
}
*************** label_for_bb (bb)
*** 214,219 ****
{
if (rtl_dump_file)
! fprintf (rtl_dump_file, "Emitting label for block %d\n",
! bb->index);
label = block_label (bb);
--- 212,216 ----
{
if (rtl_dump_file)
! fprintf (rtl_dump_file, "Emitting label for block %d\n", bb->index);
label = block_label (bb);
*************** record_effective_endpoints ()
*** 234,238 ****
int i;
! for (i = 0; i < n_basic_blocks; ++i)
{
basic_block bb = BASIC_BLOCK (i);
--- 231,235 ----
int i;
! for (i = 0; i < n_basic_blocks; i++)
{
basic_block bb = BASIC_BLOCK (i);
*************** record_effective_endpoints ()
*** 244,273 ****
next_insn = NEXT_INSN (end);
}
function_tail_eff_head = next_insn;
}
static rtx
get_next_bb_note (x)
rtx x;
{
! while (x)
! {
! if (NOTE_INSN_BASIC_BLOCK_P (x))
! return x;
! x = NEXT_INSN (x);
! }
return NULL;
}
static rtx
get_prev_bb_note (x)
rtx x;
{
! while (x)
! {
! if (NOTE_INSN_BASIC_BLOCK_P (x))
! return x;
! x = PREV_INSN (x);
! }
return NULL;
}
--- 241,271 ----
next_insn = NEXT_INSN (end);
}
+
function_tail_eff_head = next_insn;
}
+ /* Return the next NOTE_INSN_BASIC_BLOCK after X. */
+
static rtx
get_next_bb_note (x)
rtx x;
{
! for (; x; x = NEXT_INSN (x))
! if (NOTE_INSN_BASIC_BLOCK_P (x))
! return x;
!
return NULL;
}
+ /* Return the fist NOTE_INSN_BASIC_BLOCK before X. */
+
static rtx
get_prev_bb_note (x)
rtx x;
{
! for (; x; x = PREV_INSN (x))
! if (NOTE_INSN_BASIC_BLOCK_P (x))
! return x;
!
return NULL;
}
*************** relate_bbs_with_scopes (s)
*** 314,317 ****
--- 312,316 ----
if (! bbnote)
abort ();
+
if (NOTE_BASIC_BLOCK (bbnote) == s->bb_end)
{
*************** relate_bbs_with_scopes (s)
*** 336,339 ****
--- 335,339 ----
if (! bbnote)
abort ();
+
if (NOTE_BASIC_BLOCK (bbnote) == s->bb_beg)
{
*************** relate_bbs_with_scopes (s)
*** 358,362 ****
else
{
- rtx x1, x2;
/* Both notes are outside of any bbs. This implies that all the
basic blocks spanned by the pair of notes are contained in
--- 358,361 ----
*************** relate_bbs_with_scopes (s)
*** 365,371 ****
span any basic blocks, then it is an empty scope that can
safely be deleted or ignored. Mark these with level = -1. */
- x1 = get_next_bb_note (s->note_beg);
- x2 = get_prev_bb_note (s->note_end);
if (! (x1 && x2))
{
--- 364,370 ----
span any basic blocks, then it is an empty scope that can
safely be deleted or ignored. Mark these with level = -1. */
+ rtx x1 = get_next_bb_note (s->note_beg);
+ rtx x2 = get_prev_bb_note (s->note_end);
if (! (x1 && x2))
{
*************** make_new_scope (level, note)
*** 419,422 ****
--- 418,422 ----
{
scope new_scope = xcalloc (1, sizeof (struct scope_def));
+
new_scope->level = level;
new_scope->note_beg = note;
*************** build_scope_forest (forest)
*** 443,446 ****
--- 443,447 ----
curr_bb = NULL;
bbi = 0;
+
for (x = get_insns (); x; x = NEXT_INSN (x))
{
*************** build_scope_forest (forest)
*** 455,460 ****
--- 456,463 ----
{
scope new_scope;
+
if (! curr_scope)
abort();
+
level++;
new_scope = make_new_scope (level, x);
*************** build_scope_forest (forest)
*** 472,479 ****
--- 475,484 ----
}
curr_scope = curr_scope->inner_last;
+
}
else
{
int ntrees = forest->num_trees;
+
level++;
curr_scope = make_new_scope (level, x);
*************** build_scope_forest (forest)
*** 483,486 ****
--- 488,492 ----
forest->trees[forest->num_trees++] = root;
}
+
curr_scope->bb_beg = curr_bb;
}
*************** build_scope_forest (forest)
*** 494,498 ****
root = NULL;
}
! } /* if note */
if (curr_bb && curr_bb->end == x)
--- 500,504 ----
root = NULL;
}
! }
if (curr_bb && curr_bb->end == x)
*************** build_scope_forest (forest)
*** 501,506 ****
bbi++;
}
!
! } /* for */
for (i = 0; i < forest->num_trees; i++)
--- 507,511 ----
bbi++;
}
! }
for (i = 0; i < forest->num_trees; i++)
*************** build_scope_forest (forest)
*** 508,513 ****
}
! /* Remove all the NOTE_INSN_BLOCK_BEG and NOTE_INSN_BLOCK_END notes from
! the insn chain. */
static void
--- 513,518 ----
}
! /* Remove all NOTE_INSN_BLOCK_BEG and NOTE_INSN_BLOCK_END notes from the insn
! chain. */
static void
*************** insert_intra_1 (s, ip, bb)
*** 573,577 ****
}
-
/* Insert NOTE_INSN_BLOCK_END notes and NOTE_INSN_BLOCK_BEG notes for
scopes that are contained within BB. */
--- 578,581 ----
*************** insert_intra_bb_scope_notes (bb)
*** 599,603 ****
}
-
/* Given two consecutive basic blocks BB1 and BB2 with different scopes,
insert NOTE_INSN_BLOCK_END notes after BB1 and NOTE_INSN_BLOCK_BEG
--- 603,606 ----
*************** insert_inter_bb_scope_notes (bb1, bb2)
*** 620,625 ****
--- 623,630 ----
scope s1 = RBI (bb1)->scope;
scope s2 = RBI (bb2)->scope;
+
if (! s1 && ! s2)
return;
+
if (! s1)
bb1 = NULL;
*************** insert_inter_bb_scope_notes (bb1, bb2)
*** 633,640 ****
scope s1 = RBI (bb1)->scope;
scope s2 = RBI (bb2)->scope;
while (s1 != s2)
{
- if (! (s1 && s2))
- abort ();
if (s1->level > s2->level)
s1 = s1->outer;
--- 638,644 ----
scope s1 = RBI (bb1)->scope;
scope s2 = RBI (bb2)->scope;
+
while (s1 != s2)
{
if (s1->level > s2->level)
s1 = s1->outer;
*************** insert_inter_bb_scope_notes (bb1, bb2)
*** 647,650 ****
--- 651,655 ----
}
}
+
com = s1;
}
*************** insert_inter_bb_scope_notes (bb1, bb2)
*** 656,671 ****
{
rtx end = bb1->end;
- scope s = RBI (bb1)->scope;
ip = RBI (bb1)->eff_end;
! while (s != com)
! {
! if (NOTE_BLOCK (s->note_beg))
! {
! ip = emit_note_after (NOTE_INSN_BLOCK_END, ip);
! NOTE_BLOCK (ip) = NOTE_BLOCK (s->note_end);
! }
! s = s->outer;
! }
/* Emitting note may move the end of basic block to unwanted place. */
bb1->end = end;
--- 661,674 ----
{
rtx end = bb1->end;
+ scope s;
ip = RBI (bb1)->eff_end;
! for (s = RBI (bb1)->scope; s != com; s = s->outer)
! if (NOTE_BLOCK (s->note_beg))
! {
! ip = emit_note_after (NOTE_INSN_BLOCK_END, ip);
! NOTE_BLOCK (ip) = NOTE_BLOCK (s->note_end);
! }
!
/* Emitting note may move the end of basic block to unwanted place. */
bb1->end = end;
*************** insert_inter_bb_scope_notes (bb1, bb2)
*** 675,689 ****
if (bb2)
{
! scope s = RBI (bb2)->scope;
ip = bb2->head;
! while (s != com)
! {
! if (NOTE_BLOCK (s->note_beg))
! {
! ip = emit_note_before (NOTE_INSN_BLOCK_BEG, ip);
! NOTE_BLOCK (ip) = NOTE_BLOCK (s->note_beg);
! }
! s = s->outer;
! }
}
}
--- 678,690 ----
if (bb2)
{
! scope s;
!
ip = bb2->head;
! for (s = RBI (bb2)->scope; s != com; s = s->outer)
! if (NOTE_BLOCK (s->note_beg))
! {
! ip = emit_note_before (NOTE_INSN_BLOCK_BEG, ip);
! NOTE_BLOCK (ip) = NOTE_BLOCK (s->note_beg);
! }
}
}
*************** rebuild_scope_notes (forest)
*** 710,713 ****
--- 711,715 ----
basic_block bb1 = BASIC_BLOCK (i);
basic_block bb2 = BASIC_BLOCK (i + 1);
+
if (RBI (bb1)->scope != RBI (bb2)->scope)
insert_inter_bb_scope_notes (bb1, bb2);
*************** free_scope_forest (forest)
*** 746,749 ****
--- 748,752 ----
{
int i;
+
for (i = 0; i < forest->num_trees; i++)
free_scope_forest_1 (forest->trees[i]);
*************** dump_scope_forest (forest)
*** 756,768 ****
scope_forest_info *forest;
{
if (forest->num_trees == 0)
fprintf (stderr, "\n< Empty scope forest >\n");
else
! {
! int i;
! fprintf (stderr, "\n< Scope forest >\n");
! for (i = 0; i < forest->num_trees; i++)
! dump_scope_forest_1 (forest->trees[i], 0);
! }
}
--- 759,771 ----
scope_forest_info *forest;
{
+ int i;
+
if (forest->num_trees == 0)
fprintf (stderr, "\n< Empty scope forest >\n");
else
! fprintf (stderr, "\n< Scope forest >\n");
!
! for (i = 0; i < forest->num_trees; i++)
! dump_scope_forest_1 (forest->trees[i], 0);
}
*************** fixup_reorder_chain ()
*** 814,821 ****
the needed changes to jumps and labels. */
! last_bb = BASIC_BLOCK (0);
! bb = RBI (last_bb)->next;
! index = 1;
! while (bb)
{
rtx last_e = RBI (last_bb)->eff_end;
--- 817,823 ----
the needed changes to jumps and labels. */
! for (last_bb = BASIC_BLOCK (0), bb = RBI (last_bb)->next, index = 1;
! bb != 0;
! last_bb = bb, bb = RBI (bb)->next, index++)
{
rtx last_e = RBI (last_bb)->eff_end;
*************** fixup_reorder_chain ()
*** 824,831 ****
NEXT_INSN (last_e) = curr_h;
PREV_INSN (curr_h) = last_e;
-
- last_bb = bb;
- bb = RBI (bb)->next;
- index++;
}
--- 826,829 ----
*************** fixup_reorder_chain ()
*** 834,838 ****
insn = RBI (last_bb)->eff_end;
-
NEXT_INSN (insn) = function_tail_eff_head;
if (function_tail_eff_head)
--- 832,835 ----
*************** fixup_reorder_chain ()
*** 841,844 ****
--- 838,842 ----
while (NEXT_INSN (insn))
insn = NEXT_INSN (insn);
+
set_last_insn (insn);
#ifdef ENABLE_CHECKING
*************** fixup_reorder_chain ()
*** 885,888 ****
--- 883,887 ----
{
rtx note = find_reg_note (bb_end_insn, REG_BR_PROB, 0);
+
if (note
&& INTVAL (XEXP (note, 0)) < REG_BR_PROB_BASE / 2
*************** fixup_reorder_chain ()
*** 914,917 ****
--- 913,917 ----
if (! e_fall)
continue;
+
#ifdef CASE_DROPS_THROUGH
/* Except for VAX. Since we didn't have predication for the
*************** fixup_reorder_chain ()
*** 937,941 ****
continue;
! /* An fallthru to exit block. */
if (!RBI (bb)->next && e_fall->dest == EXIT_BLOCK_PTR)
continue;
--- 937,941 ----
continue;
! /* A fallthru to exit block. */
if (!RBI (bb)->next && e_fall->dest == EXIT_BLOCK_PTR)
continue;
*************** fixup_reorder_chain ()
*** 943,949 ****
/* We got here if we need to add a new jump insn. */
-
nb = force_nonfallthru (e_fall);
-
if (nb)
{
--- 943,947 ----
*************** fixup_reorder_chain ()
*** 966,970 ****
if (rtl_dump_file)
fprintf (rtl_dump_file, "Reordered sequence:\n");
! while (bb)
{
if (rtl_dump_file)
--- 964,969 ----
if (rtl_dump_file)
fprintf (rtl_dump_file, "Reordered sequence:\n");
!
! for (; bb; bb = RBI (bb)->next, index++)
{
if (rtl_dump_file)
*************** fixup_reorder_chain ()
*** 973,981 ****
bb->index,
bb->frequency);
bb->index = index;
BASIC_BLOCK (index) = bb;
-
- bb = RBI (bb)->next;
- index++;
}
}
--- 972,978 ----
bb->index,
bb->frequency);
+
bb->index = index;
BASIC_BLOCK (index) = bb;
}
}
*************** void
*** 990,1049 ****
verify_insn_chain ()
{
! rtx x,
! prevx,
! nextx;
! int insn_cnt1,
! insn_cnt2;
! prevx = NULL;
! insn_cnt1 = 1;
! for (x = get_insns (); x; x = NEXT_INSN (x))
! {
! if (PREV_INSN (x) != prevx)
! {
! fprintf (stderr, "Forward traversal: insn chain corrupt.\n");
! fprintf (stderr, "previous insn:\n");
! debug_rtx (prevx);
! fprintf (stderr, "current insn:\n");
! debug_rtx (x);
! abort ();
! }
! ++insn_cnt1;
! prevx = x;
! }
if (prevx != get_last_insn ())
! {
! fprintf (stderr, "last_insn corrupt.\n");
! abort ();
! }
! nextx = NULL;
! insn_cnt2 = 1;
! for (x = get_last_insn (); x; x = PREV_INSN (x))
! {
! if (NEXT_INSN (x) != nextx)
! {
! fprintf (stderr, "Reverse traversal: insn chain corrupt.\n");
! fprintf (stderr, "current insn:\n");
! debug_rtx (x);
! fprintf (stderr, "next insn:\n");
! debug_rtx (nextx);
! abort ();
! }
! ++insn_cnt2;
! nextx = x;
! }
if (insn_cnt1 != insn_cnt2)
! {
! fprintf (stderr, "insn_cnt1 (%d) not equal to insn_cnt2 (%d).\n",
! insn_cnt1, insn_cnt2);
! abort ();
! }
}
- /* The block falling through to exit must be the last one in the
- reordered chain. Ensure that this condition is met. */
static void
fixup_fallthru_exit_predecessor ()
--- 987,1015 ----
verify_insn_chain ()
{
! rtx x, prevx, nextx;
! int insn_cnt1, insn_cnt2;
! for (prevx = NULL, insn_cnt1 = 1, x = get_insns ();
! x != 0;
! prevx = x, insn_cnt1++, x = NEXT_INSN (x))
! if (PREV_INSN (x) != prevx)
! abort ();
if (prevx != get_last_insn ())
! abort ();
! for (nextx = NULL, insn_cnt2 = 1, x = get_last_insn ();
! x != 0;
! nextx = x, insn_cnt2++, x = PREV_INSN (x))
! if (NEXT_INSN (x) != nextx)
! abort ();
if (insn_cnt1 != insn_cnt2)
! abort ();
}
+
+ /* The block falling through to exit must be the last one in the reordered
+ chain. Ensure it is. */
static void
fixup_fallthru_exit_predecessor ()
*************** fixup_fallthru_exit_predecessor ()
*** 1055,1066 ****
--- 1021,1036 ----
if (e->flags & EDGE_FALLTHRU)
bb = e->src;
+
if (bb && RBI (bb)->next)
{
basic_block c = BASIC_BLOCK (0);
+
while (RBI (c)->next != bb)
c = RBI (c)->next;
+
RBI (c)->next = RBI (bb)->next;
while (RBI (c)->next)
c = RBI (c)->next;
+
RBI (c)->next = bb;
RBI (bb)->next = NULL;
*************** fixup_fallthru_exit_predecessor ()
*** 1068,1073 ****
}
! /* Main entry point to this module - initialize the datastructures for
! CFG layout changes. */
void
--- 1038,1043 ----
}
! /* Main entry point to this module: initialize the datastructures for CFG
! layout changes. */
void
*************** cfg_layout_initialize ()
*** 1082,1087 ****
}
! /* Finalize the changes - reorder insn list according to the sequence,
! enter compensation code, rebuild scope forest. */
void
--- 1052,1057 ----
}
! /* Finalize the changes: reorder insn list according to the sequence, enter
! compensation code, rebuild scope forest. */
void
*************** cfg_layout_finalize ()
*** 1090,1093 ****
--- 1060,1064 ----
fixup_fallthru_exit_predecessor ();
fixup_reorder_chain ();
+
#ifdef ENABLE_CHECKING
verify_insn_chain ();
*** cfgloop.c 2001/12/21 01:50:10 1.3
--- cfgloop.c 2001/12/24 14:32:53
*************** static int flow_loop_entry_edges_find PA
*** 32,40 ****
edge **));
static int flow_loop_exit_edges_find PARAMS ((const sbitmap, edge **));
! static int flow_loop_nodes_find PARAMS ((basic_block, basic_block, sbitmap));
! static void flow_loop_pre_header_scan PARAMS ((struct loop *));
static basic_block flow_loop_pre_header_find PARAMS ((basic_block,
const sbitmap *));
! static void flow_loop_tree_node_add PARAMS ((struct loop *, struct loop *));
static void flow_loops_tree_build PARAMS ((struct loops *));
static int flow_loop_level_compute PARAMS ((struct loop *, int));
--- 32,42 ----
edge **));
static int flow_loop_exit_edges_find PARAMS ((const sbitmap, edge **));
! static int flow_loop_nodes_find PARAMS ((basic_block, basic_block,
! sbitmap));
! static void flow_loop_pre_header_scan PARAMS ((struct loop *));
static basic_block flow_loop_pre_header_find PARAMS ((basic_block,
const sbitmap *));
! static void flow_loop_tree_node_add PARAMS ((struct loop *,
! struct loop *));
static void flow_loops_tree_build PARAMS ((struct loops *));
static int flow_loop_level_compute PARAMS ((struct loop *, int));
*************** flow_loops_cfg_dump (loops, file)
*** 69,74 ****
--- 71,78 ----
for (i = 0; i < n_basic_blocks; i++)
fprintf (file, "%d ", loops->cfg.dfs_order[i]);
+
fputs ("\n", file);
}
+
/* Dump the reverse completion node order. */
if (loops->cfg.rc_order)
*************** flow_loops_cfg_dump (loops, file)
*** 77,80 ****
--- 81,85 ----
for (i = 0; i < n_basic_blocks; i++)
fprintf (file, "%d ", loops->cfg.rc_order[i]);
+
fputs ("\n", file);
}
*************** flow_loop_dump (loop, file, loop_dump_au
*** 108,117 ****
loop->num, INSN_UID (loop->first->head),
INSN_UID (loop->last->end),
! loop->shared ? " shared" : "",
! loop->invalid ? " invalid" : "");
else
fprintf (file, ";;\n;; Loop %d:%s%s\n", loop->num,
! loop->shared ? " shared" : "",
! loop->invalid ? " invalid" : "");
fprintf (file, ";; header %d, latch %d, pre-header %d, first %d, last %d\n",
--- 113,120 ----
loop->num, INSN_UID (loop->first->head),
INSN_UID (loop->last->end),
! loop->shared ? " shared" : "", loop->invalid ? " invalid" : "");
else
fprintf (file, ";;\n;; Loop %d:%s%s\n", loop->num,
! loop->shared ? " shared" : "", loop->invalid ? " invalid" : "");
fprintf (file, ";; header %d, latch %d, pre-header %d, first %d, last %d\n",
*************** flow_loop_dump (loop, file, loop_dump_au
*** 126,129 ****
--- 129,133 ----
flow_edge_list_print (";; pre-header edges", loop->pre_header_edges,
loop->num_pre_header_edges, file);
+
flow_edge_list_print (";; entry edges", loop->entry_edges,
loop->num_entries, file);
*************** flow_loop_dump (loop, file, loop_dump_au
*** 132,137 ****
--- 136,143 ----
flow_edge_list_print (";; exit edges", loop->exit_edges,
loop->num_exits, file);
+
if (loop->exits_doms)
flow_nodes_print (";; exit doms", loop->exits_doms, file);
+
if (loop_dump_aux)
loop_dump_aux (loop, file, verbose);
*************** flow_loops_dump (loops, file, loop_dump_
*** 148,152 ****
int verbose;
{
! int i;
int num_loops;
--- 154,158 ----
int verbose;
{
! int i, j;
int num_loops;
*************** flow_loops_dump (loops, file, loop_dump_
*** 154,161 ****
if (! num_loops || ! file)
return;
-
- fprintf (file, ";; %d loops found, %d levels\n",
- num_loops, loops->levels);
for (i = 0; i < num_loops; i++)
{
--- 160,165 ----
if (! num_loops || ! file)
return;
+ fprintf (file, ";; %d loops found, %d levels\n", num_loops, loops->levels);
for (i = 0; i < num_loops; i++)
{
*************** flow_loops_dump (loops, file, loop_dump_
*** 163,194 ****
flow_loop_dump (loop, file, loop_dump_aux, verbose);
-
if (loop->shared)
! {
! int j;
!
! for (j = 0; j < i; j++)
! {
! struct loop *oloop = &loops->array[j];
!
! if (loop->header == oloop->header)
! {
! int disjoint;
! int smaller;
!
! smaller = loop->num_nodes < oloop->num_nodes;
!
! /* If the union of LOOP and OLOOP is different than
! the larger of LOOP and OLOOP then LOOP and OLOOP
! must be disjoint. */
! disjoint = ! flow_loop_nested_p (smaller ? loop : oloop,
! smaller ? oloop : loop);
! fprintf (file,
! ";; loop header %d shared by loops %d, %d %s\n",
! loop->header->index, i, j,
! disjoint ? "disjoint" : "nested");
! }
! }
! }
}
--- 167,193 ----
flow_loop_dump (loop, file, loop_dump_aux, verbose);
if (loop->shared)
! for (j = 0; j < i; j++)
! {
! struct loop *oloop = &loops->array[j];
!
! if (loop->header == oloop->header)
! {
! int disjoint;
! int smaller;
!
! smaller = loop->num_nodes < oloop->num_nodes;
!
! /* If the union of LOOP and OLOOP is different than
! the larger of LOOP and OLOOP then LOOP and OLOOP
! must be disjoint. */
! disjoint = ! flow_loop_nested_p (smaller ? loop : oloop,
! smaller ? oloop : loop);
! fprintf (file,
! ";; loop header %d shared by loops %d, %d %s\n",
! loop->header->index, i, j,
! disjoint ? "disjoint" : "nested");
! }
! }
}
*************** flow_loops_free (loops)
*** 226,229 ****
--- 225,229 ----
sbitmap_free (loop->exits_doms);
}
+
free (loops->array);
loops->array = NULL;
*************** flow_loops_free (loops)
*** 231,234 ****
--- 231,235 ----
if (loops->cfg.dom)
sbitmap_vector_free (loops->cfg.dom);
+
if (loops->cfg.dfs_order)
free (loops->cfg.dfs_order);
*************** flow_loop_pre_header_scan (loop)
*** 395,434 ****
struct loop *loop;
{
! int num = 0;
basic_block ebb;
loop->num_pre_header_edges = 0;
-
if (loop->num_entries != 1)
! return;
ebb = loop->entry_edges[0]->src;
!
! if (ebb != ENTRY_BLOCK_PTR)
! {
! edge e;
!
! /* Count number of edges along trace from loop header to
! root of pre-header extended basic block. Usually this is
! only one or two edges. */
! num++;
! while (ebb->pred->src != ENTRY_BLOCK_PTR && ! ebb->pred->pred_next)
! {
! ebb = ebb->pred->src;
! num++;
! }
!
! loop->pre_header_edges = (edge *) xmalloc (num * sizeof (edge *));
! loop->num_pre_header_edges = num;
! /* Store edges in order that they are followed. The source
! of the first edge is the root node of the pre-header extended
! basic block and the destination of the last last edge is
! the loop header. */
! for (e = loop->entry_edges[0]; num; e = e->src->pred)
! {
! loop->pre_header_edges[--num] = e;
! }
! }
}
--- 396,426 ----
struct loop *loop;
{
! int num;
basic_block ebb;
+ edge e;
loop->num_pre_header_edges = 0;
if (loop->num_entries != 1)
! return;
ebb = loop->entry_edges[0]->src;
! if (ebb == ENTRY_BLOCK_PTR)
! return;
! /* Count number of edges along trace from loop header to
! root of pre-header extended basic block. Usually this is
! only one or two edges. */
! for (num = 1; ebb->pred->src != ENTRY_BLOCK_PTR && ! ebb->pred->pred_next;
! num++)
! ebb = ebb->pred->src;
!
! loop->pre_header_edges = (edge *) xmalloc (num * sizeof (edge *));
! loop->num_pre_header_edges = num;
!
! /* Store edges in order that they are followed. The source of the first edge
! is the root node of the pre-header extended basic block and the
! destination of the last last edge is the loop header. */
! for (e = loop->entry_edges[0]; num; e = e->src->pred)
! loop->pre_header_edges[--num] = e;
}
*************** flow_loop_pre_header_find (header, dom)
*** 466,469 ****
--- 458,462 ----
}
}
+
return pre_header;
}
*************** flow_loop_tree_node_add (prevloop, loop)
*** 486,499 ****
}
! while (prevloop->outer)
! {
! if (flow_loop_nested_p (prevloop->outer, loop))
! {
! prevloop->next = loop;
! loop->outer = prevloop->outer;
! return;
! }
! prevloop = prevloop->outer;
! }
prevloop->next = loop;
--- 479,489 ----
}
! for (; prevloop->outer; prevloop = prevloop->outer)
! if (flow_loop_nested_p (prevloop->outer, loop))
! {
! prevloop->next = loop;
! loop->outer = prevloop->outer;
! return;
! }
prevloop->next = loop;
*************** flow_loops_tree_build (loops)
*** 518,522 ****
outermost loop. */
loops->tree_root = &loops->array[0];
! loops->tree_root->outer = loops->tree_root->inner = loops->tree_root->next = NULL;
/* Add the remaining loops to the tree. */
--- 508,513 ----
outermost loop. */
loops->tree_root = &loops->array[0];
! loops->tree_root->outer = loops->tree_root->inner
! = loops->tree_root->next = NULL;
/* Add the remaining loops to the tree. */
*************** flow_loop_level_compute (loop, depth)
*** 547,557 ****
for (inner = loop->inner; inner; inner = inner->next)
{
! int ilevel;
!
! ilevel = flow_loop_level_compute (inner, depth + 1) + 1;
! if (ilevel > level)
! level = ilevel;
}
loop->level = level;
loop->depth = depth;
--- 538,546 ----
for (inner = loop->inner; inner; inner = inner->next)
{
! int ilevel = flow_loop_level_compute (inner, depth + 1) + 1;
! level = MAX (ilevel, level);
}
+
loop->level = level;
loop->depth = depth;
*************** flow_loops_level_compute (loops)
*** 567,573 ****
struct loops *loops;
{
struct loop *loop;
int level;
- int levels = 0;
/* Traverse all the outer level loops. */
--- 556,562 ----
struct loops *loops;
{
+ int levels = 0;
struct loop *loop;
int level;
/* Traverse all the outer level loops. */
*************** flow_loops_level_compute (loops)
*** 575,581 ****
{
level = flow_loop_level_compute (loop, 1);
! if (level > levels)
! levels = level;
}
return levels;
}
--- 564,570 ----
{
level = flow_loop_level_compute (loop, 1);
! levels = MAX (levels, level);
}
+
return levels;
}
*************** flow_loop_scan (loops, loop, flags)
*** 595,615 ****
if (flags & LOOP_ENTRY_EDGES)
! {
! /* Find edges which enter the loop header.
! Note that the entry edges should only
! enter the header of a natural loop. */
! loop->num_entries
! = flow_loop_entry_edges_find (loop->header,
! loop->nodes,
! &loop->entry_edges);
! }
if (flags & LOOP_EXIT_EDGES)
! {
! /* Find edges which exit the loop. */
! loop->num_exits
! = flow_loop_exit_edges_find (loop->nodes,
! &loop->exit_edges);
! }
if (flags & LOOP_EXITS_DOMS)
--- 584,596 ----
if (flags & LOOP_ENTRY_EDGES)
! /* Find edges which enter the loop header. Note that the entry edges
! should only enter the header of a natural loop. */
! loop->num_entries = flow_loop_entry_edges_find (loop->header, loop->nodes,
! &loop->entry_edges);
if (flags & LOOP_EXIT_EDGES)
! /* Find edges which exit the loop. */
! loop->num_exits
! = flow_loop_exit_edges_find (loop->nodes, &loop->exit_edges);
if (flags & LOOP_EXITS_DOMS)
*************** flow_loop_scan (loops, loop, flags)
*** 641,651 ****
flow_loop_pre_header_scan (loop);
}
return 1;
}
! /* Find all the natural loops in the function and save in LOOPS structure
! and recalculate loop_depth information in basic block structures.
! FLAGS controls which loop information is collected.
! Return the number of natural loops found. */
int
--- 622,633 ----
flow_loop_pre_header_scan (loop);
}
+
return 1;
}
! /* Find all the natural loops in the function and save in LOOPS structure and
! recalculate loop_depth information in basic block structures. FLAGS
! controls which loop information is collected. Return the number of natural
! loops found. */
int
*************** flow_loops_find (loops, flags)
*** 669,673 ****
abort ();
! memset (loops, 0, sizeof (*loops));
/* Taking care of this degenerate case makes the rest of
--- 651,655 ----
abort ();
! memset (loops, 0, sizeof *loops);
/* Taking care of this degenerate case makes the rest of
*************** flow_loops_find (loops, flags)
*** 685,689 ****
/* Count the number of loop edges (back edges). This should be the
same as the number of natural loops. */
-
num_loops = 0;
for (b = 0; b < n_basic_blocks; b++)
--- 667,670 ----
*************** flow_loops_find (loops, flags)
*** 811,817 ****
}
else
! {
! sbitmap_vector_free (dom);
! }
loops->num = num_loops;
--- 792,796 ----
}
else
! sbitmap_vector_free (dom);
loops->num = num_loops;
*************** flow_loops_find (loops, flags)
*** 829,832 ****
--- 808,812 ----
/* Update the information regarding the loops in the CFG
specified by LOOPS. */
+
int
flow_loops_update (loops, flags)
*************** flow_loop_outside_edge_p (loop, e)
*** 851,854 ****
if (e->dest != loop->header)
abort ();
! return (e->src == ENTRY_BLOCK_PTR) || ! TEST_BIT (loop->nodes, e->src->index);
}
--- 831,836 ----
if (e->dest != loop->header)
abort ();
!
! return (e->src == ENTRY_BLOCK_PTR)
! || ! TEST_BIT (loop->nodes, e->src->index);
}
*** cfgrtl.c 2001/12/17 17:56:04 1.19
--- cfgrtl.c 2001/12/24 14:33:20
*************** Software Foundation, 59 Temple Place - S
*** 20,45 ****
02111-1307, USA. */
! /* This file contains low level functions to manipulate with CFG and analyze it
! that are aware of RTL intermediate language.
Available functionality:
! - CFG aware instruction chain manipulation
delete_insn, delete_insn_chain
- Basic block manipulation
! create_basic_block, flow_delete_block, split_block, merge_blocks_nomove
! - Infrastructure to determine quickly basic block for instruction.
compute_bb_for_insn, update_bb_for_insn, set_block_for_insn,
! - Edge redirection with updating and optimizing instruction chain
! block_label, redirect_edge_and_branch,
! redirect_edge_and_branch_force, tidy_fallthru_edge, force_nonfallthru
- Edge splitting and commiting to edges
! split_edge, insert_insn_on_edge, commit_edge_insertions
- Dumping and debugging
! print_rtl_with_bb, dump_bb, debug_bb, debug_bb_n
- Consistency checking
! verify_flow_info
- CFG updating after constant propagation
! purge_dead_edges, purge_all_dead_edges
! */
#include "config.h"
--- 20,45 ----
02111-1307, USA. */
! /* This file contains low level functions to manipulate the CFG and analyze it
! that are aware of the RTL intermediate language.
Available functionality:
! - CFG-aware instruction chain manipulation
delete_insn, delete_insn_chain
- Basic block manipulation
! create_basic_block, flow_delete_block, split_block,
! merge_blocks_nomove
! - Infrastructure to determine quickly basic block for insn
compute_bb_for_insn, update_bb_for_insn, set_block_for_insn,
! - Edge redirection with updating and optimizing of insn chain
! block_label, redirect_edge_and_branch,
! redirect_edge_and_branch_force, tidy_fallthru_edge, force_nonfallthru
- Edge splitting and commiting to edges
! split_edge, insert_insn_on_edge, commit_edge_insertions
- Dumping and debugging
! print_rtl_with_bb, dump_bb, debug_bb, debug_bb_n
- Consistency checking
! verify_flow_info
- CFG updating after constant propagation
! purge_dead_edges, purge_all_dead_edges */
#include "config.h"
*************** Software Foundation, 59 Temple Place - S
*** 58,62 ****
#include "obstack.h"
! /* Stubs in case we haven't got a return insn. */
#ifndef HAVE_return
#define HAVE_return 0
--- 58,62 ----
#include "obstack.h"
! /* Stubs in case we don't have a return insn. */
#ifndef HAVE_return
#define HAVE_return 0
*************** Software Foundation, 59 Temple Place - S
*** 65,69 ****
/* The basic block structure for every insn, indexed by uid. */
-
varray_type basic_block_for_insn;
--- 65,68 ----
*************** varray_type basic_block_for_insn;
*** 71,75 ****
/* ??? Should probably be using LABEL_NUSES instead. It would take a
bit of surgery to be able to use or co-opt the routines in jump. */
-
rtx label_value_list;
rtx tail_recursion_label_list;
--- 70,73 ----
*************** static basic_block force_nonfallthru_and
*** 84,88 ****
/* Return true if NOTE is not one of the ones that must be kept paired,
! so that we may simply delete them. */
static int
--- 82,86 ----
/* Return true if NOTE is not one of the ones that must be kept paired,
! so that we may simply delete it. */
static int
*************** can_delete_label_p (label)
*** 100,123 ****
rtx label;
{
! rtx x;
!
! if (LABEL_PRESERVE_P (label))
! return 0;
!
! for (x = forced_labels; x; x = XEXP (x, 1))
! if (label == XEXP (x, 0))
! return 0;
! for (x = label_value_list; x; x = XEXP (x, 1))
! if (label == XEXP (x, 0))
! return 0;
! for (x = exception_handler_labels; x; x = XEXP (x, 1))
! if (label == XEXP (x, 0))
! return 0;
!
! /* User declared labels must be preserved. */
! if (LABEL_NAME (label) != 0)
! return 0;
!
! return 1;
}
--- 98,107 ----
rtx label;
{
! return (!LABEL_PRESERVE_P (label)
! /* User declared labels must be preserved. */
! && LABEL_NAME (label) == 0
! && !in_expr_list_p (forced_labels, label)
! && !in_expr_list_p (label_value_list, label)
! && !in_expr_list_p (exception_handler_labels, label));
}
*************** delete_insn (insn)
*** 146,149 ****
--- 130,134 ----
NOTE_SOURCE_FILE (insn) = name;
}
+
remove_node_from_expr_list (insn, &nonlocal_goto_handler_labels);
}
*************** delete_insn_chain (start, finish)
*** 190,199 ****
rtx start, finish;
{
- /* Unchain the insns one by one. It would be quicker to delete all
- of these with a single unchaining, rather than one at a time, but
- we need to keep the NOTE's. */
-
rtx next;
while (1)
{
--- 175,183 ----
rtx start, finish;
{
rtx next;
+ /* Unchain the insns one by one. It would be quicker to delete all of these
+ with a single unchaining, rather than one at a time, but we need to keep
+ the NOTE's. */
while (1)
{
*************** delete_insn_chain (start, finish)
*** 210,221 ****
}
! /* Create a new basic block consisting of the instructions between
! HEAD and END inclusive. This function is designed to allow fast
! BB construction - reuses the note and basic block struct
! in BB_NOTE, if any and do not grow BASIC_BLOCK chain and should
! be used directly only by CFG construction code.
! END can be NULL in to create new empty basic block before HEAD.
! Both END and HEAD can be NULL to create basic block at the end of
! INSN chain. */
basic_block
--- 194,203 ----
}
! /* Create a new basic block consisting of the instructions between HEAD and END
! inclusive. This function is designed to allow fast BB construction - reuses
! the note and basic block struct in BB_NOTE, if any and do not grow
! BASIC_BLOCK chain and should be used directly only by CFG construction code.
! END can be NULL in to create new empty basic block before HEAD. Both END
! and HEAD can be NULL to create basic block at the end of INSN chain. */
basic_block
*************** create_basic_block_structure (index, hea
*** 253,260 ****
if (!head && !end)
! {
! head = end = bb_note = emit_note_after (NOTE_INSN_BASIC_BLOCK,
! get_last_insn ());
! }
else if (GET_CODE (head) == CODE_LABEL && end)
{
--- 235,240 ----
if (!head && !end)
! head = end = bb_note
! = emit_note_after (NOTE_INSN_BASIC_BLOCK, get_last_insn ());
else if (GET_CODE (head) == CODE_LABEL && end)
{
*************** create_basic_block_structure (index, hea
*** 270,273 ****
--- 250,254 ----
end = head;
}
+
NOTE_BASIC_BLOCK (bb_note) = bb;
}
*************** create_basic_block_structure (index, hea
*** 291,299 ****
}
! /* Create new basic block consisting of instructions in between HEAD and
! END and place it to the BB chain at position INDEX.
! END can be NULL in to create new empty basic block before HEAD.
! Both END and HEAD can be NULL to create basic block at the end of
! INSN chain. */
basic_block
--- 272,279 ----
}
! /* Create new basic block consisting of instructions in between HEAD and END
! and place it to the BB chain at position INDEX. END can be NULL in to
! create new empty basic block before HEAD. Both END and HEAD can be NULL to
! create basic block at the end of INSN chain. */
basic_block
*************** create_basic_block (index, head, end)
*** 314,317 ****
--- 294,298 ----
{
basic_block tmp = BASIC_BLOCK (i - 1);
+
BASIC_BLOCK (i) = tmp;
tmp->index = i;
*************** compute_bb_for_insn (max)
*** 398,401 ****
--- 379,383 ----
if (basic_block_for_insn)
VARRAY_FREE (basic_block_for_insn);
+
VARRAY_BB_INIT (basic_block_for_insn, max, "basic_block_for_insn");
*************** compute_bb_for_insn (max)
*** 403,418 ****
{
basic_block bb = BASIC_BLOCK (i);
! rtx insn, end;
! end = bb->end;
! insn = bb->head;
! while (1)
! {
! int uid = INSN_UID (insn);
! if (uid < max)
! VARRAY_BB (basic_block_for_insn, uid) = bb;
if (insn == end)
break;
- insn = NEXT_INSN (insn);
}
}
--- 385,398 ----
{
basic_block bb = BASIC_BLOCK (i);
! rtx end = bb->end;
! rtx insn;
! for (insn = bb->head; ; insn = NEXT_INSN (insn))
! {
! if (INSN_UID (insn) < max)
! VARRAY_BB (basic_block_for_insn, INSN_UID (insn)) = bb;
!
if (insn == end)
break;
}
}
*************** free_bb_for_insn ()
*** 426,429 ****
--- 406,410 ----
if (basic_block_for_insn)
VARRAY_FREE (basic_block_for_insn);
+
basic_block_for_insn = 0;
}
*************** update_bb_for_insn (bb)
*** 443,447 ****
{
set_block_for_insn (insn, bb);
-
if (insn == bb->end)
break;
--- 424,427 ----
*************** set_block_for_insn (insn, bb)
*** 457,469 ****
{
size_t uid = INSN_UID (insn);
if (uid >= basic_block_for_insn->num_elements)
{
- int new_size;
-
/* Add one-eighth the size so we don't keep calling xrealloc. */
! new_size = uid + (uid + 7) / 8;
VARRAY_GROW (basic_block_for_insn, new_size);
}
VARRAY_BB (basic_block_for_insn, uid) = bb;
}
--- 437,449 ----
{
size_t uid = INSN_UID (insn);
+
if (uid >= basic_block_for_insn->num_elements)
{
/* Add one-eighth the size so we don't keep calling xrealloc. */
! size_t new_size = uid + (uid + 7) / 8;
VARRAY_GROW (basic_block_for_insn, new_size);
}
+
VARRAY_BB (basic_block_for_insn, uid) = bb;
}
*************** merge_blocks_nomove (a, b)
*** 529,540 ****
basic_block a, b;
{
! edge e;
! rtx b_head, b_end, a_end;
rtx del_first = NULL_RTX, del_last = NULL_RTX;
int b_empty = 0;
/* If there was a CODE_LABEL beginning B, delete it. */
- b_head = b->head;
- b_end = b->end;
if (GET_CODE (b_head) == CODE_LABEL)
{
--- 509,518 ----
basic_block a, b;
{
! rtx b_head = b->head, b_end = b->end, a_end = a->end;
rtx del_first = NULL_RTX, del_last = NULL_RTX;
int b_empty = 0;
+ edge e;
/* If there was a CODE_LABEL beginning B, delete it. */
if (GET_CODE (b_head) == CODE_LABEL)
{
*************** merge_blocks_nomove (a, b)
*** 543,551 ****
if (b_head == b_end)
b_empty = 1;
del_first = del_last = b_head;
b_head = NEXT_INSN (b_head);
}
! /* Delete the basic block note. */
if (NOTE_INSN_BASIC_BLOCK_P (b_head))
{
--- 521,531 ----
if (b_head == b_end)
b_empty = 1;
+
del_first = del_last = b_head;
b_head = NEXT_INSN (b_head);
}
! /* Delete the basic block note and handle blocks containing just that
! note. */
if (NOTE_INSN_BASIC_BLOCK_P (b_head))
{
*************** merge_blocks_nomove (a, b)
*** 554,557 ****
--- 534,538 ----
if (! del_last)
del_first = b_head;
+
del_last = b_head;
b_head = NEXT_INSN (b_head);
*************** merge_blocks_nomove (a, b)
*** 559,563 ****
/* If there was a jump out of A, delete it. */
- a_end = a->end;
if (GET_CODE (a_end) == JUMP_INSN)
{
--- 540,543 ----
*************** merge_blocks_nomove (a, b)
*** 578,581 ****
--- 558,562 ----
{
rtx tmp = prev;
+
prev = prev_nonnote_insn (prev);
if (!prev)
*************** merge_blocks_nomove (a, b)
*** 615,634 ****
if (!b_empty)
{
- rtx x = a_end;
if (basic_block_for_insn)
{
! BLOCK_FOR_INSN (x) = a;
! while (x != b_end)
! {
! x = NEXT_INSN (x);
! BLOCK_FOR_INSN (x) = a;
! }
}
a_end = b_end;
}
a->end = a_end;
}
! /* Return label in the head of basic block. Create one if it doesn't exist. */
rtx
--- 596,617 ----
if (!b_empty)
{
if (basic_block_for_insn)
{
! rtx x;
!
! for (x = a_end; x != b_end; x = NEXT_INSN (x))
! BLOCK_FOR_INSN (x) = a;
!
! BLOCK_FOR_INSN (b_end) = a;
}
+
a_end = b_end;
}
+
a->end = a_end;
}
! /* Return the label in the head of basic block BLOCK. Create one if it doesn't
! exist. */
rtx
*************** block_label (block)
*** 638,641 ****
--- 621,625 ----
if (block == EXIT_BLOCK_PTR)
return NULL_RTX;
+
if (GET_CODE (block->head) != CODE_LABEL)
{
*************** block_label (block)
*** 644,657 ****
set_block_for_insn (block->head, block);
}
return block->head;
}
/* Attempt to perform edge redirection by replacing possibly complex jump
! instruction by unconditional jump or removing jump completely.
! This can apply only if all edges now point to the same block.
- The parameters and return values are equivalent to redirect_edge_and_branch.
- */
-
static bool
try_redirect_by_replacing_jump (e, target)
--- 628,640 ----
set_block_for_insn (block->head, block);
}
+
return block->head;
}
/* Attempt to perform edge redirection by replacing possibly complex jump
! instruction by unconditional jump or removing jump completely. This can
! apply only if all edges now point to the same block. The parameters and
! return values are equivalent to redirect_edge_and_branch. */
static bool
try_redirect_by_replacing_jump (e, target)
*************** try_redirect_by_replacing_jump (e, targe
*** 669,672 ****
--- 652,656 ----
if (tmp->dest != target && tmp != e)
break;
+
if (tmp || !onlyjump_p (insn))
return false;
*************** try_redirect_by_replacing_jump (e, targe
*** 695,698 ****
--- 679,683 ----
delete_insn_chain (kill_from, PREV_INSN (target->head));
}
+
/* If this already is simplejump, redirect it. */
else if (simplejump_p (insn))
*************** try_redirect_by_replacing_jump (e, targe
*** 705,708 ****
--- 690,694 ----
redirect_jump (insn, block_label (target), 0);
}
+
/* Or replace possibly complicated jump insn by simple jump insn. */
else
*************** try_redirect_by_replacing_jump (e, targe
*** 733,736 ****
--- 719,723 ----
else
e->flags = 0;
+
e->probability = REG_BR_PROB_BASE;
e->count = src->count;
*************** try_redirect_by_replacing_jump (e, targe
*** 744,747 ****
--- 731,735 ----
if (e->dest != target)
redirect_edge_succ (e, target);
+
return true;
}
*************** try_redirect_by_replacing_jump (e, targe
*** 750,757 ****
basic block. Return INSN if there are no such notes.
! When emitting jump to redirect an fallthru edge, it should always
! appear after the LOOP_BEG notes, as loop optimizer expect loop to
! either start by fallthru edge or jump following the LOOP_BEG note
! jumping to the loop exit test. */
static rtx
--- 738,745 ----
basic block. Return INSN if there are no such notes.
! When emitting jump to redirect an fallthru edge, it should always appear
! after the LOOP_BEG notes, as loop optimizer expect loop to either start by
! fallthru edge or jump following the LOOP_BEG note jumping to the loop exit
! test. */
static rtx
*************** last_loop_beg_note (insn)
*** 760,784 ****
{
rtx last = insn;
! insn = NEXT_INSN (insn);
! while (insn && GET_CODE (insn) == NOTE
! && NOTE_LINE_NUMBER (insn) != NOTE_INSN_BASIC_BLOCK)
! {
! if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG)
! last = insn;
! insn = NEXT_INSN (insn);
! }
return last;
}
! /* Attempt to change code to redirect edge E to TARGET.
! Don't do that on expense of adding new instructions or reordering
! basic blocks.
!
! Function can be also called with edge destination equivalent to the
! TARGET. Then it should try the simplifications and do nothing if
! none is possible.
! Return true if transformation succeeded. We still return false in case
! E already destinated TARGET and we didn't managed to simplify instruction
stream. */
--- 748,769 ----
{
rtx last = insn;
!
! for (insn = NEXT_INSN (insn); insn && GET_CODE (insn) == NOTE
! && NOTE_LINE_NUMBER (insn) != NOTE_INSN_BASIC_BLOCK;
! insn = NEXT_INSN (insn))
! if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG)
! last = insn;
!
return last;
}
! /* Attempt to change code to redirect edge E to TARGET. Don't do that on
! expense of adding new instructions or reordering basic blocks.
! Function can be also called with edge destination equivalent to the TARGET.
! Then it should try the simplifications and do nothing if none is possible.
!
! Return true if transformation succeeded. We still return false in case E
! already destinated TARGET and we didn't managed to simplify instruction
stream. */
*************** redirect_edge_and_branch (e, target)
*** 798,801 ****
--- 783,787 ----
if (try_redirect_by_replacing_jump (e, target))
return true;
+
/* Do this fast path late, as we want above code to simplify for cases
where called on single edge leaving basic block containing nontrivial
*************** redirect_edge_and_branch (e, target)
*** 807,811 ****
if (e->flags & EDGE_FALLTHRU)
return false;
! if (GET_CODE (insn) != JUMP_INSN)
return false;
--- 793,797 ----
if (e->flags & EDGE_FALLTHRU)
return false;
! else if (GET_CODE (insn) != JUMP_INSN)
return false;
*************** redirect_edge_and_branch (e, target)
*** 852,869 ****
one basic block to the other in case only one computed_jump is
available. */
! if (computed_jump_p (insn))
return false;
- /* A return instruction can't be redirected. */
- if (returnjump_p (insn))
- return false;
-
/* If the insn doesn't go where we think, we're confused. */
! if (JUMP_LABEL (insn) != old_label)
abort ();
- /* If the substitution doesn't succeed, die. This can happen
- if the back end emitted unrecognizable instructions. */
- if (! redirect_jump (insn, block_label (target), 0))
- abort ();
}
--- 838,852 ----
one basic block to the other in case only one computed_jump is
available. */
! if (computed_jump_p (insn)
! /* A return instruction can't be redirected. */
! || returnjump_p (insn))
return false;
/* If the insn doesn't go where we think, we're confused. */
! if (JUMP_LABEL (insn) != old_label
! /* If the substitution doesn't succeed, die. This can happen
! if the back end emitted unrecognizable instructions. */
! || !redirect_jump (insn, block_label (target), 0))
abort ();
}
*************** redirect_edge_and_branch (e, target)
*** 871,876 ****
--- 854,861 ----
fprintf (rtl_dump_file, "Edge %i->%i redirected to %i\n",
e->src->index, e->dest->index, target->index);
+
if (e->dest != target)
redirect_edge_succ_nodup (e, target);
+
return true;
}
*************** force_nonfallthru_and_redirect (e, targe
*** 890,900 ****
if (e->flags & EDGE_ABNORMAL)
abort ();
! if (!(e->flags & EDGE_FALLTHRU))
abort ();
! if (e->src->succ->succ_next)
{
/* Create the new structures. */
note = last_loop_beg_note (e->src->end);
! jump_block = create_basic_block (e->src->index + 1, NEXT_INSN (note), NULL);
jump_block->count = e->count;
jump_block->frequency = EDGE_FREQUENCY (e);
--- 875,886 ----
if (e->flags & EDGE_ABNORMAL)
abort ();
! else if (!(e->flags & EDGE_FALLTHRU))
abort ();
! else if (e->src->succ->succ_next)
{
/* Create the new structures. */
note = last_loop_beg_note (e->src->end);
! jump_block
! = create_basic_block (e->src->index + 1, NEXT_INSN (note), NULL);
jump_block->count = e->count;
jump_block->frequency = EDGE_FREQUENCY (e);
*************** force_nonfallthru_and_redirect (e, targe
*** 903,910 ****
if (target->global_live_at_start)
{
! jump_block->global_live_at_start =
! OBSTACK_ALLOC_REG_SET (&flow_obstack);
! jump_block->global_live_at_end =
! OBSTACK_ALLOC_REG_SET (&flow_obstack);
COPY_REG_SET (jump_block->global_live_at_start,
target->global_live_at_start);
--- 889,896 ----
if (target->global_live_at_start)
{
! jump_block->global_live_at_start
! = OBSTACK_ALLOC_REG_SET (&flow_obstack);
! jump_block->global_live_at_end
! = OBSTACK_ALLOC_REG_SET (&flow_obstack);
COPY_REG_SET (jump_block->global_live_at_start,
target->global_live_at_start);
*************** force_nonfallthru_and_redirect (e, targe
*** 926,929 ****
--- 912,916 ----
else
jump_block = e->src;
+
e->flags &= ~EDGE_FALLTHRU;
if (target == EXIT_BLOCK_PTR)
*************** force_nonfallthru_and_redirect (e, targe
*** 941,944 ****
--- 928,932 ----
LABEL_NUSES (label)++;
}
+
emit_barrier_after (jump_block->end);
redirect_edge_succ_nodup (e, target);
*************** force_nonfallthru_and_redirect (e, targe
*** 950,953 ****
--- 938,942 ----
(and possibly create new basic block) to make edge non-fallthru.
Return newly created BB or NULL if none. */
+
basic_block
force_nonfallthru (e)
*************** redirect_edge_and_branch_force (e, targe
*** 966,980 ****
basic_block target;
{
! basic_block new_bb;
!
! if (redirect_edge_and_branch (e, target))
return NULL;
- if (e->dest == target)
- return NULL;
/* In case the edge redirection failed, try to force it to be non-fallthru
and redirect newly created simplejump. */
! new_bb = force_nonfallthru_and_redirect (e, target);
! return new_bb;
}
--- 955,965 ----
basic_block target;
{
! if (redirect_edge_and_branch (e, target)
! || e->dest == target)
return NULL;
/* In case the edge redirection failed, try to force it to be non-fallthru
and redirect newly created simplejump. */
! return force_nonfallthru_and_redirect (e, target);
}
*************** tidy_fallthru_edges ()
*** 1043,1047 ****
int i;
! for (i = 1; i < n_basic_blocks; ++i)
{
basic_block b = BASIC_BLOCK (i - 1);
--- 1028,1032 ----
int i;
! for (i = 1; i < n_basic_blocks; i++)
{
basic_block b = BASIC_BLOCK (i - 1);
*************** tidy_fallthru_edges ()
*** 1060,1063 ****
--- 1045,1049 ----
merge the flags for the duplicate edges. So we do not want to
check that the edge is not a FALLTHRU edge. */
+
if ((s = b->succ) != NULL
&& ! (s->flags & EDGE_COMPLEX)
*************** back_edge_of_syntactic_loop_p (bb1, bb2)
*** 1083,1088 ****
if (bb1->index > bb2->index)
return false;
!
! if (bb1->index == bb2->index)
return true;
--- 1069,1073 ----
if (bb1->index > bb2->index)
return false;
! else if (bb1->index == bb2->index)
return true;
*************** back_edge_of_syntactic_loop_p (bb1, bb2)
*** 1093,1097 ****
if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG)
count++;
! if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END)
count--;
}
--- 1078,1082 ----
if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG)
count++;
! else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END)
count--;
}
*************** split_edge (edge_in)
*** 1124,1127 ****
--- 1109,1113 ----
{
edge e;
+
for (e = edge_in->dest->pred; e; e = e->pred_next)
if (e->flags & EDGE_FALLTHRU)
*************** split_edge (edge_in)
*** 1153,1157 ****
&& PREV_INSN (edge_in->dest->head)
&& GET_CODE (PREV_INSN (edge_in->dest->head)) == NOTE
! && NOTE_LINE_NUMBER (PREV_INSN (edge_in->dest->head)) == NOTE_INSN_LOOP_BEG
&& !back_edge_of_syntactic_loop_p (edge_in->dest, edge_in->src))
before = PREV_INSN (edge_in->dest->head);
--- 1139,1144 ----
&& PREV_INSN (edge_in->dest->head)
&& GET_CODE (PREV_INSN (edge_in->dest->head)) == NOTE
! && (NOTE_LINE_NUMBER (PREV_INSN (edge_in->dest->head))
! == NOTE_INSN_LOOP_BEG)
&& !back_edge_of_syntactic_loop_p (edge_in->dest, edge_in->src))
before = PREV_INSN (edge_in->dest->head);
*************** split_edge (edge_in)
*** 1171,1176 ****
bb->global_live_at_start = OBSTACK_ALLOC_REG_SET (&flow_obstack);
bb->global_live_at_end = OBSTACK_ALLOC_REG_SET (&flow_obstack);
! COPY_REG_SET (bb->global_live_at_start, edge_in->dest->global_live_at_start);
! COPY_REG_SET (bb->global_live_at_end, edge_in->dest->global_live_at_start);
}
--- 1158,1165 ----
bb->global_live_at_start = OBSTACK_ALLOC_REG_SET (&flow_obstack);
bb->global_live_at_end = OBSTACK_ALLOC_REG_SET (&flow_obstack);
! COPY_REG_SET (bb->global_live_at_start,
! edge_in->dest->global_live_at_start);
! COPY_REG_SET (bb->global_live_at_end,
! edge_in->dest->global_live_at_start);
}
*************** commit_one_edge_insertion (e)
*** 1255,1258 ****
--- 1244,1248 ----
{
bb = e->src;
+
/* It is possible to have a non-simple jump here. Consider a target
where some forms of unconditional jumps clobber a register. This
*************** commit_one_edge_insertion (e)
*** 1262,1271 ****
the queued insns before the jump. */
if (GET_CODE (bb->end) == JUMP_INSN)
! {
! before = bb->end;
! while (GET_CODE (PREV_INSN (before)) == NOTE
! && NOTE_LINE_NUMBER (PREV_INSN (before)) == NOTE_INSN_LOOP_BEG)
! before = PREV_INSN (before);
! }
else
{
--- 1252,1260 ----
the queued insns before the jump. */
if (GET_CODE (bb->end) == JUMP_INSN)
! for (before = bb->end;
! GET_CODE (PREV_INSN (before)) == NOTE
! && NOTE_LINE_NUMBER (PREV_INSN (before)) == NOTE_INSN_LOOP_BEG;
! before = PREV_INSN (before))
! ;
else
{
*************** commit_one_edge_insertion (e)
*** 1307,1312 ****
|| (e->flags & EDGE_FALLTHRU) == 0)
abort ();
- e->flags &= ~EDGE_FALLTHRU;
emit_barrier_after (last);
--- 1296,1301 ----
|| (e->flags & EDGE_FALLTHRU) == 0)
abort ();
+ e->flags &= ~EDGE_FALLTHRU;
emit_barrier_after (last);
*************** commit_one_edge_insertion (e)
*** 1316,1319 ****
--- 1305,1309 ----
else if (GET_CODE (last) == JUMP_INSN)
abort ();
+
find_sub_basic_blocks (bb);
}
*************** dump_bb (bb, outf)
*** 1375,1380 ****
putc ('\n', outf);
! for (insn = bb->head, last = NEXT_INSN (bb->end);
! insn != last;
insn = NEXT_INSN (insn))
print_rtl_single (outf, insn);
--- 1365,1369 ----
putc ('\n', outf);
! for (insn = bb->head, last = NEXT_INSN (bb->end); insn != last;
insn = NEXT_INSN (insn))
print_rtl_single (outf, insn);
*************** print_rtl_with_bb (outf, rtx_first)
*** 1421,1430 ****
enum bb_state { NOT_IN_BB, IN_ONE_BB, IN_MULTIPLE_BB };
int max_uid = get_max_uid ();
! basic_block *start = (basic_block *)
! xcalloc (max_uid, sizeof (basic_block));
! basic_block *end = (basic_block *)
! xcalloc (max_uid, sizeof (basic_block));
! enum bb_state *in_bb_p = (enum bb_state *)
! xcalloc (max_uid, sizeof (enum bb_state));
for (i = n_basic_blocks - 1; i >= 0; i--)
--- 1410,1419 ----
enum bb_state { NOT_IN_BB, IN_ONE_BB, IN_MULTIPLE_BB };
int max_uid = get_max_uid ();
! basic_block *start
! = (basic_block *) xcalloc (max_uid, sizeof (basic_block));
! basic_block *end
! = (basic_block *) xcalloc (max_uid, sizeof (basic_block));
! enum bb_state *in_bb_p
! = (enum bb_state *) xcalloc (max_uid, sizeof (enum bb_state));
for (i = n_basic_blocks - 1; i >= 0; i--)
*************** print_rtl_with_bb (outf, rtx_first)
*** 1438,1441 ****
--- 1427,1431 ----
{
enum bb_state state = IN_MULTIPLE_BB;
+
if (in_bb_p[INSN_UID (x)] == NOT_IN_BB)
state = IN_ONE_BB;
*************** print_rtl_with_bb (outf, rtx_first)
*** 1509,1513 ****
and NOTE_INSN_BASIC_BLOCK
- check that all insns are in the basic blocks
! (except the switch handling code, barriers and notes)
- check that all returns are followed by barriers
--- 1499,1503 ----
and NOTE_INSN_BASIC_BLOCK
- check that all insns are in the basic blocks
! (except the switch handling code, barriers and notes)
- check that all returns are followed by barriers
*************** verify_flow_info ()
*** 1541,1544 ****
--- 1531,1535 ----
if (x == end)
break;
+
if (!x)
{
*************** verify_flow_info ()
*** 1561,1564 ****
--- 1552,1556 ----
err = 1;
}
+
bb_info[INSN_UID (x)] = bb;
*************** verify_flow_info ()
*** 1583,1588 ****
edge e;
! e = bb->succ;
! while (e)
{
if (last_visited [e->dest->index + 2] == bb)
--- 1575,1579 ----
edge e;
! for (e = bb->succ; e; e = e->succ_next)
{
if (last_visited [e->dest->index + 2] == bb)
*************** verify_flow_info ()
*** 1592,1595 ****
--- 1583,1587 ----
err = 1;
}
+
last_visited [e->dest->index + 2] = bb;
*************** verify_flow_info ()
*** 1602,1610 ****
{
rtx insn;
if (e->src->index + 1 != e->dest->index)
{
! error ("verify_flow_info: Incorrect blocks for fallthru %i->%i",
! e->src->index, e->dest->index);
! err = 1;
}
else
--- 1594,1604 ----
{
rtx insn;
+
if (e->src->index + 1 != e->dest->index)
{
! error
! ("verify_flow_info: Incorrect blocks for fallthru %i->%i",
! e->src->index, e->dest->index);
! err = 1;
}
else
*************** verify_flow_info ()
*** 1613,1620 ****
if (GET_CODE (insn) == BARRIER
#ifndef CASE_DROPS_THROUGH
! || INSN_P (insn))
#else
! || (INSN_P (insn) && ! JUMP_TABLE_DATA_P (insn)))
#endif
{
error ("verify_flow_info: Incorrect fallthru %i->%i",
--- 1607,1615 ----
if (GET_CODE (insn) == BARRIER
#ifndef CASE_DROPS_THROUGH
! || INSN_P (insn)
#else
! || (INSN_P (insn) && ! JUMP_TABLE_DATA_P (insn))
#endif
+ )
{
error ("verify_flow_info: Incorrect fallthru %i->%i",
*************** verify_flow_info ()
*** 1624,1627 ****
--- 1619,1623 ----
}
}
+
if (e->src != bb)
{
*************** verify_flow_info ()
*** 1635,1641 ****
err = 1;
}
edge_checksum[e->dest->index + 2] += (size_t) e;
- e = e->succ_next;
}
if (!has_fallthru)
{
--- 1631,1638 ----
err = 1;
}
+
edge_checksum[e->dest->index + 2] += (size_t) e;
}
+
if (!has_fallthru)
{
*************** verify_flow_info ()
*** 1655,1660 ****
}
! e = bb->pred;
! while (e)
{
if (e->dest != bb)
--- 1652,1656 ----
}
! for (e = bb->pred; e; e = e->pred_next)
{
if (e->dest != bb)
*************** verify_flow_info ()
*** 1669,1687 ****
}
edge_checksum[e->dest->index + 2] -= (size_t) e;
- e = e->pred_next;
}
- for (x = bb->head; x != NEXT_INSN (bb->end); x = NEXT_INSN (x))
- if (basic_block_for_insn && BLOCK_FOR_INSN (x) != bb)
- {
- debug_rtx (x);
- if (! BLOCK_FOR_INSN (x))
- error ("insn %d is inside basic block %d but block_for_insn is NULL",
- INSN_UID (x), bb->index);
- else
- error ("insn %d is inside basic block %d but block_for_insn is %i",
- INSN_UID (x), bb->index, BLOCK_FOR_INSN (x)->index);
- err = 1;
- }
/* OK pointers are correct. Now check the header of basic
block. It ought to contain optional CODE_LABEL followed
--- 1665,1686 ----
}
edge_checksum[e->dest->index + 2] -= (size_t) e;
}
+ for (x = bb->head; x != NEXT_INSN (bb->end); x = NEXT_INSN (x))
+ if (basic_block_for_insn && BLOCK_FOR_INSN (x) != bb)
+ {
+ debug_rtx (x);
+ if (! BLOCK_FOR_INSN (x))
+ error
+ ("insn %d inside basic block %d but block_for_insn is NULL",
+ INSN_UID (x), bb->index);
+ else
+ error
+ ("insn %d inside basic block %d but block_for_insn is %i",
+ INSN_UID (x), bb->index, BLOCK_FOR_INSN (x)->index);
+
+ err = 1;
+ }
+
/* OK pointers are correct. Now check the header of basic
block. It ought to contain optional CODE_LABEL followed
*************** verify_flow_info ()
*** 1696,1701 ****
--- 1695,1702 ----
err = 1;
}
+
x = NEXT_INSN (x);
}
+
if (!NOTE_INSN_BASIC_BLOCK_P (x) || NOTE_BASIC_BLOCK (x) != bb)
{
*************** verify_flow_info ()
*** 1706,1738 ****
if (bb->end == x)
! {
! /* Do checks for empty blocks here */
! }
else
! {
! x = NEXT_INSN (x);
! while (x)
! {
! if (NOTE_INSN_BASIC_BLOCK_P (x))
! {
! error ("NOTE_INSN_BASIC_BLOCK %d in the middle of basic block %d",
! INSN_UID (x), bb->index);
! err = 1;
! }
!
! if (x == bb->end)
! break;
! if (GET_CODE (x) == JUMP_INSN
! || GET_CODE (x) == CODE_LABEL
! || GET_CODE (x) == BARRIER)
! {
! error ("in basic block %d:", bb->index);
! fatal_insn ("flow control insn inside a basic block", x);
! }
! x = NEXT_INSN (x);
! }
! }
}
--- 1707,1733 ----
if (bb->end == x)
! /* Do checks for empty blocks her. e */
! ;
else
! for (x = NEXT_INSN (x); x; x = NEXT_INSN (x))
! {
! if (NOTE_INSN_BASIC_BLOCK_P (x))
! {
! error ("NOTE_INSN_BASIC_BLOCK %d in middle of basic block %d",
! INSN_UID (x), bb->index);
! err = 1;
! }
! if (x == bb->end)
! break;
! if (GET_CODE (x) == JUMP_INSN
! || GET_CODE (x) == CODE_LABEL
! || GET_CODE (x) == BARRIER)
! {
! error ("in basic block %d:", bb->index);
! fatal_insn ("flow control insn inside a basic block", x);
! }
! }
}
*************** verify_flow_info ()
*** 1740,1745 ****
--- 1735,1742 ----
{
edge e;
+
for (e = ENTRY_BLOCK_PTR->succ; e ; e = e->succ_next)
edge_checksum[e->dest->index + 2] += (size_t) e;
+
for (e = EXIT_BLOCK_PTR->pred; e ; e = e->pred_next)
edge_checksum[e->dest->index + 2] -= (size_t) e;
*************** verify_flow_info ()
*** 1755,1764 ****
last_bb_num_seen = -1;
num_bb_notes = 0;
! x = rtx_first;
! while (x)
{
if (NOTE_INSN_BASIC_BLOCK_P (x))
{
basic_block bb = NOTE_BASIC_BLOCK (x);
num_bb_notes++;
if (bb->index != last_bb_num_seen + 1)
--- 1752,1761 ----
last_bb_num_seen = -1;
num_bb_notes = 0;
! for (x = rtx_first; x; x = NEXT_INSN (x))
{
if (NOTE_INSN_BASIC_BLOCK_P (x))
{
basic_block bb = NOTE_BASIC_BLOCK (x);
+
num_bb_notes++;
if (bb->index != last_bb_num_seen + 1)
*************** verify_flow_info ()
*** 1782,1788 ****
&& (GET_CODE (PATTERN (NEXT_INSN (x))) == ADDR_DIFF_VEC
|| GET_CODE (PATTERN (NEXT_INSN (x))) == ADDR_VEC))
! {
! x = NEXT_INSN (x);
! }
/* But in any case, non-deletable labels can appear anywhere. */
--- 1779,1783 ----
&& (GET_CODE (PATTERN (NEXT_INSN (x))) == ADDR_DIFF_VEC
|| GET_CODE (PATTERN (NEXT_INSN (x))) == ADDR_VEC))
! x = NEXT_INSN (x);
/* But in any case, non-deletable labels can appear anywhere. */
*************** verify_flow_info ()
*** 1799,1804 ****
&& ! (NEXT_INSN (x) && GET_CODE (NEXT_INSN (x)) == BARRIER))
fatal_insn ("return not followed by barrier", x);
-
- x = NEXT_INSN (x);
}
--- 1794,1797 ----
*************** purge_dead_edges (bb)
*** 1829,1838 ****
--- 1822,1834 ----
bool purged = false;
+ /* ??? This makes no sense since the later test includes more cases. */
if (GET_CODE (insn) == JUMP_INSN && !simplejump_p (insn))
return false;
+
if (GET_CODE (insn) == JUMP_INSN)
{
rtx note;
edge b,f;
+
/* We do care only about conditional jumps and simplejumps. */
if (!any_condjump_p (insn)
*************** purge_dead_edges (bb)
*** 1840,1843 ****
--- 1836,1840 ----
&& !simplejump_p (insn))
return false;
+
for (e = bb->succ; e; e = next)
{
*************** purge_dead_edges (bb)
*** 1853,1869 ****
&& any_condjump_p (insn))
continue;
! if (e->dest != EXIT_BLOCK_PTR
! && e->dest->head == JUMP_LABEL (insn))
continue;
! if (e->dest == EXIT_BLOCK_PTR
! && returnjump_p (insn))
continue;
purged = true;
remove_edge (e);
}
if (!bb->succ || !purged)
return false;
if (rtl_dump_file)
fprintf (rtl_dump_file, "Purged edges from bb %i\n", bb->index);
if (!optimize)
return purged;
--- 1850,1870 ----
&& any_condjump_p (insn))
continue;
! else if (e->dest != EXIT_BLOCK_PTR
! && e->dest->head == JUMP_LABEL (insn))
continue;
! else if (e->dest == EXIT_BLOCK_PTR
! && returnjump_p (insn))
continue;
+
purged = true;
remove_edge (e);
}
+
if (!bb->succ || !purged)
return false;
+
if (rtl_dump_file)
fprintf (rtl_dump_file, "Purged edges from bb %i\n", bb->index);
+
if (!optimize)
return purged;
*************** purge_dead_edges (bb)
*** 1880,1883 ****
--- 1881,1885 ----
if (!note)
return purged;
+
b = BRANCH_EDGE (bb);
f = FALLTHRU_EDGE (bb);
*************** purge_dead_edges (bb)
*** 1887,1890 ****
--- 1889,1893 ----
f->count = bb->count * f->probability / REG_BR_PROB_BASE;
}
+
return purged;
}
*************** purge_dead_edges (bb)
*** 1895,1898 ****
--- 1898,1902 ----
{
rtx eqnote;
+
if (! may_trap_p (PATTERN (insn))
|| ((eqnote = find_reg_equal_equiv_note (insn))
*************** purge_dead_edges (bb)
*** 1920,1926 ****
remove all non-fallthru edges. */
for (e = bb->succ; e && (e->flags & (EDGE_COMPLEX | EDGE_FALLTHRU));
! e = e->succ_next);
if (!e)
return purged;
for (e = bb->succ; e; e = next)
{
--- 1924,1933 ----
remove all non-fallthru edges. */
for (e = bb->succ; e && (e->flags & (EDGE_COMPLEX | EDGE_FALLTHRU));
! e = e->succ_next)
! ;
!
if (!e)
return purged;
+
for (e = bb->succ; e; e = next)
{
*************** purge_dead_edges (bb)
*** 1929,1934 ****
--- 1936,1943 ----
remove_edge (e), purged = true;
}
+
if (!bb->succ || bb->succ->succ_next)
abort ();
+
bb->succ->probability = REG_BR_PROB_BASE;
bb->succ->count = bb->count;
*************** purge_dead_edges (bb)
*** 1939,1947 ****
return purged;
}
-
- /* Search all basic blocks for potentially dead edges and purge them.
! Return true iff some edge has been eliminated.
! */
bool
--- 1948,1954 ----
return purged;
}
! /* Search all basic blocks for potentially dead edges and purge them. Return
! true if some edge has been eliminated. */
bool
*************** purge_all_dead_edges (update_life_p)
*** 1957,1972 ****
sbitmap_zero (blocks);
}
for (i = 0; i < n_basic_blocks; i++)
{
! bool purged_here;
! purged_here = purge_dead_edges (BASIC_BLOCK (i));
purged |= purged_here;
if (purged_here && update_life_p)
SET_BIT (blocks, i);
}
if (update_life_p && purged)
update_life_info (blocks, UPDATE_LIFE_GLOBAL,
PROP_DEATH_NOTES | PROP_SCAN_DEAD_CODE
| PROP_KILL_DEAD_CODE);
if (update_life_p)
sbitmap_free (blocks);
--- 1964,1982 ----
sbitmap_zero (blocks);
}
+
for (i = 0; i < n_basic_blocks; i++)
{
! bool purged_here = purge_dead_edges (BASIC_BLOCK (i));
!
purged |= purged_here;
if (purged_here && update_life_p)
SET_BIT (blocks, i);
}
+
if (update_life_p && purged)
update_life_info (blocks, UPDATE_LIFE_GLOBAL,
PROP_DEATH_NOTES | PROP_SCAN_DEAD_CODE
| PROP_KILL_DEAD_CODE);
+
if (update_life_p)
sbitmap_free (blocks);
*** rtl.h 2001/12/22 17:23:52 1.322
--- rtl.h 2001/12/24 14:34:52
*************** extern int for_each_rtx
*** 1484,1487 ****
--- 1484,1488 ----
extern rtx regno_use_in PARAMS ((unsigned int, rtx));
extern int auto_inc_p PARAMS ((rtx));
+ extern int in_expr_list_p PARAMS ((rtx, rtx));
extern void remove_node_from_expr_list PARAMS ((rtx, rtx *));
extern int insns_safe_to_move_p PARAMS ((rtx, rtx, rtx *));
*** rtlanal.c 2001/12/22 17:23:52 1.119
--- rtlanal.c 2001/12/24 14:36:32
*************** remove_note (insn, note)
*** 1955,1958 ****
--- 1955,1976 ----
/* Search LISTP (an EXPR_LIST) for an entry whose first operand is NODE and
+ return 1 if it is found. A simple equality test is used to determine if
+ NODE matches. */
+
+ int
+ in_expr_list_p (listp, node)
+ rtx listp;
+ rtx node;
+ {
+ rtx x;
+
+ for (x = listp; x; x = XEXP (x, 1))
+ if (node == XEXP (x, 0))
+ return 1;
+
+ return 0;
+ }
+
+ /* Search LISTP (an EXPR_LIST) for an entry whose first operand is NODE and
remove that entry from the list if it is found.