summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog31
-rw-r--r--gcc/emit-rtl.c153
-rw-r--r--gcc/final.c26
-rw-r--r--gcc/function.c9
-rw-r--r--gcc/function.h5
-rw-r--r--gcc/gengtype.c5
-rw-r--r--gcc/integrate.c8
-rw-r--r--gcc/print-rtl.c17
-rw-r--r--gcc/regclass.c10
-rw-r--r--gcc/reload1.c7
-rw-r--r--gcc/rtl.def2
-rw-r--r--gcc/rtl.h29
-rw-r--r--gcc/simplify-rtx.c2
-rw-r--r--gcc/stmt.c8
-rw-r--r--gcc/tree.h5
15 files changed, 249 insertions, 68 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e15a89ec5aa..a4458285624 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,34 @@
+Fri Jan 24 23:44:12 CET 2003 Jan Hubicka <jh@suse.cz>
+
+ * emit-rtl.c (reg_attrs_htab): New static variable.
+ (reg_attrs_htab_hash, reg_attrs_htab_eq, get_reg_attrs): New static
+ functions.
+ (reg_rtx): Do not maintain regno_decl.
+ (gen_rtx_REG_offset, set_reg_attrs_from_mem, set_delc_rtx,
+ set_mem_attrs_from_reg): New global function.
+ (init_emit): Do not initialize regno_decl.
+ (init_emit_once): initialize reg_attrs_htab.
+ * final.c (alter_subreg): Do not replace REG by SUBREG.
+ (gen_mem_expr_from_op): Improve output.
+ (output_asm_operands): Likewise.
+ * function.c (assign_params): Do not set REGNO_DECL.
+ * function.h (struct function): Kill regno_decl.
+ (REGNO_DECL): Kill.
+ * gengtype.c (adjust_field_rtx_def): Handle new field of reg.
+ * print_rtl.c (print_rtx): Output REG information.
+ * regclass.c (reg_scan_mark_refs): Update attrs.
+ * reload1.c (alter_reg): Likewise.
+ * simplify_rtx.c (simplify_subreg): Likewise.
+ * stmt.c (expand_decl): Likewise.
+ * rtl.def (REG): Add new field.
+ * rtl.h (struct reg_attrs): New.
+ (rtunion_def): At rtreg.
+ (X0MEMATTR): Add checking.
+ (X0REGATTR, REG_ATTRS, REG_EXPR, REG_OFFSET): New macro.
+ (set_reg_attrs_from_mem, set_mem_attrs_from_reg, gen_rtx_REG_offset):
+ Declare.
+ * tree.h (SET_DECL_RTL): Call set_decl_rtl.
+
2003-01-24 Bob Wilson <bob.wilson@acm.org>
* config/xtensa/xtensa.c: Remove unused include of machmode.h.
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index 5dd599a8599..5e719ae2ac1 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -157,6 +157,10 @@ static GTY ((if_marked ("ggc_marked_p"), param_is (struct rtx_def)))
static GTY ((if_marked ("ggc_marked_p"), param_is (struct mem_attrs)))
htab_t mem_attrs_htab;
+/* A hash table storing register attribute structures. */
+static GTY ((if_marked ("ggc_marked_p"), param_is (struct reg_attrs)))
+ htab_t reg_attrs_htab;
+
/* A hash table storing all CONST_DOUBLEs. */
static GTY ((if_marked ("ggc_marked_p"), param_is (struct rtx_def)))
htab_t const_double_htab;
@@ -190,6 +194,10 @@ static int mem_attrs_htab_eq PARAMS ((const void *,
static mem_attrs *get_mem_attrs PARAMS ((HOST_WIDE_INT, tree, rtx,
rtx, unsigned int,
enum machine_mode));
+static hashval_t reg_attrs_htab_hash PARAMS ((const void *));
+static int reg_attrs_htab_eq PARAMS ((const void *,
+ const void *));
+static reg_attrs *get_reg_attrs PARAMS ((tree, int));
static tree component_ref_for_mem_expr PARAMS ((tree));
static rtx gen_const_vector_0 PARAMS ((enum machine_mode));
@@ -323,6 +331,60 @@ get_mem_attrs (alias, expr, offset, size, align, mode)
return *slot;
}
+/* Returns a hash code for X (which is a really a reg_attrs *). */
+
+static hashval_t
+reg_attrs_htab_hash (x)
+ const void *x;
+{
+ reg_attrs *p = (reg_attrs *) x;
+
+ return ((p->offset * 1000) ^ (long) p->decl);
+}
+
+/* Returns non-zero if the value represented by X (which is really a
+ reg_attrs *) is the same as that given by Y (which is also really a
+ reg_attrs *). */
+
+static int
+reg_attrs_htab_eq (x, y)
+ const void *x;
+ const void *y;
+{
+ reg_attrs *p = (reg_attrs *) x;
+ reg_attrs *q = (reg_attrs *) y;
+
+ return (p->decl == q->decl && p->offset == q->offset);
+}
+/* Allocate a new reg_attrs structure and insert it into the hash table if
+ one identical to it is not already in the table. We are doing this for
+ MEM of mode MODE. */
+
+static reg_attrs *
+get_reg_attrs (decl, offset)
+ tree decl;
+ int offset;
+{
+ reg_attrs attrs;
+ void **slot;
+
+ /* If everything is the default, we can just return zero. */
+ if (decl == 0 && offset == 0)
+ return 0;
+
+ attrs.decl = decl;
+ attrs.offset = offset;
+
+ slot = htab_find_slot (reg_attrs_htab, &attrs, INSERT);
+ if (*slot == 0)
+ {
+ *slot = ggc_alloc (sizeof (reg_attrs));
+ memcpy (*slot, &attrs, sizeof (reg_attrs));
+ }
+
+ return *slot;
+}
+
/* Generate a new REG rtx. Make sure ORIGINAL_REGNO is set properly, and
don't attempt to share with the various global pieces of rtl (such as
frame_pointer_rtx). */
@@ -811,7 +873,7 @@ gen_reg_rtx (mode)
return gen_rtx_CONCAT (mode, realpart, imagpart);
}
- /* Make sure regno_pointer_align, regno_decl, and regno_reg_rtx are large
+ /* Make sure regno_pointer_align, and regno_reg_rtx are large
enough to have an element for this pseudo reg number. */
if (reg_rtx_no == f->emit->regno_pointer_align_length)
@@ -819,7 +881,6 @@ gen_reg_rtx (mode)
int old_size = f->emit->regno_pointer_align_length;
char *new;
rtx *new1;
- tree *new2;
new = ggc_realloc (f->emit->regno_pointer_align, old_size * 2);
memset (new + old_size, 0, old_size);
@@ -830,11 +891,6 @@ gen_reg_rtx (mode)
memset (new1 + old_size, 0, old_size * sizeof (rtx));
regno_reg_rtx = new1;
- new2 = (tree *) ggc_realloc (f->emit->regno_decl,
- old_size * 2 * sizeof (tree));
- memset (new2 + old_size, 0, old_size * sizeof (tree));
- f->emit->regno_decl = new2;
-
f->emit->regno_pointer_align_length = old_size * 2;
}
@@ -843,6 +899,70 @@ gen_reg_rtx (mode)
return val;
}
+/* Generate an register with same attributes as REG,
+ but offsetted by OFFSET. */
+
+rtx
+gen_rtx_REG_offset (reg, mode, regno, offset)
+ enum machine_mode mode;
+ unsigned int regno;
+ int offset;
+ rtx reg;
+{
+ rtx new = gen_rtx_REG (mode, regno);
+ REG_ATTRS (new) = get_reg_attrs (REG_EXPR (reg),
+ REG_OFFSET (reg) + offset);
+ return new;
+}
+
+/* Set the decl for MEM to DECL. */
+
+void
+set_reg_attrs_from_mem (reg, mem)
+ rtx reg;
+ rtx mem;
+{
+ if (MEM_OFFSET (mem) && GET_CODE (MEM_OFFSET (mem)) == CONST_INT)
+ REG_ATTRS (reg)
+ = get_reg_attrs (MEM_EXPR (mem), INTVAL (MEM_OFFSET (mem)));
+}
+
+/* Assign the RTX X to declaration T. */
+void
+set_decl_rtl (t, x)
+ tree t;
+ rtx x;
+{
+ DECL_CHECK (t)->decl.rtl = x;
+
+ if (!x)
+ return;
+ /* For register, we maitain the reverse information too. */
+ if (GET_CODE (x) == REG)
+ REG_ATTRS (x) = get_reg_attrs (t, 0);
+ else if (GET_CODE (x) == SUBREG)
+ REG_ATTRS (SUBREG_REG (x))
+ = get_reg_attrs (t, -SUBREG_BYTE (x));
+ if (GET_CODE (x) == CONCAT)
+ {
+ if (REG_P (XEXP (x, 0)))
+ REG_ATTRS (XEXP (x, 0)) = get_reg_attrs (t, 0);
+ if (REG_P (XEXP (x, 1)))
+ REG_ATTRS (XEXP (x, 1))
+ = get_reg_attrs (t, GET_MODE_UNIT_SIZE (GET_MODE (XEXP (x, 0))));
+ }
+ if (GET_CODE (x) == PARALLEL)
+ {
+ int i;
+ for (i = 0; i < XVECLEN (x, 0); i++)
+ {
+ rtx y = XVECEXP (x, 0, i);
+ if (REG_P (XEXP (y, 0)))
+ REG_ATTRS (XEXP (y, 0)) = get_reg_attrs (t, INTVAL (XEXP (y, 1)));
+ }
+ }
+}
+
/* Identify REG (which may be a CONCAT) as a user register. */
void
@@ -1921,6 +2041,19 @@ set_mem_attributes (ref, t, objectp)
set_mem_attributes_minus_bitpos (ref, t, objectp, 0);
}
+/* Set the decl for MEM to DECL. */
+
+void
+set_mem_attrs_from_reg (mem, reg)
+ rtx mem;
+ rtx reg;
+{
+ MEM_ATTRS (mem)
+ = get_mem_attrs (MEM_ALIAS_SET (mem), REG_EXPR (reg),
+ GEN_INT (REG_OFFSET (reg)),
+ MEM_SIZE (mem), MEM_ALIGN (mem), GET_MODE (mem));
+}
+
/* Set the alias set of MEM to SET. */
void
@@ -5216,10 +5349,6 @@ init_emit ()
= (rtx *) ggc_alloc_cleared (f->emit->regno_pointer_align_length
* sizeof (rtx));
- f->emit->regno_decl
- = (tree *) ggc_alloc_cleared (f->emit->regno_pointer_align_length
- * sizeof (tree));
-
/* Put copies of all the hard registers into regno_reg_rtx. */
memcpy (regno_reg_rtx,
static_regno_reg_rtx,
@@ -5323,6 +5452,8 @@ init_emit_once (line_numbers)
mem_attrs_htab = htab_create_ggc (37, mem_attrs_htab_hash,
mem_attrs_htab_eq, NULL);
+ reg_attrs_htab = htab_create_ggc (37, reg_attrs_htab_hash,
+ reg_attrs_htab_eq, NULL);
no_line_numbers = ! line_numbers;
diff --git a/gcc/final.c b/gcc/final.c
index a3a9e7c5350..103f65d7a1f 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -2622,12 +2622,7 @@ alter_subreg (xp)
else if (GET_CODE (y) == REG)
{
unsigned int regno = subreg_hard_regno (x, 1);
- PUT_CODE (x, REG);
- REGNO (x) = regno;
- ORIGINAL_REGNO (x) = ORIGINAL_REGNO (y);
- /* This field has a different meaning for REGs and SUBREGs. Make
- sure to clear it! */
- RTX_FLAG (x, used) = 0;
+ *xp = gen_rtx_REG_offset (y, GET_MODE (x), regno, SUBREG_BYTE (x));
}
else
abort ();
@@ -2893,11 +2888,8 @@ get_mem_expr_from_op (op, paddressp)
*paddressp = 0;
- if (op == NULL)
- return 0;
-
- if (GET_CODE (op) == REG && ORIGINAL_REGNO (op) >= FIRST_PSEUDO_REGISTER)
- return REGNO_DECL (ORIGINAL_REGNO (op));
+ if (GET_CODE (op) == REG)
+ return REG_EXPR (op);
else if (GET_CODE (op) != MEM)
return 0;
@@ -2941,16 +2933,22 @@ output_asm_operand_names (operands, oporder, nops)
for (i = 0; i < nops; i++)
{
int addressp;
- tree expr = get_mem_expr_from_op (operands[oporder[i]], &addressp);
+ rtx op = operands[oporder[i]];
+ tree expr = get_mem_expr_from_op (op, &addressp);
+ fprintf (asm_out_file, "%c%s",
+ wrote ? ',' : '\t', wrote ? "" : ASM_COMMENT_START);
+ wrote = 1;
if (expr)
{
- fprintf (asm_out_file, "%c%s %s",
- wrote ? ',' : '\t', wrote ? "" : ASM_COMMENT_START,
+ fprintf (asm_out_file, "%s",
addressp ? "*" : "");
print_mem_expr (asm_out_file, expr);
wrote = 1;
}
+ else if (REG_P (op) && ORIGINAL_REGNO (op)
+ && ORIGINAL_REGNO (op) != REGNO (op))
+ fprintf (asm_out_file, " tmp%i", ORIGINAL_REGNO (op));
}
}
diff --git a/gcc/function.c b/gcc/function.c
index c240788e30a..78347c9599d 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -5005,15 +5005,6 @@ assign_parms (fndecl)
set_mem_attributes (x, result, 1);
SET_DECL_RTL (result, x);
}
-
- if (GET_CODE (DECL_RTL (parm)) == REG)
- REGNO_DECL (REGNO (DECL_RTL (parm))) = parm;
- else if (GET_CODE (DECL_RTL (parm)) == CONCAT)
- {
- REGNO_DECL (REGNO (XEXP (DECL_RTL (parm), 0))) = parm;
- REGNO_DECL (REGNO (XEXP (DECL_RTL (parm), 1))) = parm;
- }
-
}
/* Output all parameter conversion instructions (possibly including calls)
diff --git a/gcc/function.h b/gcc/function.h
index 11c781750da..63e48f7db29 100644
--- a/gcc/function.h
+++ b/gcc/function.h
@@ -100,10 +100,6 @@ struct emit_status GTY(())
unsigned char * GTY ((length ("%h.regno_pointer_align_length")))
regno_pointer_align;
- /* Indexed by pseudo register number, if nonzero gives the decl
- corresponding to that register. */
- tree * GTY ((length ("%h.regno_pointer_align_length"))) regno_decl;
-
/* Indexed by pseudo register number, gives the rtx for that pseudo.
Allocated in parallel with regno_pointer_align.
@@ -119,7 +115,6 @@ struct emit_status GTY(())
#define seq_stack (cfun->emit->sequence_stack)
#define REGNO_POINTER_ALIGN(REGNO) (cfun->emit->regno_pointer_align[REGNO])
-#define REGNO_DECL(REGNO) (cfun->emit->regno_decl[REGNO])
struct expr_status GTY(())
{
diff --git a/gcc/gengtype.c b/gcc/gengtype.c
index cbaf7ac6d67..422214137ec 100644
--- a/gcc/gengtype.c
+++ b/gcc/gengtype.c
@@ -419,7 +419,7 @@ adjust_field_rtx_def (t, opt)
options_p nodot;
int i;
type_p rtx_tp, rtvec_tp, tree_tp, mem_attrs_tp, note_union_tp, scalar_tp;
- type_p bitmap_tp, basic_block_tp;
+ type_p bitmap_tp, basic_block_tp, reg_attrs_tp;
static const char * const rtx_name[NUM_RTX_CODE] = {
#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) NAME ,
@@ -443,6 +443,7 @@ adjust_field_rtx_def (t, opt)
rtvec_tp = create_pointer (find_structure ("rtvec_def", 0));
tree_tp = create_pointer (find_structure ("tree_node", 1));
mem_attrs_tp = create_pointer (find_structure ("mem_attrs", 0));
+ reg_attrs_tp = create_pointer (find_structure ("reg_attrs", 0));
bitmap_tp = create_pointer (find_structure ("bitmap_element_def", 0));
basic_block_tp = create_pointer (find_structure ("basic_block_def", 0));
scalar_tp = create_scalar_type ("rtunion scalar", 14);
@@ -523,6 +524,8 @@ adjust_field_rtx_def (t, opt)
t = scalar_tp, subname = "rtint";
else if (i == REG && aindex == 1)
t = scalar_tp, subname = "rtint";
+ else if (i == REG && aindex == 2)
+ t = reg_attrs_tp, subname = "rtreg";
else if (i == SCRATCH && aindex == 0)
t = scalar_tp, subname = "rtint";
else if (i == BARRIER && aindex >= 3)
diff --git a/gcc/integrate.c b/gcc/integrate.c
index 8feb845b9e4..6eef65038fc 100644
--- a/gcc/integrate.c
+++ b/gcc/integrate.c
@@ -1838,14 +1838,6 @@ integrate_decl_tree (let, map)
subst_constants (&r, NULL_RTX, map, 1);
SET_DECL_RTL (d, r);
- if (GET_CODE (r) == REG)
- REGNO_DECL (REGNO (r)) = d;
- else if (GET_CODE (r) == CONCAT)
- {
- REGNO_DECL (REGNO (XEXP (r, 0))) = d;
- REGNO_DECL (REGNO (XEXP (r, 1))) = d;
- }
-
apply_change_group ();
}
diff --git a/gcc/print-rtl.c b/gcc/print-rtl.c
index f61b09123d1..6930e76c5aa 100644
--- a/gcc/print-rtl.c
+++ b/gcc/print-rtl.c
@@ -409,6 +409,23 @@ print_rtx (in_rtx)
else
fprintf (outfile, " %d", value);
+ if (GET_CODE (in_rtx) == REG && REG_ATTRS (in_rtx))
+ {
+ fputs (" [", outfile);
+ if (ORIGINAL_REGNO (in_rtx) != REGNO (in_rtx))
+ fprintf (outfile, "orig:%i", ORIGINAL_REGNO (in_rtx));
+ if (REG_EXPR (in_rtx))
+ print_mem_expr (outfile, REG_EXPR (in_rtx));
+
+ if (REG_OFFSET (in_rtx))
+ {
+ fputc ('+', outfile);
+ fprintf (outfile, HOST_WIDE_INT_PRINT_DEC,
+ REG_OFFSET (in_rtx));
+ }
+ fputs (" ]", outfile);
+ }
+
if (is_insn && &INSN_CODE (in_rtx) == &XINT (in_rtx, i)
&& XINT (in_rtx, i) >= 0
&& (name = get_insn_name (XINT (in_rtx, i))) != NULL)
diff --git a/gcc/regclass.c b/gcc/regclass.c
index 4612f713bf4..21cb6ead80f 100644
--- a/gcc/regclass.c
+++ b/gcc/regclass.c
@@ -2520,7 +2520,7 @@ reg_scan_mark_refs (x, insn, note_flag, min_regno)
REG_POINTER (SET_DEST (x)) = 1;
/* If this is setting a register from a register or from a simple
- conversion of a register, propagate REG_DECL. */
+ conversion of a register, propagate REG_EXPR. */
if (GET_CODE (dest) == REG)
{
rtx src = SET_SRC (x);
@@ -2531,10 +2531,10 @@ reg_scan_mark_refs (x, insn, note_flag, min_regno)
|| (GET_CODE (src) == SUBREG && subreg_lowpart_p (src)))
src = XEXP (src, 0);
- if (GET_CODE (src) == REG && REGNO_DECL (REGNO (src)) == 0)
- REGNO_DECL (REGNO (src)) = REGNO_DECL (REGNO (dest));
- else if (GET_CODE (src) == REG && REGNO_DECL (REGNO (dest)) == 0)
- REGNO_DECL (REGNO (dest)) = REGNO_DECL (REGNO (src));
+ if (!REG_ATTRS (dest) && REG_P (src))
+ REG_ATTRS (dest) = REG_ATTRS (src);
+ if (!REG_ATTRS (dest) && GET_CODE (src) == MEM)
+ set_reg_attrs_from_mem (dest, src);
}
/* ... fall through ... */
diff --git a/gcc/reload1.c b/gcc/reload1.c
index 2479ac4c8a2..90625dbee67 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -2081,9 +2081,10 @@ alter_reg (i, from_reg)
/* If we have a decl for the original register, set it for the
memory. If this is a shared MEM, make a copy. */
- if (REGNO_DECL (i))
+ if (REG_EXPR (regno_reg_rtx[i])
+ && TREE_CODE_CLASS (TREE_CODE (REG_EXPR (regno_reg_rtx[i]))) == 'd')
{
- rtx decl = DECL_RTL_IF_SET (REGNO_DECL (i));
+ rtx decl = DECL_RTL_IF_SET (REG_EXPR (regno_reg_rtx[i]));
/* We can do this only for the DECLs home pseudo, not for
any copies of it, since otherwise when the stack slot
@@ -2094,7 +2095,7 @@ alter_reg (i, from_reg)
if (from_reg != -1 && spill_stack_slot[from_reg] == x)
x = copy_rtx (x);
- set_mem_expr (x, REGNO_DECL (i));
+ set_mem_attrs_from_reg (x, regno_reg_rtx[i]);
}
}
diff --git a/gcc/rtl.def b/gcc/rtl.def
index c1f812bc071..e3be833e15f 100644
--- a/gcc/rtl.def
+++ b/gcc/rtl.def
@@ -811,7 +811,7 @@ DEF_RTL_EXPR(VALUE, "value", "0", 'o')
pseudo register that got turned into a hard register.
This rtx needs to have as many (or more) fields as a MEM, since we
can change REG rtx's into MEMs during reload. */
-DEF_RTL_EXPR(REG, "reg", "i0", 'o')
+DEF_RTL_EXPR(REG, "reg", "i00", 'o')
/* A scratch register. This represents a register used only within a
single insn. It will be turned into a REG during register allocation
diff --git a/gcc/rtl.h b/gcc/rtl.h
index ec448305d16..7531d8a1cfa 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -103,6 +103,15 @@ typedef struct mem_attrs GTY(())
unsigned int align; /* Alignment of MEM in bits. */
} mem_attrs;
+/* Structure used to describe the attributes of a REG in similar way as
+ mem_attrs does for MEM above. */
+
+typedef struct reg_attrs GTY(())
+{
+ tree decl; /* decl corresponding to REG. */
+ HOST_WIDE_INT offset; /* Offset from start of DECL. */
+} reg_attrs;
+
/* Common union for an element of an rtx. */
union rtunion_def
@@ -120,6 +129,7 @@ union rtunion_def
tree rttree;
struct basic_block_def *bb;
mem_attrs *rtmem;
+ reg_attrs *rtreg;
};
typedef union rtunion_def rtunion;
@@ -499,7 +509,8 @@ do { \
#define X0BBDEF(RTX, N) (RTL_CHECK1 (RTX, N, '0').bb)
#define X0ADVFLAGS(RTX, N) (RTL_CHECK1 (RTX, N, '0').rt_addr_diff_vec_flags)
#define X0CSELIB(RTX, N) (RTL_CHECK1 (RTX, N, '0').rt_cselib)
-#define X0MEMATTR(RTX, N) (RTL_CHECK1 (RTX, N, '0').rtmem)
+#define X0MEMATTR(RTX, N) (RTL_CHECKC1 (RTX, N, MEM).rtmem)
+#define X0REGATTR(RTX, N) (RTL_CHECKC1 (RTX, N, REG).rtreg)
#define XCWINT(RTX, N, C) (RTL_CHECKC1 (RTX, N, C).rtwint)
#define XCINT(RTX, N, C) (RTL_CHECKC1 (RTX, N, C).rtint)
@@ -1128,6 +1139,10 @@ do { \
in the block and provide defaults if none specified. */
#define MEM_ATTRS(RTX) X0MEMATTR (RTX, 1)
+/* The register attribute block. We provide access macros for each value
+ in the block and provide defaults if none specified. */
+#define REG_ATTRS(RTX) X0REGATTR (RTX, 2)
+
/* For a MEM rtx, the alias set. If 0, this MEM is not in any alias
set, and may alias anything. Otherwise, the MEM can only alias
MEMs in the same alias set. This value is set in a
@@ -1161,6 +1176,14 @@ do { \
: (STRICT_ALIGNMENT && GET_MODE (RTX) != BLKmode \
? GET_MODE_ALIGNMENT (GET_MODE (RTX)) : BITS_PER_UNIT))
+/* For a REG rtx, the decl it is known to refer to, if it is known to
+ refer to part of a DECL. */
+#define REG_EXPR(RTX) (REG_ATTRS (RTX) == 0 ? 0 : REG_ATTRS (RTX)->decl)
+
+/* For a MEM rtx, the offset from the start of MEM_DECL, if known, as a
+ RTX that is always a CONST_INT. */
+#define REG_OFFSET(RTX) (REG_ATTRS (RTX) == 0 ? 0 : REG_ATTRS (RTX)->offset)
+
/* Copy the attributes that apply to memory locations from RHS to LHS. */
#define MEM_COPY_ATTRIBUTES(LHS, RHS) \
(MEM_VOLATILE_P (LHS) = MEM_VOLATILE_P (RHS), \
@@ -1365,6 +1388,8 @@ extern rtx copy_insn PARAMS ((rtx));
extern rtx gen_int_mode PARAMS ((HOST_WIDE_INT,
enum machine_mode));
extern rtx emit_copy_of_insn_after PARAMS ((rtx, rtx));
+extern void set_reg_attrs_from_mem PARAMS ((rtx, rtx));
+extern void set_mem_attrs_from_reg PARAMS ((rtx, rtx));
/* In rtl.c */
extern rtx rtx_alloc PARAMS ((RTX_CODE));
@@ -1382,6 +1407,8 @@ extern int rtx_equal_p PARAMS ((rtx, rtx));
/* In emit-rtl.c */
extern rtvec gen_rtvec_v PARAMS ((int, rtx *));
extern rtx gen_reg_rtx PARAMS ((enum machine_mode));
+extern rtx gen_rtx_REG_offset PARAMS ((rtx, enum machine_mode,
+ unsigned int, int));
extern rtx gen_label_rtx PARAMS ((void));
extern int subreg_hard_regno PARAMS ((rtx, int));
extern rtx gen_lowpart_common PARAMS ((enum machine_mode, rtx));
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index b0ddb65b24e..1cef92a211f 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -2568,7 +2568,7 @@ simplify_subreg (outermode, op, innermode, byte)
if (HARD_REGNO_MODE_OK (final_regno, outermode)
|| ! HARD_REGNO_MODE_OK (REGNO (op), innermode))
{
- rtx x = gen_rtx_REG (outermode, final_regno);
+ rtx x = gen_rtx_REG_offset (op, outermode, final_regno, byte);
/* Propagate original regno. We don't have any way to specify
the offset inside original regno, so do so only for lowpart.
diff --git a/gcc/stmt.c b/gcc/stmt.c
index adc7114c7e2..8d7d1435def 100644
--- a/gcc/stmt.c
+++ b/gcc/stmt.c
@@ -3908,14 +3908,6 @@ expand_decl (decl)
SET_DECL_RTL (decl, gen_reg_rtx (reg_mode));
- if (GET_CODE (DECL_RTL (decl)) == REG)
- REGNO_DECL (REGNO (DECL_RTL (decl))) = decl;
- else if (GET_CODE (DECL_RTL (decl)) == CONCAT)
- {
- REGNO_DECL (REGNO (XEXP (DECL_RTL (decl), 0))) = decl;
- REGNO_DECL (REGNO (XEXP (DECL_RTL (decl), 1))) = decl;
- }
-
mark_user_reg (DECL_RTL (decl));
if (POINTER_TYPE_P (type))
diff --git a/gcc/tree.h b/gcc/tree.h
index 626c49d44cf..0b6b4e0fea2 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1517,7 +1517,7 @@ struct tree_type GTY(())
? (NODE)->decl.rtl \
: (make_decl_rtl (NODE, NULL), (NODE)->decl.rtl))
/* Set the DECL_RTL for NODE to RTL. */
-#define SET_DECL_RTL(NODE, RTL) (DECL_CHECK (NODE)->decl.rtl = (RTL))
+#define SET_DECL_RTL(NODE, RTL) set_decl_rtl (NODE, RTL)
/* Returns nonzero if the DECL_RTL for NODE has already been set. */
#define DECL_RTL_SET_P(NODE) (DECL_CHECK (NODE)->decl.rtl != NULL)
/* Copy the RTL from NODE1 to NODE2. If the RTL was not set for
@@ -3173,6 +3173,9 @@ extern void dump_end PARAMS ((enum tree_dump_index, FILE *));
extern void dump_node PARAMS ((tree, int, FILE *));
extern int dump_switch_p PARAMS ((const char *));
extern const char *dump_flag_name PARAMS ((enum tree_dump_index));
+/* Assign the RTX to declaration. */
+
+extern void set_decl_rtl PARAMS ((tree, rtx));
/* Redefine abort to report an internal error w/o coredump, and