summaryrefslogtreecommitdiff
path: root/gcc/reorg.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/reorg.c')
-rw-r--r--gcc/reorg.c150
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 */
}
};