/* Global constant/copy propagation for RTL.
- Copyright (C) 1997-2017 Free Software Foundation, Inc.
+ Copyright (C) 1997-2021 Free Software Foundation, Inc.
This file is part of GCC.
#include "cfganal.h"
#include "lcm.h"
#include "cfgcleanup.h"
-#include "params.h"
#include "cselib.h"
#include "intl.h"
#include "tree-pass.h"
(set (reg X) (reg Y))
(set (reg Y) (reg X))
- This can not happen since the set of (reg Y) would have killed the
+ This cannot happen since the set of (reg Y) would have killed the
set of (reg X) making it unavailable at the start of this block. */
while (1)
{
remove_note (jump, note);
}
- /* Delete the cc0 setter. */
- if (HAVE_cc0 && setcc != NULL && CC0_P (SET_DEST (single_set (setcc))))
- delete_insn (setcc);
-
global_const_prop_count++;
if (dump_file != NULL)
{
fprintf (dump_file,
- "GLOBAL CONST-PROP: Replacing reg %d in jump_insn %d with"
+ "GLOBAL CONST-PROP: Replacing reg %d in jump_insn %d with "
"constant ", REGNO (from), INSN_UID (jump));
print_rtl (dump_file, src);
fprintf (dump_file, "\n");
constprop_register (rtx from, rtx src, rtx_insn *insn)
{
rtx sset;
+ rtx_insn *next_insn;
- /* Check for reg or cc0 setting instructions followed by
- conditional branch instructions first. */
+ /* Check for reg setting instructions followed by conditional branch
+ instructions first. */
if ((sset = single_set (insn)) != NULL
- && NEXT_INSN (insn)
- && any_condjump_p (NEXT_INSN (insn)) && onlyjump_p (NEXT_INSN (insn)))
+ && (next_insn = next_nondebug_insn (insn)) != NULL
+ && any_condjump_p (next_insn)
+ && onlyjump_p (next_insn))
{
rtx dest = SET_DEST (sset);
- if ((REG_P (dest) || CC0_P (dest))
- && cprop_jump (BLOCK_FOR_INSN (insn), insn, NEXT_INSN (insn),
+ if (REG_P (dest)
+ && cprop_jump (BLOCK_FOR_INSN (insn), insn, next_insn,
from, src))
return 1;
}
return;
case SUBREG:
- if (df_read_modify_subreg_p (x))
+ if (read_modify_subreg_p (x))
return;
break;
/* Avoid unification of the edge with other edges from original
branch. We would end up emitting the instruction on "both"
edges. */
- if (dest && setcc && !CC0_P (SET_DEST (PATTERN (setcc)))
- && find_edge (e->src, dest))
+ if (dest && setcc && find_edge (e->src, dest))
dest = NULL;
old_dest = e->dest;
{
redirect_edge_and_branch_force (e, dest);
- /* Copy the register setter to the redirected edge.
- Don't copy CC0 setters, as CC0 is dead after jump. */
+ /* Copy the register setter to the redirected edge. */
if (setcc)
{
rtx pat = PATTERN (setcc);
- if (!CC0_P (SET_DEST (pat)))
- insert_insn_on_edge (copy_insn (pat), e);
+ insert_insn_on_edge (copy_insn (pat), e);
}
if (dump_file != NULL)
break;
dest = SET_DEST (PATTERN (insn));
- if (REG_P (dest) || CC0_P (dest))
+ if (REG_P (dest))
setcc = insn;
else
break;
if (! NOTE_P (insn) && ! insn->deleted ())
mark_oprs_set (insn);
- if (!was_uncond_trap && !seen_uncond_trap
+ if (!was_uncond_trap
&& GET_CODE (PATTERN (insn)) == TRAP_IF
&& XEXP (PATTERN (insn), 0) == const1_rtx)
{
- seen_uncond_trap = true;
- uncond_traps.safe_push (insn);
+ /* If we have already seen an unconditional trap
+ earlier, the rest of the bb is going to be removed
+ as unreachable. Just turn it into a note, so that
+ RTL verification doesn't complain about it before
+ it is finally removed. */
+ if (seen_uncond_trap)
+ set_insn_deleted (insn);
+ else
+ {
+ seen_uncond_trap = true;
+ uncond_traps.safe_push (insn);
+ }
}
}
}