diff options
Diffstat (limited to 'gcc/reorg.c')
-rw-r--r-- | gcc/reorg.c | 150 |
1 files changed, 63 insertions, 87 deletions
diff --git a/gcc/reorg.c b/gcc/reorg.c index 82b54e2a14e..30efd79be82 100644 --- a/gcc/reorg.c +++ b/gcc/reorg.c @@ -921,8 +921,8 @@ get_branch_condition (rtx insn, rtx target) if (condjump_in_parallel_p (insn)) pat = XVECEXP (pat, 0, 0); - if (ANY_RETURN_P (pat)) - return pat == target ? const_true_rtx : 0; + if (ANY_RETURN_P (pat) && pat == target) + return const_true_rtx; if (GET_CODE (pat) != SET || SET_DEST (pat) != pc_rtx) return 0; @@ -933,14 +933,16 @@ get_branch_condition (rtx insn, rtx target) else if (GET_CODE (src) == IF_THEN_ELSE && XEXP (src, 2) == pc_rtx - && GET_CODE (XEXP (src, 1)) == LABEL_REF - && XEXP (XEXP (src, 1), 0) == target) + && ((GET_CODE (XEXP (src, 1)) == LABEL_REF + && XEXP (XEXP (src, 1), 0) == target) + || (ANY_RETURN_P (XEXP (src, 1)) && XEXP (src, 1) == target))) return XEXP (src, 0); else if (GET_CODE (src) == IF_THEN_ELSE && XEXP (src, 1) == pc_rtx - && GET_CODE (XEXP (src, 2)) == LABEL_REF - && XEXP (XEXP (src, 2), 0) == target) + && ((GET_CODE (XEXP (src, 2)) == LABEL_REF + && XEXP (XEXP (src, 2), 0) == target) + || (ANY_RETURN_P (XEXP (src, 2)) && XEXP (src, 2) == target))) { enum rtx_code rev; rev = reversed_comparison_code (XEXP (src, 0), insn); @@ -2129,99 +2131,79 @@ fill_simple_delay_slots (int non_jumps_p) Presumably, we should also check to see if we could get back to this function via `setjmp'. */ && ! can_throw_internal (insn) - && (!JUMP_P (insn) - || ((condjump_p (insn) || condjump_in_parallel_p (insn)) - && ! simplejump_p (insn) - && !ANY_RETURN_P (JUMP_LABEL (insn))))) + && !JUMP_P (insn)) { - /* Invariant: If insn is a JUMP_INSN, the insn's jump - label. Otherwise, zero. */ - rtx target = 0; int maybe_never = 0; rtx pat, trial_delay; CLEAR_RESOURCE (&needed); CLEAR_RESOURCE (&set); + mark_set_resources (insn, &set, 0, MARK_SRC_DEST_CALL); + mark_referenced_resources (insn, &needed, true); if (CALL_P (insn)) + maybe_never = 1; + + for (trial = next_nonnote_insn (insn); !stop_search_p (trial, 1); + trial = next_trial) { - mark_set_resources (insn, &set, 0, MARK_SRC_DEST_CALL); - mark_referenced_resources (insn, &needed, true); - maybe_never = 1; - } - else - { - mark_set_resources (insn, &set, 0, MARK_SRC_DEST_CALL); - mark_referenced_resources (insn, &needed, true); - if (JUMP_P (insn)) - target = JUMP_LABEL (insn); - } + next_trial = next_nonnote_insn (trial); + + /* This must be an INSN or CALL_INSN. */ + pat = PATTERN (trial); - if (target == 0 || ANY_RETURN_P (target)) - for (trial = next_nonnote_insn (insn); !stop_search_p (trial, 1); - trial = next_trial) - { - next_trial = next_nonnote_insn (trial); + /* Stand-alone USE and CLOBBER are just for flow. */ + if (GET_CODE (pat) == USE || GET_CODE (pat) == CLOBBER) + continue; - /* This must be an INSN or CALL_INSN. */ - pat = PATTERN (trial); + /* If this already has filled delay slots, get the insn needing + the delay slots. */ + if (GET_CODE (pat) == SEQUENCE) + trial_delay = XVECEXP (pat, 0, 0); + else + trial_delay = trial; - /* Stand-alone USE and CLOBBER are just for flow. */ - if (GET_CODE (pat) == USE || GET_CODE (pat) == CLOBBER) - continue; + /* Stop our search when seeing a jump. */ + if (JUMP_P (trial_delay)) + break; - /* If this already has filled delay slots, get the insn needing - the delay slots. */ - if (GET_CODE (pat) == SEQUENCE) - trial_delay = XVECEXP (pat, 0, 0); - else - trial_delay = trial; - - /* Stop our search when seeing a jump. */ - if (JUMP_P (trial_delay)) - break; - - /* See if we have a resource problem before we try to - split. */ - if (GET_CODE (pat) != SEQUENCE - && ! insn_references_resource_p (trial, &set, true) - && ! insn_sets_resource_p (trial, &set, true) - && ! insn_sets_resource_p (trial, &needed, true) + /* See if we have a resource problem before we try to split. */ + if (GET_CODE (pat) != SEQUENCE + && ! insn_references_resource_p (trial, &set, true) + && ! insn_sets_resource_p (trial, &set, true) + && ! insn_sets_resource_p (trial, &needed, true) #ifdef HAVE_cc0 - && ! (reg_mentioned_p (cc0_rtx, pat) && ! sets_cc0_p (pat)) + && ! (reg_mentioned_p (cc0_rtx, pat) && ! sets_cc0_p (pat)) #endif - && ! (maybe_never && may_trap_or_fault_p (pat)) - && (trial = try_split (pat, trial, 0)) - && eligible_for_delay (insn, slots_filled, trial, flags) - && ! can_throw_internal(trial)) - { - next_trial = next_nonnote_insn (trial); - delay_list = add_to_delay_list (trial, delay_list); - + && ! (maybe_never && may_trap_or_fault_p (pat)) + && (trial = try_split (pat, trial, 0)) + && eligible_for_delay (insn, slots_filled, trial, flags) + && ! can_throw_internal(trial)) + { + next_trial = next_nonnote_insn (trial); + delay_list = add_to_delay_list (trial, delay_list); #ifdef HAVE_cc0 - if (reg_mentioned_p (cc0_rtx, pat)) - link_cc0_insns (trial); + if (reg_mentioned_p (cc0_rtx, pat)) + link_cc0_insns (trial); #endif + delete_related_insns (trial); + if (slots_to_fill == ++slots_filled) + break; + continue; + } - delete_related_insns (trial); - if (slots_to_fill == ++slots_filled) - break; - continue; - } - - mark_set_resources (trial, &set, 0, MARK_SRC_DEST_CALL); - mark_referenced_resources (trial, &needed, true); + mark_set_resources (trial, &set, 0, MARK_SRC_DEST_CALL); + mark_referenced_resources (trial, &needed, true); - /* Ensure we don't put insns between the setting of cc and the - comparison by moving a setting of cc into an earlier delay - slot since these insns could clobber the condition code. */ - set.cc = 1; + /* Ensure we don't put insns between the setting of cc and the + comparison by moving a setting of cc into an earlier delay + slot since these insns could clobber the condition code. */ + set.cc = 1; - /* If this is a call or jump, we might not get here. */ - if (CALL_P (trial_delay) - || JUMP_P (trial_delay)) - maybe_never = 1; - } + /* If this is a call, we might not get here. */ + if (CALL_P (trial_delay)) + maybe_never = 1; + } /* If there are slots left to fill and our search was stopped by an unconditional branch, try the insn at the branch target. We can @@ -2232,7 +2214,6 @@ fill_simple_delay_slots (int non_jumps_p) && trial && jump_to_label_p (trial) && simplejump_p (trial) - && (target == 0 || JUMP_LABEL (trial) == target) && (next_trial = next_active_insn (JUMP_LABEL (trial))) != 0 && ! (NONJUMP_INSN_P (next_trial) && GET_CODE (PATTERN (next_trial)) == SEQUENCE) @@ -2264,11 +2245,6 @@ fill_simple_delay_slots (int non_jumps_p) delay_list); slots_filled++; reorg_redirect_jump (trial, new_label); - - /* If we merged because we both jumped to the same place, - redirect the original insn also. */ - if (target) - reorg_redirect_jump (insn, new_label); } } } @@ -3907,7 +3883,7 @@ struct rtl_opt_pass pass_delay_slots = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_ggc_collect /* todo_flags_finish */ + 0 /* todo_flags_finish */ } }; @@ -3942,6 +3918,6 @@ struct rtl_opt_pass pass_machine_reorg = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_ggc_collect /* todo_flags_finish */ + 0 /* todo_flags_finish */ } }; |