From 998d7deb143c6511c68e21abb811af9f5524f89d Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sun, 2 Dec 2001 11:04:23 -0800 Subject: [PATCH] rtl.h (mem_attrs): Rename decl to expr; adjust all users. * rtl.h (mem_attrs): Rename decl to expr; adjust all users. (MEM_EXPR): Rename from MEM_DECL; adjust all users. * emit-rtl.c (set_mem_expr): Rename from set_mem_decl. * expr.h, final.c, reload1.c: Adjust users. * alias.c (nonoverlapping_component_refs_p): New. (decl_for_component_ref, adjust_offset_for_component_ref): New. (nonoverlapping_memrefs_p): Use them. * emit-rtl.c (component_ref_for_mem_expr): New. (set_mem_attributes): Use it. (set_mem_offset): New. * expr.c (expand_assignment): Call set_mem_attributes for inner references; adjust the memory offset as needed. * print-rtl.c (print_mem_expr): New. (print_rtx): Use it. From-SVN: r47534 --- gcc/ChangeLog | 18 +++++++ gcc/alias.c | 164 +++++++++++++++++++++++++++++++++++++++++++++++++++----- gcc/emit-rtl.c | 112 +++++++++++++++++++++++++++++++------- gcc/expr.c | 21 +++++++- gcc/expr.h | 7 ++- gcc/final.c | 35 ++++++------ gcc/print-rtl.c | 31 ++++++++--- gcc/reload1.c | 2 +- gcc/rtl.h | 9 ++-- 9 files changed, 335 insertions(+), 64 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2e3bd95..f7c1b46 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,21 @@ +2001-12-02 Richard Henderson + + * rtl.h (mem_attrs): Rename decl to expr; adjust all users. + (MEM_EXPR): Rename from MEM_DECL; adjust all users. + * emit-rtl.c (set_mem_expr): Rename from set_mem_decl. + * expr.h, final.c, reload1.c: Adjust users. + + * alias.c (nonoverlapping_component_refs_p): New. + (decl_for_component_ref, adjust_offset_for_component_ref): New. + (nonoverlapping_memrefs_p): Use them. + * emit-rtl.c (component_ref_for_mem_expr): New. + (set_mem_attributes): Use it. + (set_mem_offset): New. + * expr.c (expand_assignment): Call set_mem_attributes for + inner references; adjust the memory offset as needed. + * print-rtl.c (print_mem_expr): New. + (print_rtx): Use it. + Sun Dec 2 09:22:25 2001 Douglas B. Rupp * config/x-interix3 (SYSTEM_HEADER_DIR): Put back default. diff --git a/gcc/alias.c b/gcc/alias.c index da9ca04..21563ec 100644 --- a/gcc/alias.c +++ b/gcc/alias.c @@ -103,6 +103,9 @@ static alias_set_entry get_alias_set_entry PARAMS ((HOST_WIDE_INT)); static rtx fixed_scalar_and_varying_struct_p PARAMS ((rtx, rtx, rtx, rtx, int (*) (rtx, int))); static int aliases_everything_p PARAMS ((rtx)); +static bool nonoverlapping_component_refs_p PARAMS ((tree, tree)); +static tree decl_for_component_ref PARAMS ((tree)); +static rtx adjust_offset_for_component_ref PARAMS ((tree, rtx)); static int nonoverlapping_memrefs_p PARAMS ((rtx, rtx)); static int write_dependence_p PARAMS ((rtx, rtx, int)); static int nonlocal_mentioned_p PARAMS ((rtx)); @@ -1736,23 +1739,158 @@ aliases_everything_p (mem) return 0; } -/* Return nonzero if we can deterimine the decls corresponding to memrefs +/* Return true if we can determine that the fields referenced cannot + overlap for any pair of objects. */ + +static bool +nonoverlapping_component_refs_p (x, y) + tree x, y; +{ + tree fieldx, fieldy, typex, typey, orig_y; + + do + { + /* The comparison has to be done at a common type, since we don't + know how the inheritance heirarchy works. */ + orig_y = y; + do + { + fieldx = TREE_OPERAND (x, 1); + typex = DECL_FIELD_CONTEXT (fieldx); + + y = orig_y; + do + { + fieldy = TREE_OPERAND (y, 1); + typey = DECL_FIELD_CONTEXT (fieldy); + + if (typex == typey) + goto found; + + y = TREE_OPERAND (y, 0); + } + while (y && TREE_CODE (y) == COMPONENT_REF); + + x = TREE_OPERAND (x, 0); + } + while (x && TREE_CODE (x) == COMPONENT_REF); + + /* Never found a common type. */ + return false; + + found: + /* If we're left with accessing different fields of a structure, + then no overlap. */ + if (TREE_CODE (typex) == RECORD_TYPE + && fieldx != fieldy) + return true; + + /* The comparison on the current field failed. If we're accessing + a very nested structure, look at the next outer level. */ + x = TREE_OPERAND (x, 0); + y = TREE_OPERAND (y, 0); + } + while (x && y + && TREE_CODE (x) == COMPONENT_REF + && TREE_CODE (y) == COMPONENT_REF); + + return false; +} + +/* Look at the bottom of the COMPONENT_REF list for a DECL, and return it. */ + +static tree +decl_for_component_ref (x) + tree x; +{ + do + { + x = TREE_OPERAND (x, 0); + } + while (x && TREE_CODE (x) == COMPONENT_REF); + + return x && DECL_P (x) ? x : NULL_TREE; +} + +/* Walk up the COMPONENT_REF list and adjust OFFSET to compensate for the + offset of the field reference. */ + +static rtx +adjust_offset_for_component_ref (x, offset) + tree x; + rtx offset; +{ + HOST_WIDE_INT ioffset; + + if (! offset) + return NULL_RTX; + + ioffset = INTVAL (offset); + do + { + tree field = TREE_OPERAND (x, 1); + + if (! host_integerp (DECL_FIELD_OFFSET (field), 1)) + return NULL_RTX; + ioffset += (tree_low_cst (DECL_FIELD_OFFSET (field), 1) + + (tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1) + / BITS_PER_UNIT)); + + x = TREE_OPERAND (x, 0); + } + while (x && TREE_CODE (x) == COMPONENT_REF); + + return GEN_INT (ioffset); +} + +/* Return nonzero if we can deterimine the exprs corresponding to memrefs X and Y and they do not overlap. */ static int nonoverlapping_memrefs_p (x, y) rtx x, y; { + tree exprx = MEM_EXPR (x), expry = MEM_EXPR (y); rtx rtlx, rtly; rtx basex, basey; + rtx moffsetx, moffsety; HOST_WIDE_INT offsetx = 0, offsety = 0, sizex, sizey, tem; - /* Unless both have decls, we can't tell anything. */ - if (MEM_DECL (x) == 0 || MEM_DECL (y) == 0) + /* Unless both have exprs, we can't tell anything. */ + if (exprx == 0 || expry == 0) + return 0; + + /* If both are field references, we may be able to determine something. */ + if (TREE_CODE (exprx) == COMPONENT_REF + && TREE_CODE (expry) == COMPONENT_REF + && nonoverlapping_component_refs_p (exprx, expry)) + return 1; + + /* If the field reference test failed, look at the DECLs involved. */ + moffsetx = MEM_OFFSET (x); + if (TREE_CODE (exprx) == COMPONENT_REF) + { + tree t = decl_for_component_ref (exprx); + if (! t) + return 0; + moffsetx = adjust_offset_for_component_ref (exprx, moffsetx); + exprx = t; + } + moffsety = MEM_OFFSET (y); + if (TREE_CODE (expry) == COMPONENT_REF) + { + tree t = decl_for_component_ref (expry); + if (! t) + return 0; + moffsety = adjust_offset_for_component_ref (expry, moffsety); + expry = t; + } + + if (! DECL_P (exprx) || ! DECL_P (expry)) return 0; - rtlx = DECL_RTL (MEM_DECL (x)); - rtly = DECL_RTL (MEM_DECL (y)); + rtlx = DECL_RTL (exprx); + rtly = DECL_RTL (expry); /* If either RTL is not a MEM, it must be a REG or CONCAT, meaning they can't overlap unless they are the same because we never reuse that part @@ -1784,26 +1922,26 @@ nonoverlapping_memrefs_p (x, y) || (CONSTANT_P (basey) && REG_P (basex) && REGNO_PTR_FRAME_P (REGNO (basex)))); - sizex = (GET_CODE (rtlx) != MEM ? GET_MODE_SIZE (GET_MODE (rtlx)) + sizex = (GET_CODE (rtlx) != MEM ? (int) GET_MODE_SIZE (GET_MODE (rtlx)) : MEM_SIZE (rtlx) ? INTVAL (MEM_SIZE (rtlx)) : -1); - sizey = (GET_CODE (rtly) != MEM ? GET_MODE_SIZE (GET_MODE (rtly)) + sizey = (GET_CODE (rtly) != MEM ? (int) GET_MODE_SIZE (GET_MODE (rtly)) : MEM_SIZE (rtly) ? INTVAL (MEM_SIZE (rtly)) : -1); /* If we have an offset for either memref, it can update the values computed above. */ - if (MEM_OFFSET (x)) - offsetx += INTVAL (MEM_OFFSET (x)), sizex -= INTVAL (MEM_OFFSET (x)); - if (MEM_OFFSET (y)) - offsety += INTVAL (MEM_OFFSET (y)), sizey -= INTVAL (MEM_OFFSET (y)); + if (moffsetx) + offsetx += INTVAL (moffsetx), sizex -= INTVAL (moffsetx); + if (moffsety) + offsety += INTVAL (moffsety), sizey -= INTVAL (moffsety); /* If a memref has both a size and an offset, we can use the smaller size. We can't do this if the offset isn't known because we must view this memref as being anywhere inside the DECL's MEM. */ - if (MEM_SIZE (x) && MEM_OFFSET (x)) + if (MEM_SIZE (x) && moffsetx) sizex = INTVAL (MEM_SIZE (x)); - if (MEM_SIZE (y) && MEM_OFFSET (y)) + if (MEM_SIZE (y) && moffsety) sizey = INTVAL (MEM_SIZE (y)); /* Put the values of the memref with the lower offset in X's values. */ diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index e7afacd..d25e549 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -195,6 +195,7 @@ static void mem_attrs_mark PARAMS ((const void *)); static mem_attrs *get_mem_attrs PARAMS ((HOST_WIDE_INT, tree, rtx, rtx, unsigned int, enum machine_mode)); +static tree component_ref_for_mem_expr PARAMS ((tree)); /* Probability of the conditional branch currently proceeded by try_split. Set to -1 otherwise. */ @@ -232,7 +233,7 @@ mem_attrs_htab_hash (x) return (p->alias ^ (p->align * 1000) ^ ((p->offset ? INTVAL (p->offset) : 0) * 50000) ^ ((p->size ? INTVAL (p->size) : 0) * 2500000) - ^ (long) p->decl); + ^ (size_t) p->expr); } /* Returns non-zero if the value represented by X (which is really a @@ -247,7 +248,7 @@ mem_attrs_htab_eq (x, y) mem_attrs *p = (mem_attrs *) x; mem_attrs *q = (mem_attrs *) y; - return (p->alias == q->alias && p->decl == q->decl && p->offset == q->offset + return (p->alias == q->alias && p->expr == q->expr && p->offset == q->offset && p->size == q->size && p->align == q->align); } @@ -260,8 +261,8 @@ mem_attrs_mark (x) { mem_attrs *p = (mem_attrs *) x; - if (p->decl) - ggc_mark_tree (p->decl); + if (p->expr) + ggc_mark_tree (p->expr); if (p->offset) ggc_mark_rtx (p->offset); @@ -275,9 +276,9 @@ mem_attrs_mark (x) MEM of mode MODE. */ static mem_attrs * -get_mem_attrs (alias, decl, offset, size, align, mode) +get_mem_attrs (alias, expr, offset, size, align, mode) HOST_WIDE_INT alias; - tree decl; + tree expr; rtx offset; rtx size; unsigned int align; @@ -287,7 +288,7 @@ get_mem_attrs (alias, decl, offset, size, align, mode) void **slot; /* If everything is the default, we can just return zero. */ - if (alias == 0 && decl == 0 && offset == 0 + if (alias == 0 && expr == 0 && offset == 0 && (size == 0 || (mode != BLKmode && GET_MODE_SIZE (mode) == INTVAL (size))) && (align == BITS_PER_UNIT @@ -295,7 +296,7 @@ get_mem_attrs (alias, decl, offset, size, align, mode) return 0; attrs.alias = alias; - attrs.decl = decl; + attrs.expr = expr; attrs.offset = offset; attrs.size = size; attrs.align = align; @@ -1636,6 +1637,26 @@ reverse_comparison (insn) } } +/* Within a MEM_EXPR, we care about either (1) a component ref of a decl, + or (2) a component ref of something variable. Represent the later with + a NULL expression. */ + +static tree +component_ref_for_mem_expr (ref) + tree ref; +{ + tree inner = TREE_OPERAND (ref, 0); + + if (TREE_CODE (inner) == COMPONENT_REF) + inner = component_ref_for_mem_expr (inner); + else if (! DECL_P (inner)) + inner = NULL_TREE; + + if (inner == TREE_OPERAND (ref, 0)) + return ref; + else + return build (COMPONENT_REF, TREE_TYPE (ref), inner, TREE_OPERAND (ref, 1)); +} /* Given REF, a MEM, and T, either the type of X or the expression corresponding to REF, set the memory attributes. OBJECTP is nonzero @@ -1648,7 +1669,7 @@ set_mem_attributes (ref, t, objectp) int objectp; { HOST_WIDE_INT alias = MEM_ALIAS_SET (ref); - tree decl = MEM_DECL (ref); + tree expr = MEM_EXPR (ref); rtx offset = MEM_OFFSET (ref); rtx size = MEM_SIZE (ref); unsigned int align = MEM_ALIGN (ref); @@ -1716,8 +1737,8 @@ set_mem_attributes (ref, t, objectp) /* If this is a decl, set the attributes of the MEM from it. */ if (DECL_P (t)) { - decl = t; - offset = GEN_INT (0); + expr = t; + offset = const0_rtx; size = (DECL_SIZE_UNIT (t) && host_integerp (DECL_SIZE_UNIT (t), 1) ? GEN_INT (tree_low_cst (DECL_SIZE_UNIT (t), 1)) : 0); @@ -1732,11 +1753,51 @@ set_mem_attributes (ref, t, objectp) align = CONSTANT_ALIGNMENT (t, align); #endif } + + /* If this is a field reference and not a bit-field, record it. */ + /* ??? There is some information that can be gleened from bit-fields, + such as the word offset in the structure that might be modified. + But skip it for now. */ + else if (TREE_CODE (t) == COMPONENT_REF + && ! DECL_BIT_FIELD (TREE_OPERAND (t, 1))) + { + expr = component_ref_for_mem_expr (t); + offset = const0_rtx; + /* ??? Any reason the field size would be different than + the size we got from the type? */ + } + + /* If this is an array reference, look for an outer field reference. */ + else if (TREE_CODE (t) == ARRAY_REF) + { + tree off_tree = size_zero_node; + + do + { + off_tree + = fold (build (PLUS_EXPR, sizetype, + fold (build (MULT_EXPR, sizetype, + TREE_OPERAND (t, 1), + TYPE_SIZE_UNIT (TREE_TYPE (t)))), + off_tree)); + t = TREE_OPERAND (t, 0); + } + while (TREE_CODE (t) == ARRAY_REF); + + if (TREE_CODE (t) == COMPONENT_REF) + { + expr = component_ref_for_mem_expr (t); + if (host_integerp (off_tree, 1)) + offset = GEN_INT (tree_low_cst (off_tree, 1)); + /* ??? Any reason the field size would be different than + the size we got from the type? */ + } + } } /* Now set the attributes we computed above. */ MEM_ATTRS (ref) - = get_mem_attrs (alias, decl, offset, size, align, GET_MODE (ref)); + = get_mem_attrs (alias, expr, offset, size, align, GET_MODE (ref)); /* If this is already known to be a scalar or aggregate, we are done. */ if (MEM_IN_STRUCT_P (ref) || MEM_SCALAR_P (ref)) @@ -1763,7 +1824,7 @@ set_mem_alias_set (mem, set) abort (); #endif - MEM_ATTRS (mem) = get_mem_attrs (set, MEM_DECL (mem), MEM_OFFSET (mem), + MEM_ATTRS (mem) = get_mem_attrs (set, MEM_EXPR (mem), MEM_OFFSET (mem), MEM_SIZE (mem), MEM_ALIGN (mem), GET_MODE (mem)); } @@ -1775,22 +1836,33 @@ set_mem_align (mem, align) rtx mem; unsigned int align; { - MEM_ATTRS (mem) = get_mem_attrs (MEM_ALIAS_SET (mem), MEM_DECL (mem), + MEM_ATTRS (mem) = get_mem_attrs (MEM_ALIAS_SET (mem), MEM_EXPR (mem), MEM_OFFSET (mem), MEM_SIZE (mem), align, GET_MODE (mem)); } -/* Set the decl for MEM to DECL. */ +/* Set the expr for MEM to EXPR. */ void -set_mem_decl (mem, decl) +set_mem_expr (mem, expr) rtx mem; - tree decl; + tree expr; { MEM_ATTRS (mem) - = get_mem_attrs (MEM_ALIAS_SET (mem), decl, MEM_OFFSET (mem), + = get_mem_attrs (MEM_ALIAS_SET (mem), expr, MEM_OFFSET (mem), MEM_SIZE (mem), MEM_ALIGN (mem), GET_MODE (mem)); } + +/* Set the offset of MEM to OFFSET. */ + +void +set_mem_offset (mem, offset) + rtx mem, offset; +{ + MEM_ATTRS (mem) = get_mem_attrs (MEM_ALIAS_SET (mem), MEM_EXPR (mem), + offset, MEM_SIZE (mem), MEM_ALIGN (mem), + GET_MODE (mem)); +} /* Return a memory reference like MEMREF, but with its mode changed to MODE and its address changed to ADDR. (VOIDmode means don't change the mode. @@ -1907,7 +1979,7 @@ adjust_address_1 (memref, mode, offset, validate, adjust) else if (MEM_SIZE (memref)) size = plus_constant (MEM_SIZE (memref), -offset); - MEM_ATTRS (new) = get_mem_attrs (MEM_ALIAS_SET (memref), MEM_DECL (memref), + MEM_ATTRS (new) = get_mem_attrs (MEM_ALIAS_SET (memref), MEM_EXPR (memref), memoffset, size, memalign, GET_MODE (new)); /* At some point, we should validate that this offset is within the object, @@ -1948,7 +2020,7 @@ offset_address (memref, offset, pow2) /* Update the alignment to reflect the offset. Reset the offset, which we don't know. */ - MEM_ATTRS (new) = get_mem_attrs (MEM_ALIAS_SET (memref), MEM_DECL (memref), + MEM_ATTRS (new) = get_mem_attrs (MEM_ALIAS_SET (memref), MEM_EXPR (memref), 0, 0, MIN (MEM_ALIGN (memref), pow2 * BITS_PER_UNIT), GET_MODE (new)); diff --git a/gcc/expr.c b/gcc/expr.c index eb7f2d3..659ff03 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -3603,7 +3603,6 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra, } emit_move_insn (dest, x); - } if (current_function_check_memory_usage && ! in_check_memory_usage) @@ -3768,6 +3767,26 @@ expand_assignment (to, from, want_value, suggest_reg) highest_pow2_factor (offset)); } + if (GET_CODE (to_rtx) == MEM) + { + tree old_expr = MEM_EXPR (to_rtx); + + /* If the field is at offset zero, we could have been given the + DECL_RTX of the parent struct. Don't munge it. */ + to_rtx = shallow_copy_rtx (to_rtx); + + set_mem_attributes (to_rtx, to, 0); + + /* If we changed MEM_EXPR, that means we're now referencing + the COMPONENT_REF, which means that MEM_OFFSET must be + relative to that field. But we've not yet reflected BITPOS + in TO_RTX. This will be done in store_field. Adjust for + that by biasing MEM_OFFSET by -bitpos. */ + if (MEM_EXPR (to_rtx) != old_expr && MEM_OFFSET (to_rtx) + && (bitpos / BITS_PER_UNIT) != 0) + set_mem_offset (to_rtx, GEN_INT (INTVAL (MEM_OFFSET (to_rtx)) + - (bitpos / BITS_PER_UNIT))); + } /* Deal with volatile and readonly fields. The former is only done for MEM. Also set MEM_KEEP_ALIAS_SET_P if needed. */ diff --git a/gcc/expr.h b/gcc/expr.h index 4275b81..aa4bde6 100644 --- a/gcc/expr.h +++ b/gcc/expr.h @@ -614,8 +614,11 @@ extern void set_mem_alias_set PARAMS ((rtx, HOST_WIDE_INT)); /* Set the alignment of MEM to ALIGN bits. */ extern void set_mem_align PARAMS ((rtx, unsigned int)); -/* Set the DECL for MEM to DECL. */ -extern void set_mem_decl PARAMS ((rtx, tree)); +/* Set the expr for MEM to EXPR. */ +extern void set_mem_expr PARAMS ((rtx, tree)); + +/* Set the offset for MEM to OFFSET. */ +extern void set_mem_offset PARAMS ((rtx, rtx)); /* Return a memory reference like MEMREF, but with its mode changed to MODE and its address changed to ADDR. diff --git a/gcc/final.c b/gcc/final.c index 7af2c1f..158da0b 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -245,7 +245,7 @@ static int add_bb_string PARAMS ((const char *, int)); static void notice_source_line PARAMS ((rtx)); static rtx walk_alter_subreg PARAMS ((rtx *)); static void output_asm_name PARAMS ((void)); -static tree get_decl_from_op PARAMS ((rtx, int *)); +static tree get_mem_expr_from_op PARAMS ((rtx, int *)); static void output_asm_operand_names PARAMS ((rtx *, int *, int)); static void output_operand PARAMS ((rtx, int)); #ifdef LEAF_REGISTERS @@ -3302,16 +3302,16 @@ output_asm_name () } } -/* If OP is a REG or MEM and we can find a decl corresponding to it or - its address, return that decl. Set *PADDRESSP to 1 if the decl +/* If OP is a REG or MEM and we can find a MEM_EXPR corresponding to it + or its address, return that expr . Set *PADDRESSP to 1 if the expr corresponds to the address of the object and 0 if to the object. */ static tree -get_decl_from_op (op, paddressp) +get_mem_expr_from_op (op, paddressp) rtx op; int *paddressp; { - tree decl; + tree expr; int inner_addressp; *paddressp = 0; @@ -3321,8 +3321,8 @@ get_decl_from_op (op, paddressp) else if (GET_CODE (op) != MEM) return 0; - if (MEM_DECL (op) != 0) - return MEM_DECL (op); + if (MEM_EXPR (op) != 0) + return MEM_EXPR (op); /* Otherwise we have an address, so indicate it and look at the address. */ *paddressp = 1; @@ -3331,18 +3331,18 @@ get_decl_from_op (op, paddressp) /* First check if we have a decl for the address, then look at the right side if it is a PLUS. Otherwise, strip off arithmetic and keep looking. But don't allow the address to itself be indirect. */ - if ((decl = get_decl_from_op (op, &inner_addressp)) && ! inner_addressp) - return decl; + if ((expr = get_mem_expr_from_op (op, &inner_addressp)) && ! inner_addressp) + return expr; else if (GET_CODE (op) == PLUS - && (decl = get_decl_from_op (XEXP (op, 1), &inner_addressp))) - return decl; + && (expr = get_mem_expr_from_op (XEXP (op, 1), &inner_addressp))) + return expr; while (GET_RTX_CLASS (GET_CODE (op)) == '1' || GET_RTX_CLASS (GET_CODE (op)) == '2') op = XEXP (op, 0); - decl = get_decl_from_op (op, &inner_addressp); - return inner_addressp ? 0 : decl; + expr = get_mem_expr_from_op (op, &inner_addressp); + return inner_addressp ? 0 : expr; } /* Output operand names for assembler instructions. OPERANDS is the @@ -3361,13 +3361,14 @@ output_asm_operand_names (operands, oporder, nops) for (i = 0; i < nops; i++) { int addressp; - tree decl = get_decl_from_op (operands[oporder[i]], &addressp); + tree expr = get_mem_expr_from_op (operands[oporder[i]], &addressp); - if (decl && DECL_NAME (decl)) + if (expr) { - fprintf (asm_out_file, "%c%s %s%s", + fprintf (asm_out_file, "%c%s %s", wrote ? ',' : '\t', wrote ? "" : ASM_COMMENT_START, - addressp ? "*" : "", IDENTIFIER_POINTER (DECL_NAME (decl))); + addressp ? "*" : ""); + print_mem_expr (asm_out_file, expr); wrote = 1; } } diff --git a/gcc/print-rtl.c b/gcc/print-rtl.c index 3213a51..b819d14 100644 --- a/gcc/print-rtl.c +++ b/gcc/print-rtl.c @@ -77,6 +77,28 @@ int dump_for_graph; /* Nonzero to dump all call_placeholder alternatives. */ static int debug_call_placeholder_verbose; +void +print_mem_expr (outfile, expr) + FILE *outfile; + tree expr; +{ + if (TREE_CODE (expr) == COMPONENT_REF) + { + if (TREE_OPERAND (expr, 0)) + print_mem_expr (outfile, TREE_OPERAND (expr, 0)); + else + fputs (" ", outfile); + fprintf (outfile, ".%s", + IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (expr, 1)))); + } + else if (DECL_NAME (expr)) + fprintf (outfile, " %s", IDENTIFIER_POINTER (DECL_NAME (expr))); + else if (TREE_CODE (expr) == RESULT_DECL) + fputs (" ", outfile); + else + fputs (" ", outfile); +} + /* Print IN_RTX onto OUTFILE. This is the recursive part of printing. */ static void @@ -456,12 +478,9 @@ print_rtx (in_rtx) case MEM: fputs (" [", outfile); fprintf (outfile, HOST_WIDE_INT_PRINT_DEC, MEM_ALIAS_SET (in_rtx)); - if (MEM_DECL (in_rtx)) - fprintf (outfile, " %s", - DECL_NAME (MEM_DECL (in_rtx)) - ? IDENTIFIER_POINTER (DECL_NAME (MEM_DECL (in_rtx))) - : TREE_CODE (MEM_DECL (in_rtx)) == RESULT_DECL ? "" - : ""); + + if (MEM_EXPR (in_rtx)) + print_mem_expr (outfile, MEM_EXPR (in_rtx)); if (MEM_OFFSET (in_rtx)) { diff --git a/gcc/reload1.c b/gcc/reload1.c index fa17d53..58019b0 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -2059,7 +2059,7 @@ alter_reg (i, from_reg) if (from_reg != -1 && spill_stack_slot[from_reg] == x) x = copy_rtx (x); - set_mem_decl (x, REGNO_DECL (i)); + set_mem_expr (x, REGNO_DECL (i)); } /* Save the stack slot for later. */ diff --git a/gcc/rtl.h b/gcc/rtl.h index 31dabb8..baafcdc 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -92,7 +92,7 @@ typedef struct typedef struct { HOST_WIDE_INT alias; /* Memory alias set. */ - tree decl; /* decl corresponding to MEM. */ + tree expr; /* expr corresponding to MEM. */ rtx offset; /* Offset from start of DECL, as CONST_INT. */ rtx size; /* Size in bytes, as a CONST_INT. */ unsigned int align; /* Alignment of MEM in bits. */ @@ -904,10 +904,10 @@ extern unsigned int subreg_regno PARAMS ((rtx)); #define MEM_ALIAS_SET(RTX) (MEM_ATTRS (RTX) == 0 ? 0 : MEM_ATTRS (RTX)->alias) /* For a MEM rtx, the decl it is known to refer to, if it is known to - refer to part of a DECL. */ -#define MEM_DECL(RTX) (MEM_ATTRS (RTX) == 0 ? 0 : MEM_ATTRS (RTX)->decl) + refer to part of a DECL. It may also be a COMPONENT_REF. */ +#define MEM_EXPR(RTX) (MEM_ATTRS (RTX) == 0 ? 0 : MEM_ATTRS (RTX)->expr) -/* For a MEM rtx, the offset from the start of MEM_DECL, if known, as a +/* For a MEM rtx, the offset from the start of MEM_EXPR, if known, as a RTX that is always a CONST_INT. */ #define MEM_OFFSET(RTX) (MEM_ATTRS (RTX) == 0 ? 0 : MEM_ATTRS (RTX)->offset) @@ -1865,6 +1865,7 @@ extern void debug_rtx_list PARAMS ((rtx, int)); extern void debug_rtx_range PARAMS ((rtx, rtx)); extern rtx debug_rtx_find PARAMS ((rtx, int)); #ifdef BUFSIZ +extern void print_mem_expr PARAMS ((FILE *, tree)); extern void print_rtl PARAMS ((FILE *, rtx)); extern void print_simple_rtl PARAMS ((FILE *, rtx)); extern int print_rtl_single PARAMS ((FILE *, rtx)); -- 2.7.4