diff options
author | bernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-04-29 10:55:25 +0000 |
---|---|---|
committer | bernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-04-29 10:55:25 +0000 |
commit | 2a21643e4653c318b6f07d9b6c202fd1a1a80c4e (patch) | |
tree | 8420552b2acc6e4c396b99475fba77d7ea594f69 /gcc/config/bfin | |
parent | ba0c188a4ecac69547f5f1c0c9a358e28313662e (diff) | |
download | gcc-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.c | 52 |
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); |