Commit 3ada20ee by Richard Henderson Committed by Richard Henderson

regrename.c (build_def_use): Don't rename asm operands that were originally hard registers.

        * regrename.c (build_def_use): Don't rename asm operands that
        were originally hard registers.
        (copyprop_hardreg_forward_1): Likewise.
        (find_oldest_value_reg): Copy ORIGINAL_REGNO from source.
        * varasm.c (make_decl_rtl): Use gen_rtx_raw_REG.  Set ORIGINAL_REGNO.

        * gcc.dg/asm-5.c: New.

From-SVN: r48435
parent 5a598ccc
2001-12-31 Richard Henderson <rth@redhat.com>
* regrename.c (build_def_use): Don't rename asm operands that
were originally hard registers.
(copyprop_hardreg_forward_1): Likewise.
(find_oldest_value_reg): Copy ORIGINAL_REGNO from source.
* varasm.c (make_decl_rtl): Use gen_rtx_raw_REG. Set ORIGINAL_REGNO.
2001-12-31 Douglas B Rupp <rupp@gnat.com> 2001-12-31 Douglas B Rupp <rupp@gnat.com>
* config/alpha/vms.h (HAS_INIT_SECTION, NEED_ATEXIT): Remove. * config/alpha/vms.h (HAS_INIT_SECTION, NEED_ATEXIT): Remove.
......
...@@ -838,6 +838,21 @@ build_def_use (bb) ...@@ -838,6 +838,21 @@ build_def_use (bb)
scan_rtx (insn, &CALL_INSN_FUNCTION_USAGE (insn), scan_rtx (insn, &CALL_INSN_FUNCTION_USAGE (insn),
NO_REGS, terminate_all_read, OP_IN, 0); NO_REGS, terminate_all_read, OP_IN, 0);
/* Step 2C: Can't rename asm operands that were originally
hard registers. */
if (asm_noperands (PATTERN (insn)) > 0)
for (i = 0; i < n_ops; i++)
{
rtx *loc = recog_data.operand_loc[i];
rtx op = *loc;
if (GET_CODE (op) == REG
&& REGNO (op) == ORIGINAL_REGNO (op)
&& (recog_data.operand_type[i] == OP_IN
|| recog_data.operand_type[i] == OP_INOUT))
scan_rtx (insn, loc, NO_REGS, terminate_all_read, OP_IN, 0);
}
/* Step 3: Append to chains for reads inside operands. */ /* Step 3: Append to chains for reads inside operands. */
for (i = 0; i < n_ops + recog_data.n_dups; i++) for (i = 0; i < n_ops + recog_data.n_dups; i++)
{ {
...@@ -909,8 +924,27 @@ build_def_use (bb) ...@@ -909,8 +924,27 @@ build_def_use (bb)
/* Step 6: Begin new chains for writes inside operands. */ /* Step 6: Begin new chains for writes inside operands. */
/* ??? Many targets have output constraints on the SET_DEST /* ??? Many targets have output constraints on the SET_DEST
of a call insn, which is stupid, since these are certainly of a call insn, which is stupid, since these are certainly
ABI defined hard registers. Don't change calls at all. */ ABI defined hard registers. Don't change calls at all.
if (GET_CODE (insn) != CALL_INSN) Similarly take special care for asm statement that originally
referenced hard registers. */
if (asm_noperands (PATTERN (insn)) > 0)
{
for (i = 0; i < n_ops; i++)
if (recog_data.operand_type[i] == OP_OUT)
{
rtx *loc = recog_data.operand_loc[i];
rtx op = *loc;
enum reg_class class = recog_op_alt[i][alt].class;
if (GET_CODE (op) == REG
&& REGNO (op) == ORIGINAL_REGNO (op))
continue;
scan_rtx (insn, loc, class, mark_write, OP_OUT,
recog_op_alt[i][alt].earlyclobber);
}
}
else if (GET_CODE (insn) != CALL_INSN)
for (i = 0; i < n_ops + recog_data.n_dups; i++) for (i = 0; i < n_ops + recog_data.n_dups; i++)
{ {
int opn = i < n_ops ? i : recog_data.dup_num[i - n_ops]; int opn = i < n_ops ? i : recog_data.dup_num[i - n_ops];
...@@ -1000,9 +1034,8 @@ static int kill_autoinc_value PARAMS ((rtx *, void *)); ...@@ -1000,9 +1034,8 @@ static int kill_autoinc_value PARAMS ((rtx *, void *));
static void copy_value PARAMS ((rtx, rtx, struct value_data *)); static void copy_value PARAMS ((rtx, rtx, struct value_data *));
static bool mode_change_ok PARAMS ((enum machine_mode, enum machine_mode, static bool mode_change_ok PARAMS ((enum machine_mode, enum machine_mode,
unsigned int)); unsigned int));
static rtx find_oldest_value_reg PARAMS ((enum reg_class, unsigned int, static rtx find_oldest_value_reg PARAMS ((enum reg_class, rtx,
enum machine_mode, struct value_data *));
struct value_data *));
static bool replace_oldest_value_reg PARAMS ((rtx *, enum reg_class, rtx, static bool replace_oldest_value_reg PARAMS ((rtx *, enum reg_class, rtx,
struct value_data *)); struct value_data *));
static bool replace_oldest_value_addr PARAMS ((rtx *, enum reg_class, static bool replace_oldest_value_addr PARAMS ((rtx *, enum reg_class,
...@@ -1240,19 +1273,24 @@ mode_change_ok (orig_mode, new_mode, regno) ...@@ -1240,19 +1273,24 @@ mode_change_ok (orig_mode, new_mode, regno)
of that oldest register, otherwise return NULL. */ of that oldest register, otherwise return NULL. */
static rtx static rtx
find_oldest_value_reg (class, regno, mode, vd) find_oldest_value_reg (class, reg, vd)
enum reg_class class; enum reg_class class;
unsigned int regno; rtx reg;
enum machine_mode mode;
struct value_data *vd; struct value_data *vd;
{ {
unsigned int regno = REGNO (reg);
enum machine_mode mode = GET_MODE (reg);
unsigned int i; unsigned int i;
for (i = vd->e[regno].oldest_regno; i != regno; i = vd->e[i].next_regno) for (i = vd->e[regno].oldest_regno; i != regno; i = vd->e[i].next_regno)
if (TEST_HARD_REG_BIT (reg_class_contents[class], i) if (TEST_HARD_REG_BIT (reg_class_contents[class], i)
&& (vd->e[i].mode == mode && (vd->e[i].mode == mode
|| mode_change_ok (vd->e[i].mode, mode, regno))) || mode_change_ok (vd->e[i].mode, mode, regno)))
return gen_rtx_REG (mode, i); {
rtx new = gen_rtx_REG (mode, i);
ORIGINAL_REGNO (new) = ORIGINAL_REGNO (reg);
return new;
}
return NULL_RTX; return NULL_RTX;
} }
...@@ -1267,7 +1305,7 @@ replace_oldest_value_reg (loc, class, insn, vd) ...@@ -1267,7 +1305,7 @@ replace_oldest_value_reg (loc, class, insn, vd)
rtx insn; rtx insn;
struct value_data *vd; struct value_data *vd;
{ {
rtx new = find_oldest_value_reg (class, REGNO (*loc), GET_MODE (*loc), vd); rtx new = find_oldest_value_reg (class, *loc, vd);
if (new) if (new)
{ {
if (rtl_dump_file) if (rtl_dump_file)
...@@ -1443,6 +1481,7 @@ copyprop_hardreg_forward_1 (bb, vd) ...@@ -1443,6 +1481,7 @@ copyprop_hardreg_forward_1 (bb, vd)
for (insn = bb->head; ; insn = NEXT_INSN (insn)) for (insn = bb->head; ; insn = NEXT_INSN (insn))
{ {
int n_ops, i, alt, predicated; int n_ops, i, alt, predicated;
bool is_asm;
rtx set; rtx set;
if (! INSN_P (insn)) if (! INSN_P (insn))
...@@ -1459,6 +1498,7 @@ copyprop_hardreg_forward_1 (bb, vd) ...@@ -1459,6 +1498,7 @@ copyprop_hardreg_forward_1 (bb, vd)
preprocess_constraints (); preprocess_constraints ();
alt = which_alternative; alt = which_alternative;
n_ops = recog_data.n_operands; n_ops = recog_data.n_operands;
is_asm = asm_noperands (PATTERN (insn)) >= 0;
/* Simplify the code below by rewriting things to reflect /* Simplify the code below by rewriting things to reflect
matching constraints. Also promote OP_OUT to OP_INOUT matching constraints. Also promote OP_OUT to OP_INOUT
...@@ -1498,8 +1538,9 @@ copyprop_hardreg_forward_1 (bb, vd) ...@@ -1498,8 +1538,9 @@ copyprop_hardreg_forward_1 (bb, vd)
be able to do the move from a different register class. */ be able to do the move from a different register class. */
if (set && REG_P (SET_SRC (set))) if (set && REG_P (SET_SRC (set)))
{ {
unsigned int regno = REGNO (SET_SRC (set)); rtx src = SET_SRC (set);
enum machine_mode mode = GET_MODE (SET_SRC (set)); unsigned int regno = REGNO (src);
enum machine_mode mode = GET_MODE (src);
unsigned int i; unsigned int i;
rtx new; rtx new;
...@@ -1507,8 +1548,7 @@ copyprop_hardreg_forward_1 (bb, vd) ...@@ -1507,8 +1548,7 @@ copyprop_hardreg_forward_1 (bb, vd)
register in the same class. */ register in the same class. */
if (REG_P (SET_DEST (set))) if (REG_P (SET_DEST (set)))
{ {
new = find_oldest_value_reg (REGNO_REG_CLASS (regno), new = find_oldest_value_reg (REGNO_REG_CLASS (regno), src, vd);
regno, mode, vd);
if (new && validate_change (insn, &SET_SRC (set), new, 0)) if (new && validate_change (insn, &SET_SRC (set), new, 0))
{ {
if (rtl_dump_file) if (rtl_dump_file)
...@@ -1528,6 +1568,7 @@ copyprop_hardreg_forward_1 (bb, vd) ...@@ -1528,6 +1568,7 @@ copyprop_hardreg_forward_1 (bb, vd)
new = gen_rtx_REG (mode, i); new = gen_rtx_REG (mode, i);
if (validate_change (insn, &SET_SRC (set), new, 0)) if (validate_change (insn, &SET_SRC (set), new, 0))
{ {
ORIGINAL_REGNO (new) = ORIGINAL_REGNO (src);
if (rtl_dump_file) if (rtl_dump_file)
fprintf (rtl_dump_file, fprintf (rtl_dump_file,
"insn %u: replaced reg %u with %u\n", "insn %u: replaced reg %u with %u\n",
...@@ -1550,6 +1591,12 @@ copyprop_hardreg_forward_1 (bb, vd) ...@@ -1550,6 +1591,12 @@ copyprop_hardreg_forward_1 (bb, vd)
if (recog_data.constraints[i][0] == '\0') if (recog_data.constraints[i][0] == '\0')
continue; continue;
/* Don't replace in asms intentionally referencing hard regs. */
if (is_asm && GET_CODE (recog_data.operand[i]) == REG
&& (REGNO (recog_data.operand[i])
== ORIGINAL_REGNO (recog_data.operand[i])))
continue;
if (recog_data.operand_type[i] == OP_IN) if (recog_data.operand_type[i] == OP_IN)
{ {
if (recog_op_alt[i][alt].is_address) if (recog_op_alt[i][alt].is_address)
......
2001-12-31 Richard Henderson <rth@redhat.com>
* gcc.dg/asm-5.c: New.
2001-12-31 Paolo Carlini <pcarlini@unitus.it> 2001-12-31 Paolo Carlini <pcarlini@unitus.it>
* g++.old-deja/g++.robertl/eb130.C: hash_set is now * g++.old-deja/g++.robertl/eb130.C: hash_set is now
......
/* Asm operands that are given as hard registers must keep the same
hard register all the way through compilation. Example derived
from glibc source. */
/* { dg-do compile { target alpha*-*-* } } */
/* { dg-options "-O2 -frename-registers -fcprop-registers" } */
/* { dg-final { scan-assembler "callsys1 .0 .19 .0 .16 .17" } } */
/* { dg-final { scan-assembler "callsys2 .0 .19 .0 .16 .17" } } */
struct stat {
int dummy;
};
struct kernel_stat {
int dummy;
};
extern int xstat_conv (int vers, struct kernel_stat *kbuf, void *ubuf);
extern int *__errno_location (void) __attribute__ ((__const__));
int
__fxstat (int vers, int fd, struct stat *buf)
{
struct kernel_stat kbuf;
int result;
if (vers == 0)
return
({
long _sc_ret, _sc_err;
{
register long _sc_0 __asm__("$0");
register long _sc_16 __asm__("$16");
register long _sc_17 __asm__("$17");
register long _sc_19 __asm__("$19");
_sc_0 = 91;
_sc_16 = (long) (fd);
_sc_17 = (long) (((struct kernel_stat *) buf));
__asm__("callsys1 %0 %1 %2 %3 %4"
: "=r"(_sc_0), "=r"(_sc_19)
: "0"(_sc_0), "r"(_sc_16), "r"(_sc_17)
: "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8",
"$22", "$23", "$24", "$25", "$27", "$28", "memory");
_sc_ret = _sc_0, _sc_err = _sc_19;
}
if (_sc_err)
{
(*__errno_location ()) = (_sc_ret);
_sc_ret = -1L;
}
_sc_ret;
});
result =
({
long _sc_ret, _sc_err;
{
register long _sc_0 __asm__("$0");
register long _sc_16 __asm__("$16");
register long _sc_17 __asm__("$17");
register long _sc_19 __asm__("$19");
_sc_0 = 91;
_sc_16 = (long) (fd);
_sc_17 = (long) ((&kbuf));
__asm__("callsys2 %0 %1 %2 %3 %4"
: "=r"(_sc_0), "=r"(_sc_19)
: "0"(_sc_0), "r"(_sc_16), "r"(_sc_17)
: "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8",
"$22", "$23", "$24", "$25", "$27", "$28", "memory");
_sc_ret = _sc_0, _sc_err = _sc_19;
}
if (_sc_err)
{
(*__errno_location ()) = (_sc_ret);
_sc_ret = -1L;
}
_sc_ret;
});
if (result == 0)
result = xstat_conv (vers, &kbuf, buf);
return result;
}
...@@ -898,14 +898,11 @@ make_decl_rtl (decl, asmspec) ...@@ -898,14 +898,11 @@ make_decl_rtl (decl, asmspec)
/* If the user specified one of the eliminables registers here, /* If the user specified one of the eliminables registers here,
e.g., FRAME_POINTER_REGNUM, we don't want to get this variable e.g., FRAME_POINTER_REGNUM, we don't want to get this variable
confused with that register and be eliminated. Although this confused with that register and be eliminated. This usage is
usage is somewhat suspect, we nevertheless use the following somewhat suspect... */
kludge to avoid setting DECL_RTL to frame_pointer_rtx. */
SET_DECL_RTL (decl, gen_rtx_raw_REG (DECL_MODE (decl), reg_number));
SET_DECL_RTL (decl, ORIGINAL_REGNO (DECL_RTL (decl)) = reg_number;
gen_rtx_REG (DECL_MODE (decl),
FIRST_PSEUDO_REGISTER));
REGNO (DECL_RTL (decl)) = reg_number;
REG_USERVAR_P (DECL_RTL (decl)) = 1; REG_USERVAR_P (DECL_RTL (decl)) = 1;
if (TREE_STATIC (decl)) if (TREE_STATIC (decl))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment