From: Bernd Schmidt Date: Wed, 28 Mar 2001 09:02:18 +0000 (+0000) Subject: Avoid deleting labels that got put into the constant pool X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f004c6fd92e0c8d93c33785c165440d58a7baf24;p=thirdparty%2Fgcc.git Avoid deleting labels that got put into the constant pool From-SVN: r40923 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 921089dda7c4..98efc07a0175 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2001-03-28 Bernd Schmidt + + * flow.c (propagate_block): When trying to delete a case vector, cope + if its label has LABEL_PRESERVE_P set. + * jump.c (jump_optimize_1): Move call to delete_barrier_successors to + a point where JUMP_LABELS and LABEL_NUSES are set up properly. + (delete_barrier_successors): If deleting a table jump, delete the case + vector as well. + * varasm.c (force_const_mem): If we have a label, set LABEL_PRESERVE_P + so it won't get deleted. + Tue Mar 20 18:31:48 2001 Kaveh R. Ghazi 1999-11-30 Kaveh R. Ghazi diff --git a/gcc/flow.c b/gcc/flow.c index 432a990220ab..f3b32139541c 100644 --- a/gcc/flow.c +++ b/gcc/flow.c @@ -2744,15 +2744,23 @@ propagate_block (old, first, last, final, significant, bnum, remove_dead_code) { if (REG_NOTE_KIND (inote) == REG_LABEL) { + int n_forced; rtx label = XEXP (inote, 0); rtx next; LABEL_NUSES (label)--; + /* The label may be forced if it has been put in the + constant pool. We can't delete it in this case, but + we still must discard a jump table following it. */ + n_forced = 0; + if (LABEL_PRESERVE_P (label)) + n_forced++; + /* If this label was attached to an ADDR_VEC, it's safe to delete the ADDR_VEC. In fact, it's pretty much mandatory to delete it, because the ADDR_VEC may be referencing labels that no longer exist. */ - if (LABEL_NUSES (label) == 0 + if (LABEL_NUSES (label) == n_forced && (next = next_nonnote_insn (label)) != NULL && GET_CODE (next) == JUMP_INSN && (GET_CODE (PATTERN (next)) == ADDR_VEC diff --git a/gcc/jump.c b/gcc/jump.c index 32eebd1eb6c0..68f967382ed1 100644 --- a/gcc/jump.c +++ b/gcc/jump.c @@ -200,8 +200,6 @@ jump_optimize_1 (f, cross_jump, noop_moves, after_regscan, mark_labels_only) if (flag_exceptions && cross_jump) init_insn_eh_region (f, max_uid); - delete_barrier_successors (f); - /* Leave some extra room for labels and duplicate exit test insns we make. */ max_jump_chain = max_uid * 14 / 10; @@ -224,6 +222,8 @@ jump_optimize_1 (f, cross_jump, noop_moves, after_regscan, mark_labels_only) for (insn = exception_handler_labels; insn; insn = XEXP (insn, 1)) LABEL_NUSES (XEXP (insn, 0))++; + delete_barrier_successors (f); + /* Quit now if we just wanted to rebuild the JUMP_LABEL and REG_LABEL notes and recompute LABEL_NUSES. */ if (mark_labels_only) @@ -2139,7 +2139,23 @@ delete_barrier_successors (f) insn = NEXT_INSN (insn); while (insn != 0 && GET_CODE (insn) != CODE_LABEL) { - if (GET_CODE (insn) == NOTE + if (GET_CODE (insn) == JUMP_INSN) + { + /* Detect when we're deleting a tablejump; get rid of + the jump table as well. */ + rtx next1 = next_nonnote_insn (insn); + rtx next2 = next1 ? next_nonnote_insn (next1) : 0; + if (next2 && GET_CODE (next1) == CODE_LABEL + && (GET_CODE (PATTERN (next2)) == ADDR_VEC + || GET_CODE (PATTERN (next2)) == ADDR_DIFF_VEC)) + { + delete_insn (insn); + insn = next2; + } + else + insn = delete_insn (insn); + } + else if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_END) insn = NEXT_INSN (insn); else diff --git a/gcc/varasm.c b/gcc/varasm.c index b93506546bcf..e5df1d8b52fe 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -3495,6 +3495,9 @@ force_const_mem (mode, x) pop_obstacks (); } + if (GET_CODE (x) == LABEL_REF) + LABEL_PRESERVE_P (XEXP (x, 0)) = 1; + /* Allocate a pool constant descriptor, fill it in, and chain it in. */ pool = (struct pool_constant *) savealloc (sizeof (struct pool_constant));