/* Perform instruction reorganizations for delay slot filling.
- Copyright (C) 1992-2015 Free Software Foundation, Inc.
+ Copyright (C) 1992-2017 Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu).
Hacked by Michael Tiemann (tiemann@cygnus.com).
#include "system.h"
#include "coretypes.h"
#include "backend.h"
-#include "predict.h"
-#include "tree.h"
+#include "target.h"
#include "rtl.h"
-#include "df.h"
-#include "diagnostic-core.h"
+#include "tree.h"
+#include "predict.h"
+#include "memmodel.h"
#include "tm_p.h"
-#include "flags.h"
-#include "alias.h"
-#include "insn-config.h"
#include "expmed.h"
-#include "dojump.h"
-#include "explow.h"
-#include "calls.h"
+#include "insn-config.h"
#include "emit-rtl.h"
-#include "varasm.h"
-#include "stmt.h"
-#include "expr.h"
-#include "conditions.h"
-#include "regs.h"
#include "recog.h"
#include "insn-attr.h"
#include "resource.h"
-#include "except.h"
#include "params.h"
-#include "target.h"
#include "tree-pass.h"
-#ifdef DELAY_SLOTS
-
-#ifndef ANNUL_IFTRUE_SLOTS
-#define eligible_for_annul_true(INSN, SLOTS, TRIAL, FLAGS) 0
-#endif
-#ifndef ANNUL_IFFALSE_SLOTS
-#define eligible_for_annul_false(INSN, SLOTS, TRIAL, FLAGS) 0
-#endif
-
\f
/* First, some functions that were used before GCC got a control flow graph.
These functions are now only used here in reorg.c, and have therefore
static rtx_insn *delete_from_delay_slot (rtx_insn *);
static void delete_scheduled_jump (rtx_insn *);
static void note_delay_statistics (int, int);
-#if defined(ANNUL_IFFALSE_SLOTS) || defined(ANNUL_IFTRUE_SLOTS)
-static void optimize_skip (rtx_jump_insn *, vec<rtx_insn *> *);
-#endif
static int get_jump_flags (const rtx_insn *, rtx);
static int mostly_true_jump (rtx);
static rtx get_branch_condition (const rtx_insn *, rtx);
struct resources *,
int, int *, int *);
static void try_merge_delay_insns (rtx_insn *, rtx_insn *);
-static rtx redundant_insn (rtx, rtx_insn *, const vec<rtx_insn *> &);
+static rtx_insn *redundant_insn (rtx, rtx_insn *, const vec<rtx_insn *> &);
static int own_thread_p (rtx, rtx, int);
-static void update_block (rtx_insn *, rtx);
+static void update_block (rtx_insn *, rtx_insn *);
static int reorg_redirect_jump (rtx_jump_insn *, rtx);
static void update_reg_dead_notes (rtx_insn *, rtx_insn *);
-static void fix_reg_dead_note (rtx, rtx);
-static void update_reg_unused_notes (rtx, rtx);
+static void fix_reg_dead_note (rtx_insn *, rtx);
+static void update_reg_unused_notes (rtx_insn *, rtx);
static void fill_simple_delay_slots (int);
static void fill_slots_from_thread (rtx_jump_insn *, rtx, rtx, rtx,
int, int, int, int,
num_filled_delays[index][slots_filled][reorg_pass_number]++;
}
\f
-#if defined(ANNUL_IFFALSE_SLOTS) || defined(ANNUL_IFTRUE_SLOTS)
-
/* Optimize the following cases:
1. When a conditional branch skips over only one instruction,
|| recog_memoized (trial) < 0
|| (! eligible_for_annul_false (insn, 0, trial, flags)
&& ! eligible_for_annul_true (insn, 0, trial, flags))
+ || RTX_FRAME_RELATED_P (trial)
|| can_throw_internal (trial))
return;
we have one insn followed by a branch to the same label we branch to.
In both of these cases, inverting the jump and annulling the delay
slot give the same effect in fewer insns. */
- if (next_trial == next_active_insn (JUMP_LABEL (insn))
+ if (next_trial == next_active_insn (JUMP_LABEL_AS_INSN (insn))
|| (next_trial != 0
&& simplejump_or_return_p (next_trial)
&& JUMP_LABEL (insn) == JUMP_LABEL (next_trial)))
INSN_ANNULLED_BRANCH_P (insn) = 1;
}
}
-#endif
\f
/* Encode and return branch direction and prediction information for
INSN assuming it will jump to LABEL.
rtx note = find_reg_note (jump_insn, REG_BR_PROB, 0);
if (note)
{
- int prob = XINT (note, 0);
+ int prob = profile_probability::from_reg_br_prob_note (XINT (note, 0))
+ .to_reg_br_prob_base ();
if (prob >= REG_BR_PROB_BASE * 9 / 10)
return 2;
return 0;
src = SET_SRC (pat);
- if (GET_CODE (src) == LABEL_REF && LABEL_REF_LABEL (src) == target)
+ if (GET_CODE (src) == LABEL_REF && label_ref_label (src) == target)
return const_true_rtx;
else if (GET_CODE (src) == IF_THEN_ELSE
&& XEXP (src, 2) == pc_rtx
&& ((GET_CODE (XEXP (src, 1)) == LABEL_REF
- && LABEL_REF_LABEL (XEXP (src, 1)) == target)
+ && label_ref_label (XEXP (src, 1)) == 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
- && LABEL_REF_LABEL (XEXP (src, 2)) == target)
+ && label_ref_label (XEXP (src, 2)) == target)
|| (ANY_RETURN_P (XEXP (src, 2)) && XEXP (src, 2) == target)))
{
enum rtx_code rev;
flags = get_jump_flags (jump, newlabel);
for (i = 1; i < pat->len (); i++)
if (! (
-#ifdef ANNUL_IFFALSE_SLOTS
+#if ANNUL_IFFALSE_SLOTS
(INSN_ANNULLED_BRANCH_P (jump)
&& INSN_FROM_TARGET_P (pat->insn (i)))
? eligible_for_annul_false (jump, i - 1, pat->insn (i), flags) :
#endif
-#ifdef ANNUL_IFTRUE_SLOTS
+#if ANNUL_IFTRUE_SLOTS
(INSN_ANNULLED_BRANCH_P (jump)
&& ! INSN_FROM_TARGET_P (XVECEXP (pat, 0, i)))
? eligible_for_annul_true (jump, i - 1, pat->insn (i), flags) :
unsigned int i = 0;
for (; i < delay_insns; i++)
if (! (
-#ifdef ANNUL_IFFALSE_SLOTS
+#if ANNUL_IFFALSE_SLOTS
(INSN_ANNULLED_BRANCH_P (jump)
&& INSN_FROM_TARGET_P (delay_list[i]))
? eligible_for_annul_false (jump, i, delay_list[i], flags) :
#endif
-#ifdef ANNUL_IFTRUE_SLOTS
+#if ANNUL_IFTRUE_SLOTS
(INSN_ANNULLED_BRANCH_P (jump)
&& ! INSN_FROM_TARGET_P (delay_list[i]))
? eligible_for_annul_true (jump, i, delay_list[i], flags) :
trial, flags)))
{
if (must_annul)
- used_annul = 1;
+ {
+ /* Frame related instructions cannot go into annulled delay
+ slots, it messes up the dwarf info. */
+ if (RTX_FRAME_RELATED_P (trial))
+ return;
+ used_annul = 1;
+ }
rtx_insn *temp = copy_delay_slot_insn (trial);
INSN_FROM_TARGET_P (temp) = 1;
add_to_delay_list (temp, &new_delay_list);
int num_slots = XVECLEN (PATTERN (insn), 0);
rtx next_to_match = XVECEXP (PATTERN (insn), 0, slot_number);
struct resources set, needed, modified;
- rtx_insn_list *merged_insns = 0;
- int i, j;
+ auto_vec<std::pair<rtx_insn *, bool>, 10> merged_insns;
int flags;
flags = get_jump_flags (delay_insn, JUMP_LABEL (delay_insn));
will essentially disable this optimization. This method is somewhat of
a kludge, but I don't see a better way.) */
if (! annul_p)
- for (i = 1 ; i < num_slots; i++)
+ for (int i = 1; i < num_slots; i++)
if (XVECEXP (PATTERN (insn), 0, i))
mark_referenced_resources (XVECEXP (PATTERN (insn), 0, i), &needed,
true);
INSN_FROM_TARGET_P (next_to_match) = 0;
}
else
- merged_insns = gen_rtx_INSN_LIST (VOIDmode, trial, merged_insns);
+ merged_insns.safe_push (std::pair<rtx_insn *, bool> (trial, false));
if (++slot_number == num_slots)
break;
mark_set_resources (filled_insn, &set, 0, MARK_SRC_DEST_CALL);
mark_referenced_resources (filled_insn, &needed, true);
- for (i = 1; i < pat->len (); i++)
+ for (int i = 1; i < pat->len (); i++)
{
rtx_insn *dtrial = pat->insn (i);
CLEAR_RESOURCE (&modified);
/* Account for resources set by the insn following NEXT_TO_MATCH
inside INSN's delay list. */
- for (j = 1; slot_number + j < num_slots; j++)
+ for (int j = 1; slot_number + j < num_slots; j++)
mark_set_resources (XVECEXP (PATTERN (insn), 0, slot_number + j),
&modified, 0, MARK_SRC_DEST_CALL);
/* Account for resources set by the insn before DTRIAL and inside
TRIAL's delay list. */
- for (j = 1; j < i; j++)
+ for (int j = 1; j < i; j++)
mark_set_resources (XVECEXP (pat, 0, j),
&modified, 0, MARK_SRC_DEST_CALL);
if (! insn_references_resource_p (dtrial, &set, true)
INSN_FROM_TARGET_P (next_to_match) = 0;
}
else
- merged_insns = gen_rtx_INSN_LIST (SImode, dtrial,
- merged_insns);
+ merged_insns.safe_push (std::pair<rtx_insn *, bool> (dtrial,
+ true));
if (++slot_number == num_slots)
break;
target. */
if (slot_number == num_slots && annul_p)
{
- for (; merged_insns; merged_insns = merged_insns->next ())
- {
- if (GET_MODE (merged_insns) == SImode)
- {
- rtx_insn *new_rtx;
-
- update_block (merged_insns->insn (), thread);
- new_rtx = delete_from_delay_slot (merged_insns->insn ());
- if (thread->deleted ())
- thread = new_rtx;
- }
- else
- {
- update_block (merged_insns->insn (), thread);
- delete_related_insns (merged_insns->insn ());
- }
- }
+ unsigned int len = merged_insns.length ();
+ for (unsigned int i = len - 1; i < len; i--)
+ if (merged_insns[i].second)
+ {
+ update_block (merged_insns[i].first, thread);
+ rtx_insn *new_rtx = delete_from_delay_slot (merged_insns[i].first);
+ if (thread->deleted ())
+ thread = new_rtx;
+ }
+ else
+ {
+ update_block (merged_insns[i].first, thread);
+ delete_related_insns (merged_insns[i].first);
+ }
INSN_ANNULLED_BRANCH_P (delay_insn) = 0;
- for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
+ for (int i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
INSN_FROM_TARGET_P (XVECEXP (PATTERN (insn), 0, i)) = 0;
}
}
redundant insn, but the cost of splitting seems greater than the possible
gain in rare cases. */
-static rtx
+static rtx_insn *
redundant_insn (rtx insn, rtx_insn *target, const vec<rtx_insn *> &delay_list)
{
rtx target_main = target;
resource requirements as we go. */
for (i = seq->len () - 1; i > 0; i--)
{
- rtx candidate = seq->element (i);
+ rtx_insn *candidate = seq->insn (i);
/* If an insn will be annulled if the branch is false, it isn't
considered as a possible duplicate insn. */
}
\f
/* Called when INSN is being moved from a location near the target of a jump.
- We leave a marker of the form (use (INSN)) immediately in front
- of WHERE for mark_target_live_regs. These markers will be deleted when
- reorg finishes.
+ We leave a marker of the form (use (INSN)) immediately in front of WHERE
+ for mark_target_live_regs. These markers will be deleted at the end.
We used to try to update the live status of registers if WHERE is at
the start of a basic block, but that can't work since we may remove a
BARRIER in relax_delay_slots. */
static void
-update_block (rtx_insn *insn, rtx where)
+update_block (rtx_insn *insn, rtx_insn *where)
{
- /* Ignore if this was in a delay slot and it came from the target of
- a branch. */
- if (INSN_FROM_TARGET_P (insn))
- return;
-
emit_insn_before (gen_rtx_USE (VOIDmode, insn), where);
/* INSN might be making a value live in a block where it didn't use to
be. So recompute liveness information for this block. */
-
incr_ticks_for_insn (insn);
}
confused into thinking the register is dead. */
static void
-fix_reg_dead_note (rtx start_insn, rtx stop_insn)
+fix_reg_dead_note (rtx_insn *start_insn, rtx stop_insn)
{
rtx link, next;
rtx_insn *p;
does. */
static void
-update_reg_unused_notes (rtx insn, rtx redundant_insn)
+update_reg_unused_notes (rtx_insn *insn, rtx redundant_insn)
{
rtx link, next;
/* If all needed slots haven't been filled, we come here. */
/* Try to optimize case of jumping around a single insn. */
-#if defined(ANNUL_IFFALSE_SLOTS) || defined(ANNUL_IFTRUE_SLOTS)
- if (slots_filled != slots_to_fill
+ if ((ANNUL_IFTRUE_SLOTS || ANNUL_IFFALSE_SLOTS)
+ && slots_filled != slots_to_fill
&& delay_list.is_empty ()
&& JUMP_P (insn)
&& (condjump_p (insn) || condjump_in_parallel_p (insn))
if (!delay_list.is_empty ())
slots_filled += 1;
}
-#endif
/* Try to get insns from beyond the insn needing the delay slot.
These insns can neither set or reference resources set in insns being
&& trial
&& jump_to_label_p (trial)
&& simplejump_p (trial)
- && (next_trial = next_active_insn (JUMP_LABEL (trial))) != 0
+ && (next_trial = next_active_insn (JUMP_LABEL_AS_INSN (trial))) != 0
&& ! (NONJUMP_INSN_P (next_trial)
&& GET_CODE (PATTERN (next_trial)) == SEQUENCE)
&& !JUMP_P (next_trial)
&& simplejump_p (jump_insn)
&& slots_filled != slots_to_fill)
fill_slots_from_thread (jump_insn, const_true_rtx,
- next_active_insn (JUMP_LABEL (insn)), NULL, 1,
- 1, own_thread_p (JUMP_LABEL (insn),
+ next_active_insn (JUMP_LABEL_AS_INSN (insn)),
+ NULL, 1, 1, own_thread_p (JUMP_LABEL (insn),
JUMP_LABEL (insn), 0),
slots_to_fill, &slots_filled, &delay_list);
&& (! own_thread || ! sets_cc0_p (pat)))))
&& ! can_throw_internal (trial))
{
- rtx prior_insn;
+ rtx_insn *prior_insn;
/* If TRIAL is redundant with some insn before INSN, we don't
actually need to add it to the delay list; we can merely pretend
if (eligible_for_delay (insn, *pslots_filled, trial, flags))
goto winner;
}
- else if (0
-#ifdef ANNUL_IFTRUE_SLOTS
- || ! thread_if_true
-#endif
-#ifdef ANNUL_IFFALSE_SLOTS
- || thread_if_true
-#endif
- )
+ else if (!RTX_FRAME_RELATED_P (trial)
+ && ((ANNUL_IFTRUE_SLOTS && ! thread_if_true)
+ || (ANNUL_IFFALSE_SLOTS && thread_if_true)))
{
old_trial = trial;
trial = try_split (pat, trial, 0);
to call update_block and delete_insn. */
fix_reg_dead_note (prior_insn, insn);
update_reg_unused_notes (prior_insn, new_thread);
- new_thread = next_active_insn (new_thread);
+ new_thread
+ = next_active_insn (as_a<rtx_insn *> (new_thread));
}
break;
}
}
}
\f
-static void delete_computation (rtx insn);
+static void delete_computation (rtx_insn *insn);
/* Recursively delete prior insns that compute the value (used only by INSN
which the caller is deleting) stored in the register mentioned by NOTE
which is a REG_DEAD note associated with INSN. */
static void
-delete_prior_computation (rtx note, rtx insn)
+delete_prior_computation (rtx note, rtx_insn *insn)
{
- rtx our_prev;
+ rtx_insn *our_prev;
rtx reg = XEXP (note, 0);
for (our_prev = prev_nonnote_insn (insn);
delete the insn that set it. */
static void
-delete_computation (rtx insn)
+delete_computation (rtx_insn *insn)
{
rtx note, next;
}
static rtx_insn *
-label_before_next_insn (rtx x, rtx scan_limit)
+label_before_next_insn (rtx_insn *x, rtx scan_limit)
{
rtx_insn *insn = next_active_insn (x);
while (insn)
{
rtx_insn *insn, *next;
rtx_sequence *pat;
- rtx trial;
rtx_insn *delay_insn;
rtx target_label;
if (ANY_RETURN_P (target_label))
target_label = find_end_label (target_label);
- if (target_label && next_active_insn (target_label) == next
+ if (target_label
+ && next_active_insn (as_a<rtx_insn *> (target_label)) == next
&& ! condjump_in_parallel_p (jump_insn)
&& ! (next && switch_text_sections_between_p (jump_insn, next)))
{
if (next && simplejump_or_return_p (next)
&& any_condjump_p (jump_insn)
&& target_label
- && next_active_insn (target_label) == next_active_insn (next)
+ && (next_active_insn (as_a<rtx_insn *> (target_label))
+ == next_active_insn (next))
&& no_labels_between_p (jump_insn, next)
&& targetm.can_follow_jump (jump_insn, next))
{
&& (other = prev_active_insn (insn)) != 0
&& any_condjump_p (other)
&& no_labels_between_p (other, insn)
- && 0 > mostly_true_jump (other))
+ && mostly_true_jump (other) < 0)
{
rtx other_target = JUMP_LABEL (other);
target_label = JUMP_LABEL (insn);
for (i = 0; i < XVECLEN (pat, 0); i++)
INSN_FROM_TARGET_P (XVECEXP (pat, 0, i)) = 0;
- trial = PREV_INSN (insn);
+ rtx_insn *prev = PREV_INSN (insn);
delete_related_insns (insn);
gcc_assert (GET_CODE (pat) == SEQUENCE);
- add_insn_after (delay_insn, trial, NULL);
+ add_insn_after (delay_insn, prev, NULL);
after = delay_insn;
for (i = 1; i < pat->len (); i++)
after = emit_copy_of_insn_after (pat->insn (i), after);
/* If this jump goes to another unconditional jump, thread it, but
don't convert a jump into a RETURN here. */
- trial = skip_consecutive_labels (follow_jumps (target_label,
- delay_jump_insn,
- &crossing));
+ rtx trial = skip_consecutive_labels (follow_jumps (target_label,
+ delay_jump_insn,
+ &crossing));
if (ANY_RETURN_P (trial))
trial = find_end_label (trial);
reorg_redirect_jump (delay_jump_insn, trial);
target_label = trial;
if (crossing)
- CROSSING_JUMP_P (insn) = 1;
+ CROSSING_JUMP_P (delay_jump_insn) = 1;
}
/* If the first insn at TARGET_LABEL is redundant with a previous
{
/* Figure out where to emit the special USE insn so we don't
later incorrectly compute register live/death info. */
- rtx_insn *tmp = next_active_insn (trial);
+ rtx_insn *tmp = next_active_insn (as_a<rtx_insn *> (trial));
if (tmp == 0)
tmp = find_end_label (simple_return_rtx);
&& simplejump_or_return_p (trial_seq->insn (0))
&& redundant_insn (trial_seq->insn (1), insn, vNULL))
{
- target_label = JUMP_LABEL (trial_seq->insn (0));
- if (ANY_RETURN_P (target_label))
- target_label = find_end_label (target_label);
+ rtx temp_label = JUMP_LABEL (trial_seq->insn (0));
+ if (ANY_RETURN_P (temp_label))
+ temp_label = find_end_label (temp_label);
- if (target_label
+ if (temp_label
&& redirect_with_delay_slots_safe_p (delay_jump_insn,
- target_label, insn))
+ temp_label, insn))
{
update_block (trial_seq->insn (1), insn);
- reorg_redirect_jump (delay_jump_insn, target_label);
+ reorg_redirect_jump (delay_jump_insn, temp_label);
next = insn;
continue;
}
}
/* See if we have a simple (conditional) jump that is useless. */
- if (! INSN_ANNULLED_BRANCH_P (delay_jump_insn)
- && ! condjump_in_parallel_p (delay_jump_insn)
- && prev_active_insn (target_label) == insn
- && ! BARRIER_P (prev_nonnote_insn (target_label))
+ if (!CROSSING_JUMP_P (delay_jump_insn)
+ && !INSN_ANNULLED_BRANCH_P (delay_jump_insn)
+ && !condjump_in_parallel_p (delay_jump_insn)
+ && prev_active_insn (as_a<rtx_insn *> (target_label)) == insn
+ && !BARRIER_P (prev_nonnote_insn (as_a<rtx_insn *> (target_label)))
/* If the last insn in the delay slot sets CC0 for some insn,
various code assumes that it is in a delay slot. We could
put it back where it belonged and delete the register notes,
for (i = 0; i < XVECLEN (pat, 0); i++)
INSN_FROM_TARGET_P (XVECEXP (pat, 0, i)) = 0;
- trial = PREV_INSN (insn);
+ rtx_insn *prev = PREV_INSN (insn);
delete_related_insns (insn);
gcc_assert (GET_CODE (pat) == SEQUENCE);
- add_insn_after (delay_jump_insn, trial, NULL);
+ add_insn_after (delay_jump_insn, prev, NULL);
after = delay_jump_insn;
for (i = 1; i < pat->len (); i++)
after = emit_copy_of_insn_after (pat->insn (i), after);
if (! INSN_ANNULLED_BRANCH_P (delay_jump_insn)
&& any_condjump_p (delay_jump_insn)
&& next && simplejump_or_return_p (next)
- && next_active_insn (target_label) == next_active_insn (next)
+ && (next_active_insn (as_a<rtx_insn *> (target_label))
+ == next_active_insn (next))
&& no_labels_between_p (insn, next))
{
rtx label = JUMP_LABEL (next);
try_merge_delay_insns (insn, next);
else if (! INSN_FROM_TARGET_P (pat->insn (1))
&& own_thread_p (target_label, target_label, 0))
- try_merge_delay_insns (insn, next_active_insn (target_label));
+ try_merge_delay_insns (insn,
+ next_active_insn (as_a<rtx_insn *> (target_label)));
/* If we get here, we haven't deleted INSN. But we may have deleted
NEXT, so recompute it. */
{
for (i = 1; i < XVECLEN (pat, 0); i++)
if (! (
-#ifdef ANNUL_IFFALSE_SLOTS
+#if ANNUL_IFFALSE_SLOTS
(INSN_ANNULLED_BRANCH_P (jump_insn)
&& INSN_FROM_TARGET_P (pat->insn (i)))
? eligible_for_annul_false (jump_insn, i - 1,
pat->insn (i), flags) :
#endif
-#ifdef ANNUL_IFTRUE_SLOTS
+#if ANNUL_IFTRUE_SLOTS
(INSN_ANNULLED_BRANCH_P (jump_insn)
&& ! INSN_FROM_TARGET_P (pat->insn (i)))
? eligible_for_annul_true (jump_insn, i - 1,
delete_related_insns (insn);
for (i = 1; i < XVECLEN (pat, 0); i++)
- prev = emit_insn_after (PATTERN (XVECEXP (pat, 0, i)), prev);
+ {
+ rtx_insn *in_seq_insn = as_a<rtx_insn *> (XVECEXP (pat, 0, i));
+ prev = emit_insn_after_setloc (PATTERN (in_seq_insn), prev,
+ INSN_LOCATION (in_seq_insn));
+ }
- insn = emit_jump_insn_after (PATTERN (jump_insn), prev);
+ insn = emit_jump_insn_after_setloc (PATTERN (jump_insn), prev,
+ INSN_LOCATION (jump_insn));
emit_barrier_after (insn);
if (slots)
{
fill_simple_delay_slots (1);
fill_simple_delay_slots (0);
- fill_eager_delay_slots ();
+ if (!targetm.no_speculation_in_delay_slots_p ())
+ fill_eager_delay_slots ();
relax_delay_slots (first);
}
}
}
fprintf (dump_file, "\n");
-#if defined (ANNUL_IFTRUE_SLOTS) || defined (ANNUL_IFFALSE_SLOTS)
- fprintf (dump_file, ";; Reorg annuls: ");
- need_comma = 0;
- for (j = 0; j < MAX_DELAY_HISTOGRAM + 1; j++)
+
+ if (ANNUL_IFTRUE_SLOTS || ANNUL_IFFALSE_SLOTS)
{
- if (total_annul_slots[j])
+ fprintf (dump_file, ";; Reorg annuls: ");
+ need_comma = 0;
+ for (j = 0; j < MAX_DELAY_HISTOGRAM + 1; j++)
{
- if (need_comma)
- fprintf (dump_file, ", ");
- need_comma = 1;
- fprintf (dump_file, "%d got %d delays", total_annul_slots[j], j);
+ if (total_annul_slots[j])
+ {
+ if (need_comma)
+ fprintf (dump_file, ", ");
+ need_comma = 1;
+ fprintf (dump_file, "%d got %d delays", total_annul_slots[j], j);
+ }
}
+ fprintf (dump_file, "\n");
}
- fprintf (dump_file, "\n");
-#endif
+
fprintf (dump_file, "\n");
}
free (uid_to_ruid);
crtl->dbr_scheduled_p = true;
}
-#endif /* DELAY_SLOTS */
\f
/* Run delay slot optimization. */
static unsigned int
rest_of_handle_delay_slots (void)
{
-#ifdef DELAY_SLOTS
- dbr_schedule (get_insns ());
-#endif
+ if (DELAY_SLOTS)
+ dbr_schedule (get_insns ());
+
return 0;
}
bool
pass_delay_slots::gate (function *)
{
-#ifdef DELAY_SLOTS
/* At -O0 dataflow info isn't updated after RA. */
- return optimize > 0 && flag_delayed_branch && !crtl->dbr_scheduled_p;
-#else
- return 0;
-#endif
+ if (DELAY_SLOTS)
+ return optimize > 0 && flag_delayed_branch && !crtl->dbr_scheduled_p;
+
+ return false;
}
} // anon namespace