/* Optimize jump instructions, for GNU compiler.
Copyright (C) 1987, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997
- 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007
+ 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
Free Software Foundation, Inc.
This file is part of GCC.
return 0;
}
-struct tree_opt_pass pass_cleanup_barriers =
+struct rtl_opt_pass pass_cleanup_barriers =
{
+ {
+ RTL_PASS,
"barriers", /* name */
NULL, /* gate */
cleanup_barriers, /* execute */
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
- TODO_dump_func, /* todo_flags_finish */
- 0 /* letter */
+ TODO_dump_func /* todo_flags_finish */
+ }
};
\f
return UNKNOWN;
/* These CONST_CAST's are okay because prev_nonnote_insn just
- returns it's argument and we assign it to a const_rtx
+ returns its argument and we assign it to a const_rtx
variable. */
for (prev = prev_nonnote_insn (CONST_CAST_RTX(insn));
prev != 0 && !LABEL_P (prev);
if (insn)
{
if (is_target
+ /* Do not change a previous setting of JUMP_LABEL. If the
+ JUMP_LABEL slot is occupied by a different label,
+ create a note for this label. */
&& (JUMP_LABEL (insn) == NULL || JUMP_LABEL (insn) == label))
JUMP_LABEL (insn) = label;
else
a label, except for the primary target of a jump,
must have such a note. */
if (! find_reg_note (insn, kind, label))
- REG_NOTES (insn)
- = gen_rtx_INSN_LIST (kind, label, REG_NOTES (insn));
+ add_reg_note (insn, kind, label);
}
}
return;
return;
}
+ if (code == IF_THEN_ELSE)
+ {
+ /* Skip the condition of an IF_THEN_ELSE. We only want to
+ change jump destinations, not eventual label comparisons. */
+ redirect_exp_1 (&XEXP (x, 1), olabel, nlabel, insn);
+ redirect_exp_1 (&XEXP (x, 2), olabel, nlabel, insn);
+ return;
+ }
+
fmt = GET_RTX_FORMAT (code);
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
{
{
int reg_x = -1, reg_y = -1;
int byte_x = 0, byte_y = 0;
+ struct subreg_info info;
if (GET_MODE (x) != GET_MODE (y))
return 0;
if (reg_renumber[reg_x] >= 0)
{
- reg_x = subreg_regno_offset (reg_renumber[reg_x],
- GET_MODE (SUBREG_REG (x)),
- byte_x,
- GET_MODE (x));
+ subreg_get_info (reg_renumber[reg_x],
+ GET_MODE (SUBREG_REG (x)), byte_x,
+ GET_MODE (x), &info);
+ if (!info.representable_p)
+ return 0;
+ reg_x = info.offset;
byte_x = 0;
}
}
if (reg_renumber[reg_y] >= 0)
{
- reg_y = subreg_regno_offset (reg_renumber[reg_y],
- GET_MODE (SUBREG_REG (y)),
- byte_y,
- GET_MODE (y));
+ subreg_get_info (reg_renumber[reg_y],
+ GET_MODE (SUBREG_REG (y)), byte_y,
+ GET_MODE (y), &info);
+ if (!info.representable_p)
+ return 0;
+ reg_y = info.offset;
byte_y = 0;
}
}
{
int base = true_regnum (SUBREG_REG (x));
if (base >= 0
- && base < FIRST_PSEUDO_REGISTER
- && subreg_offset_representable_p (REGNO (SUBREG_REG (x)),
- GET_MODE (SUBREG_REG (x)),
- SUBREG_BYTE (x), GET_MODE (x)))
- return base + subreg_regno_offset (REGNO (SUBREG_REG (x)),
- GET_MODE (SUBREG_REG (x)),
- SUBREG_BYTE (x), GET_MODE (x));
+ && base < FIRST_PSEUDO_REGISTER)
+ {
+ struct subreg_info info;
+
+ subreg_get_info (REGNO (SUBREG_REG (x)),
+ GET_MODE (SUBREG_REG (x)),
+ SUBREG_BYTE (x), GET_MODE (x), &info);
+
+ if (info.representable_p)
+ return base + info.offset;
+ }
}
return -1;
}