summaryrefslogtreecommitdiff
path: root/gcc/flow.c
diff options
context:
space:
mode:
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2001-07-25 20:51:24 +0000
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2001-07-25 20:51:24 +0000
commitee8f4738eb07aaffceb99cf9199e909b98ba2946 (patch)
tree5205cf427c945b033bd08b12e5836f7ef40eecd0 /gcc/flow.c
parent385df8c52a6d7eec77fdab76aa83c244309e37f9 (diff)
downloadgcc-ee8f4738eb07aaffceb99cf9199e909b98ba2946.tar.gz
* flow.c (delete_dead_jumptables): New function.
(life_analyzis): Call it. * bb-reorder.c (skip_insns_after_block): Handle contradictive sequences. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@44365 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/flow.c')
-rw-r--r--gcc/flow.c77
1 files changed, 68 insertions, 9 deletions
diff --git a/gcc/flow.c b/gcc/flow.c
index 67a2db559f2..529eb00ddf0 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)