diff options
Diffstat (limited to 'gcc/cfgcleanup.c')
-rw-r--r-- | gcc/cfgcleanup.c | 33 |
1 files changed, 25 insertions, 8 deletions
diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c index f31f168..b6a7f0c 100644 --- a/gcc/cfgcleanup.c +++ b/gcc/cfgcleanup.c @@ -54,7 +54,8 @@ enum bb_flags { /* Set if BB is the forwarder block to avoid too many forwarder_block_p calls. */ - BB_FORWARDER_BLOCK = 1 + BB_FORWARDER_BLOCK = 1, + BB_NONTHREADABLE_BLOCK = 2 }; #define BB_FLAGS(BB) (enum bb_flags) (BB)->aux @@ -279,17 +280,28 @@ thread_jump (mode, e, b) regset nonequal; bool failed = false; + if (BB_FLAGS (b) & BB_NONTHREADABLE_BLOCK) + return NULL; + /* At the moment, we do handle only conditional jumps, but later we may want to extend this code to tablejumps and others. */ if (!e->src->succ->succ_next || e->src->succ->succ_next->succ_next) return NULL; if (!b->succ || !b->succ->succ_next || b->succ->succ_next->succ_next) - return NULL; + { + BB_SET_FLAG (b, BB_NONTHREADABLE_BLOCK); + return NULL; + } /* Second branch must end with onlyjump, as we will eliminate the jump. */ - if (!any_condjump_p (e->src->end) || !any_condjump_p (b->end) - || !onlyjump_p (b->end)) + if (!any_condjump_p (e->src->end)) return NULL; + + if (!any_condjump_p (b->end) || !onlyjump_p (b->end)) + { + BB_SET_FLAG (b, BB_NONTHREADABLE_BLOCK); + return NULL; + } set1 = pc_set (e->src->end); set2 = pc_set (b->end); @@ -324,7 +336,10 @@ thread_jump (mode, e, b) for (insn = NEXT_INSN (b->head); insn != NEXT_INSN (b->end); insn = NEXT_INSN (insn)) if (INSN_P (insn) && side_effects_p (PATTERN (insn))) - return NULL; + { + BB_SET_FLAG (b, BB_NONTHREADABLE_BLOCK); + return NULL; + } cselib_init (); @@ -363,7 +378,10 @@ thread_jump (mode, e, b) /* Later we should clear nonequal of dead registers. So far we don't have life information in cfg_cleanup. */ if (failed) - goto failed_exit; + { + BB_SET_FLAG (b, BB_NONTHREADABLE_BLOCK); + goto failed_exit; + } /* cond2 must not mention any register that is not equal to the former block. */ @@ -1723,8 +1741,7 @@ try_optimize_cfg (mode) if (mode & CLEANUP_CROSSJUMP) remove_fake_edges (); - for (i = 0; i < n_basic_blocks; i++) - BASIC_BLOCK (i)->aux = NULL; + clear_aux_for_blocks (); return changed_overall; } |