summaryrefslogtreecommitdiff
path: root/gcc/config/bfin
diff options
context:
space:
mode:
authorbernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4>2009-04-29 10:55:25 +0000
committerbernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4>2009-04-29 10:55:25 +0000
commit2a21643e4653c318b6f07d9b6c202fd1a1a80c4e (patch)
tree8420552b2acc6e4c396b99475fba77d7ea594f69 /gcc/config/bfin
parentba0c188a4ecac69547f5f1c0c9a358e28313662e (diff)
downloadgcc-2a21643e4653c318b6f07d9b6c202fd1a1a80c4e.tar.gz
* config/bfin/bfin.c (bfin_optimize_loop): Unify handling of
problematic last insns. Test for TYPE_CALL rather than CALL_P. Remove special case testing for last insn of inner loops. Don't fail if the loop ends with a jump, emit an extra nop instead. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@146952 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/bfin')
-rw-r--r--gcc/config/bfin/bfin.c52
1 files changed, 22 insertions, 30 deletions
diff --git a/gcc/config/bfin/bfin.c b/gcc/config/bfin/bfin.c
index d094d52ab00..43682a3dd57 100644
--- a/gcc/config/bfin/bfin.c
+++ b/gcc/config/bfin/bfin.c
@@ -3792,7 +3792,7 @@ bfin_optimize_loop (loop_info loop)
{
basic_block bb;
loop_info inner;
- rtx insn, init_insn, last_insn, nop_insn;
+ rtx insn, init_insn, last_insn;
rtx loop_init, start_label, end_label;
rtx reg_lc0, reg_lc1, reg_lt0, reg_lt1, reg_lb0, reg_lb1;
rtx iter_reg;
@@ -4003,42 +4003,34 @@ bfin_optimize_loop (loop_info loop)
goto bad_loop;
}
- if (JUMP_P (last_insn))
+ if (JUMP_P (last_insn) && !any_condjump_p (last_insn))
{
- loop_info inner = (loop_info) bb->aux;
- if (inner
- && inner->outer == loop
- && inner->loop_end == last_insn
- && inner->depth == 1)
- /* This jump_insn is the exact loop_end of an inner loop
- and to be optimized away. So use the inner's last_insn. */
- last_insn = inner->last_insn;
- else
+ if (dump_file)
+ fprintf (dump_file, ";; loop %d has bad last instruction\n",
+ loop->loop_no);
+ goto bad_loop;
+ }
+ /* In all other cases, try to replace a bad last insn with a nop. */
+ else if (JUMP_P (last_insn)
+ || CALL_P (last_insn)
+ || get_attr_type (last_insn) == TYPE_SYNC
+ || get_attr_type (last_insn) == TYPE_CALL
+ || get_attr_seq_insns (last_insn) == SEQ_INSNS_MULTI
+ || recog_memoized (last_insn) == CODE_FOR_return_internal
+ || GET_CODE (PATTERN (last_insn)) == ASM_INPUT
+ || asm_noperands (PATTERN (last_insn)) >= 0)
+ {
+ if (loop->length + 2 > MAX_LOOP_LENGTH)
{
if (dump_file)
- fprintf (dump_file, ";; loop %d has bad last instruction\n",
- loop->loop_no);
+ fprintf (dump_file, ";; loop %d too long\n", loop->loop_no);
goto bad_loop;
}
- }
- else if (CALL_P (last_insn)
- || (GET_CODE (PATTERN (last_insn)) != SEQUENCE
- && get_attr_type (last_insn) == TYPE_SYNC)
- || recog_memoized (last_insn) == CODE_FOR_return_internal)
- {
if (dump_file)
- fprintf (dump_file, ";; loop %d has bad last instruction\n",
+ fprintf (dump_file, ";; loop %d has bad last insn; replace with nop\n",
loop->loop_no);
- goto bad_loop;
- }
- if (GET_CODE (PATTERN (last_insn)) == ASM_INPUT
- || asm_noperands (PATTERN (last_insn)) >= 0
- || (GET_CODE (PATTERN (last_insn)) != SEQUENCE
- && get_attr_seq_insns (last_insn) == SEQ_INSNS_MULTI))
- {
- nop_insn = emit_insn_after (gen_nop (), last_insn);
- last_insn = nop_insn;
+ last_insn = emit_insn_after (gen_forced_nop (), last_insn);
}
loop->last_insn = last_insn;
@@ -4169,7 +4161,7 @@ bfin_optimize_loop (loop_info loop)
redirect_edge_succ (e, new_bb);
}
}
-
+
delete_insn (loop->loop_end);
/* Insert the loop end label before the last instruction of the loop. */
emit_label_before (loop->end_label, loop->last_insn);