aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2001-07-25 22:51:24 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2001-07-25 20:51:24 +0000
commit6e64a52a928d47c3b8f9dad8549866b869c37491 (patch)
tree5205cf427c945b033bd08b12e5836f7ef40eecd0 /gcc
parent7f206d8f42ecbe874b67712a5994dc4459ca4795 (diff)
downloadgcc-6e64a52a928d47c3b8f9dad8549866b869c37491.zip
gcc-6e64a52a928d47c3b8f9dad8549866b869c37491.tar.gz
gcc-6e64a52a928d47c3b8f9dad8549866b869c37491.tar.bz2
flow.c (delete_dead_jumptables): New function.
* flow.c (delete_dead_jumptables): New function. (life_analyzis): Call it. * bb-reorder.c (skip_insns_after_block): Handle contradictive sequences. From-SVN: r44365
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/bb-reorder.c35
-rw-r--r--gcc/flow.c77
3 files changed, 102 insertions, 16 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 973a821..9eb513e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+Wed Jul 25 22:48:59 CEST 2001 Jan Hubicka <jh@suse.cz>
+
+ * flow.c (delete_dead_jumptables): New function.
+ (life_analyzis): Call it.
+ * bb-reorder.c (skip_insns_after_block): Handle contradictive sequences.
+
2001-07-25 Richard Henderson <rth@redhat.com>
* except.c (reachable_handlers): Handle a region being removed
diff --git a/gcc/bb-reorder.c b/gcc/bb-reorder.c
index e2dc44c..e1b3417 100644
--- a/gcc/bb-reorder.c
+++ b/gcc/bb-reorder.c
@@ -205,7 +205,7 @@ static rtx
skip_insns_after_block (bb)
basic_block bb;
{
- rtx insn, last_insn, next_head;
+ rtx insn, last_insn, next_head, prev;
next_head = NULL_RTX;
if (bb->index + 1 != n_basic_blocks)
@@ -234,12 +234,7 @@ skip_insns_after_block (bb)
continue;
default:
- /* Make line notes attached to the succesor block unless they
- are followed by something attached to predecesor block.
- These notes remained after removing code in the predecesor
- block and thus should be kept together. */
- if (NOTE_LINE_NUMBER (insn) >= 0)
- continue;
+ continue;
break;
}
break;
@@ -262,6 +257,32 @@ skip_insns_after_block (bb)
break;
}
+ /* It is possible to hit contradicting sequence. For instance:
+
+ jump_insn
+ NOTE_INSN_LOOP_BEG
+ 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);
+ }
+ }
return last_insn;
}
diff --git a/gcc/flow.c b/gcc/flow.c
index 67a2db5..529eb00 100644
--- a/gcc/flow.c
+++ b/gcc/flow.c
@@ -481,6 +481,7 @@ 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));
static int flow_loops_level_compute PARAMS ((struct loops *));
+static void delete_dead_jumptables PARAMS ((void));
/* Find basic blocks of the current function.
F is the first insn of the function and NREGS the number of register
@@ -4081,6 +4082,8 @@ life_analysis (f, file, flags)
}
}
#endif
+ /* Removing dead insns should've made jumptables really dead. */
+ delete_dead_jumptables ();
}
/* A subroutine of verify_wide_reg, called through for_each_rtx.
@@ -4334,6 +4337,32 @@ delete_noop_moves (f)
}
}
+/* Delete any jump tables never referenced. We can't delete them at the
+ time of removing tablejump insn as they are referenced by the preceeding
+ insns computing the destination, so we delay deleting and garbagecollect
+ them once life information is computed. */
+static void
+delete_dead_jumptables ()
+{
+ rtx insn, next;
+ for (insn = get_insns (); insn; insn = next)
+ {
+ next = NEXT_INSN (insn);
+ if (GET_CODE (insn) == CODE_LABEL
+ && LABEL_NUSES (insn) == 0
+ && GET_CODE (next) == JUMP_INSN
+ && (GET_CODE (PATTERN (next)) == ADDR_VEC
+ || GET_CODE (PATTERN (next)) == ADDR_DIFF_VEC))
+ {
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, "Dead jumptable %i removed\n", INSN_UID (insn));
+ flow_delete_insn (NEXT_INSN (insn));
+ flow_delete_insn (insn);
+ next = NEXT_INSN (next);
+ }
+ }
+}
+
/* Determine if the stack pointer is constant over the life of the function.
Only useful before prologues have been emitted. */
@@ -7956,7 +7985,7 @@ set_block_for_new_insns (insn, bb)
- test head/end pointers
- overlapping of basic blocks
- - edge list corectness
+ - edge list correctness
- headers of basic blocks (the NOTE_INSN_BASIC_BLOCK note)
- tails of basic blocks (ensure that boundary is necesary)
- scans body of the basic block for JUMP_INSN, CODE_LABEL
@@ -8031,8 +8060,9 @@ verify_flow_info ()
for (i = n_basic_blocks - 1; i >= 0; i--)
{
basic_block bb = BASIC_BLOCK (i);
- /* Check corectness of edge lists */
+ /* Check correctness of edge lists. */
edge e;
+ int has_fallthru = 0;
e = bb->succ;
while (e)
@@ -8045,17 +8075,31 @@ verify_flow_info ()
}
last_visited [e->dest->index + 2] = bb;
+ if (e->flags & EDGE_FALLTHRU)
+ has_fallthru = 1;
+
if ((e->flags & EDGE_FALLTHRU)
&& e->src != ENTRY_BLOCK_PTR
- && e->dest != EXIT_BLOCK_PTR
- && (e->src->index + 1 != e->dest->index
- || !can_fallthru (e->src, e->dest)))
+ && e->dest != EXIT_BLOCK_PTR)
{
- error ("verify_flow_info: Incorrect fallthru edge %i->%i",
- e->src->index, e->dest->index);
- err = 1;
+ 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
+ for (insn = NEXT_INSN (e->src->end); insn != e->dest->head;
+ insn = NEXT_INSN (insn))
+ if (GET_CODE (insn) == BARRIER || INSN_P (insn))
+ {
+ error ("verify_flow_info: Incorrect fallthru %i->%i",
+ e->src->index, e->dest->index);
+ fatal_insn ("Wrong insn in the fallthru edge", insn);
+ err = 1;
+ }
}
-
if (e->src != bb)
{
error ("verify_flow_info: Basic block %d succ edge is corrupted",
@@ -8080,6 +8124,21 @@ verify_flow_info ()
}
e = e->succ_next;
}
+ if (!has_fallthru)
+ {
+ rtx insn = bb->end;
+
+ /* Ensure existence of barrier in BB with no fallthru edges. */
+ for (insn = bb->end; GET_CODE (insn) != BARRIER;
+ insn = NEXT_INSN (insn))
+ if (!insn
+ || (GET_CODE (insn) == NOTE
+ && NOTE_LINE_NUMBER (insn) == NOTE_INSN_BASIC_BLOCK))
+ {
+ error ("Missing barrier after block %i", bb->index);
+ err = 1;
+ }
+ }
e = bb->pred;
while (e)