cfgrtl.c (can_fallthru): Reorder code to move tablejump check up.

* cfgrtl.c (can_fallthru): Reorder code to move tablejump check up.
	Make that check explicit.  BB_HEAD cannot be NULL, remove check for it.
	* haifa-sched.c (ready_remove_first_dispatch): Check INSN_P before
	looking at INSN_CODE.
	* reload1.c (delete_dead_insn) Do not expect JUMP_TABLE_DATA to be an
	active_insn_p object, respect basic block boundaries.
	* reorg.c (follow_jumps): Use invariant that JUMP_TABLE_DATA always
	follows immediately after the jump table data label.
	* config/nds32/nds32.c (nds32_output_casesi_pc_relative): Likewise.
	* config/sh/sh.c (barrier_align): Likewise.  Rearrange code such
	that JUMP_TABLE_DATA is not expected to be an active_insn_p object.

From-SVN: r204758
This commit is contained in:
Steven Bosscher 2013-11-13 22:55:49 +00:00
parent c3d77f3add
commit d7b6661b55
8 changed files with 58 additions and 34 deletions

View file

@ -1,3 +1,17 @@
2013-11-13 Steven Bosscher <steven@gcc.gnu.org>
* cfgrtl.c (can_fallthru): Reorder code to move tablejump check up.
Make that check explicit. BB_HEAD cannot be NULL, remove check for it.
* haifa-sched.c (ready_remove_first_dispatch): Check INSN_P before
looking at INSN_CODE.
* reload1.c (delete_dead_insn) Do not expect JUMP_TABLE_DATA to be an
active_insn_p object, respect basic block boundaries.
* reorg.c (follow_jumps): Use invariant that JUMP_TABLE_DATA always
follows immediately after the jump table data label.
* config/nds32/nds32.c (nds32_output_casesi_pc_relative): Likewise.
* config/sh/sh.c (barrier_align): Likewise. Rearrange code such
that JUMP_TABLE_DATA is not expected to be an active_insn_p object.
2013-11-13 Teresa Johnson <tejohnson@google.com> 2013-11-13 Teresa Johnson <tejohnson@google.com>
PR ipa/58862 PR ipa/58862

View file

@ -610,7 +610,7 @@ forwarder_block_p (const_basic_block bb)
} }
/* Return nonzero if we can reach target from src by falling through. */ /* Return nonzero if we can reach target from src by falling through. */
/* FIXME: Make this a cfg hook. */ /* FIXME: Make this a cfg hook, the result is only valid in cfgrtl mode. */
bool bool
can_fallthru (basic_block src, basic_block target) can_fallthru (basic_block src, basic_block target)
@ -623,17 +623,21 @@ can_fallthru (basic_block src, basic_block target)
if (target == EXIT_BLOCK_PTR) if (target == EXIT_BLOCK_PTR)
return true; return true;
if (src->next_bb != target) if (src->next_bb != target)
return 0; return false;
/* ??? Later we may add code to move jump tables offline. */
if (tablejump_p (insn, NULL, NULL))
return false;
FOR_EACH_EDGE (e, ei, src->succs) FOR_EACH_EDGE (e, ei, src->succs)
if (e->dest == EXIT_BLOCK_PTR if (e->dest == EXIT_BLOCK_PTR
&& e->flags & EDGE_FALLTHRU) && e->flags & EDGE_FALLTHRU)
return 0; return false;
insn2 = BB_HEAD (target); insn2 = BB_HEAD (target);
if (insn2 && !active_insn_p (insn2)) if (!active_insn_p (insn2))
insn2 = next_active_insn (insn2); insn2 = next_active_insn (insn2);
/* ??? Later we may add code to move jump tables offline. */
return next_active_insn (insn) == insn2; return next_active_insn (insn) == insn2;
} }

View file

@ -4677,7 +4677,7 @@ nds32_output_casesi_pc_relative (rtx *operands)
enum machine_mode mode; enum machine_mode mode;
rtx diff_vec; rtx diff_vec;
diff_vec = PATTERN (next_active_insn (operands[1])); diff_vec = PATTERN (NEXT_INSN (operands[1]));
gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC); gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);

View file

@ -5774,24 +5774,18 @@ fixup_addr_diff_vecs (rtx first)
int int
barrier_align (rtx barrier_or_label) barrier_align (rtx barrier_or_label)
{ {
rtx next = next_active_insn (barrier_or_label), pat, prev; rtx next, pat;
if (! next) if (LABEL_P (barrier_or_label)
return 0; && NEXT_INSN (barrier_or_label)
&& JUMP_TABLE_DATA_P (NEXT_INSN (barrier_or_label)))
pat = PATTERN (next);
if (GET_CODE (pat) == ADDR_DIFF_VEC)
return 2; return 2;
if (GET_CODE (pat) == UNSPEC_VOLATILE && XINT (pat, 1) == UNSPECV_ALIGN) if (BARRIER_P (barrier_or_label)
/* This is a barrier in front of a constant table. */ && PREV_INSN (barrier_or_label)
return 0; && JUMP_TABLE_DATA_P (PREV_INSN (barrier_or_label)))
prev = prev_active_insn (barrier_or_label);
if (GET_CODE (PATTERN (prev)) == ADDR_DIFF_VEC)
{ {
pat = PATTERN (prev); pat = PATTERN (PREV_INSN (barrier_or_label));
/* If this is a very small table, we want to keep the alignment after /* If this is a very small table, we want to keep the alignment after
the table to the minimum for proper code alignment. */ the table to the minimum for proper code alignment. */
return ((optimize_size return ((optimize_size
@ -5800,6 +5794,17 @@ barrier_align (rtx barrier_or_label)
? 1 << TARGET_SHMEDIA : align_jumps_log); ? 1 << TARGET_SHMEDIA : align_jumps_log);
} }
next = next_active_insn (barrier_or_label);
if (! next)
return 0;
pat = PATTERN (next);
if (GET_CODE (pat) == UNSPEC_VOLATILE && XINT (pat, 1) == UNSPECV_ALIGN)
/* This is a barrier in front of a constant table. */
return 0;
if (optimize_size) if (optimize_size)
return 0; return 0;
@ -5824,13 +5829,12 @@ barrier_align (rtx barrier_or_label)
(fill_eager_delay_slots) and the branch is to the insn after the insn (fill_eager_delay_slots) and the branch is to the insn after the insn
after the barrier. */ after the barrier. */
/* PREV is presumed to be the JUMP_INSN for the barrier under
investigation. Skip to the insn before it. */
int slot, credit; int slot, credit;
bool jump_to_next = false; bool jump_to_next = false;
prev = prev_real_insn (prev); /* Skip to the insn before the JUMP_INSN before the barrier under
investigation. */
rtx prev = prev_real_insn (prev_active_insn (barrier_or_label));
for (slot = 2, credit = (1 << (CACHE_LOG - 2)) + 2; for (slot = 2, credit = (1 << (CACHE_LOG - 2)) + 2;
credit >= 0 && prev && NONJUMP_INSN_P (prev); credit >= 0 && prev && NONJUMP_INSN_P (prev);

View file

@ -8589,8 +8589,8 @@ ready_remove_first_dispatch (struct ready_list *ready)
rtx insn = ready_element (ready, 0); rtx insn = ready_element (ready, 0);
if (ready->n_ready == 1 if (ready->n_ready == 1
|| INSN_CODE (insn) < 0
|| !INSN_P (insn) || !INSN_P (insn)
|| INSN_CODE (insn) < 0
|| !active_insn_p (insn) || !active_insn_p (insn)
|| targetm.sched.dispatch (insn, FITS_DISPATCH_WINDOW)) || targetm.sched.dispatch (insn, FITS_DISPATCH_WINDOW))
return ready_remove_first (ready); return ready_remove_first (ready);
@ -8599,8 +8599,8 @@ ready_remove_first_dispatch (struct ready_list *ready)
{ {
insn = ready_element (ready, i); insn = ready_element (ready, i);
if (INSN_CODE (insn) < 0 if (!INSN_P (insn)
|| !INSN_P (insn) || INSN_CODE (insn) < 0
|| !active_insn_p (insn)) || !active_insn_p (insn))
continue; continue;
@ -8619,8 +8619,8 @@ ready_remove_first_dispatch (struct ready_list *ready)
{ {
insn = ready_element (ready, i); insn = ready_element (ready, i);
if (INSN_CODE (insn) < 0 if (! INSN_P (insn)
|| !INSN_P (insn) || INSN_CODE (insn) < 0
|| !active_insn_p (insn)) || !active_insn_p (insn))
continue; continue;

View file

@ -124,7 +124,7 @@
2012-07-16 Steven Bosscher <steven@gcc.gnu.org> 2012-07-16 Steven Bosscher <steven@gcc.gnu.org>
* java-gimplify.c Include dumpfile.h instead of tree-dump.h * java-gimplify.c: Include dumpfile.h instead of tree-dump.h
* Make-lang.in: Fix dependencies. * Make-lang.in: Fix dependencies.
2012-07-11 Steven Bosscher <steven@gcc.gnu.org> 2012-07-11 Steven Bosscher <steven@gcc.gnu.org>

View file

@ -2123,7 +2123,8 @@ delete_dead_insn (rtx insn)
block local equivalences. Instead of trying to figure out the exact block local equivalences. Instead of trying to figure out the exact
circumstances where we can delete the potentially dead insns, just circumstances where we can delete the potentially dead insns, just
let DCE do the job. */ let DCE do the job. */
if (prev && GET_CODE (PATTERN (prev)) == SET if (prev && BLOCK_FOR_INSN (prev) == BLOCK_FOR_INSN (insn)
&& GET_CODE (PATTERN (prev)) == SET
&& (prev_dest = SET_DEST (PATTERN (prev)), REG_P (prev_dest)) && (prev_dest = SET_DEST (PATTERN (prev)), REG_P (prev_dest))
&& reg_mentioned_p (prev_dest, PATTERN (insn)) && reg_mentioned_p (prev_dest, PATTERN (insn))
&& find_regno_note (insn, REG_DEAD, REGNO (prev_dest)) && find_regno_note (insn, REG_DEAD, REGNO (prev_dest))

View file

@ -2302,15 +2302,16 @@ follow_jumps (rtx label, rtx jump, bool *crossing)
depth++) depth++)
{ {
rtx this_label = JUMP_LABEL (insn); rtx this_label = JUMP_LABEL (insn);
rtx tem;
/* If we have found a cycle, make the insn jump to itself. */ /* If we have found a cycle, make the insn jump to itself. */
if (this_label == label) if (this_label == label)
return label; return label;
/* Cannot follow returns and cannot look through tablejumps. */
if (ANY_RETURN_P (this_label)) if (ANY_RETURN_P (this_label))
return this_label; return this_label;
tem = next_active_insn (this_label); if (NEXT_INSN (this_label)
if (tem && JUMP_TABLE_DATA_P (tem)) && JUMP_TABLE_DATA_P (NEXT_INSN (this_label)))
break; break;
if (!targetm.can_follow_jump (jump, insn)) if (!targetm.can_follow_jump (jump, insn))