diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 33bf8b21808..751e583ae39 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,24 @@ +Wed Oct 17 05:26:39 2001 Richard Kenner + + * Makefile.in (print-rtl.o): Depend on TREE_H. + * alias.c (get_alias_set): Make two passes over objects to first + see if inner object is access via restricted pointer. + Defer allocating alias set for restricted pointer until here. + Call find_placeholder with second arg nonzero. + Minor cleanups. + * emit-rtl.c (set_mem_attributes): Set more attributes. + (set_mem_align, change_address, adjust_address_1): New functions. + (change_address_1): Now static. + (adjust_address, adjust_address_nv): Deleted. + (replace_equiv_address): Call change_address_1. + * expr.c (get_inner_reference): Handle PLACEHOLDER_EXPR. + (find_placeholder): Get starting point from PLIST arg. + (expand_expr, case PLACEHOLDER_EXPR): Initialize find_placeholder arg. + * expr.h (set_mem_align, change_address, adjust_address_1): New decls. + (adjust_address, adjust_address_nv): New macros. + * print-rtl.c (tree.h): New include. + (print_rtx, case MEM): Print all memory attributes. + 2001-10-17 Richard Henderson * config/alpha/alpha.c (direct_call_operand): Don't fall off end. diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 018481681b3..27a3111b113 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1381,8 +1381,8 @@ rtl-error.o: rtl-error.c system.h $(RTL_H) $(INSN_ATTR_H) insn-config.h \ rtl.o : rtl.c $(GCONFIG_H) $(SYSTEM_H) $(RTL_H) real.h $(GGC_H) errors.h $(CC) -c $(ALL_CFLAGS) -DGENERATOR_FILE $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) -print-rtl.o : print-rtl.c $(GCONFIG_H) $(SYSTEM_H) $(RTL_H) hard-reg-set.h \ - $(BASIC_BLOCK_H) +print-rtl.o : print-rtl.c $(GCONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) \ + hard-reg-set.h $(BASIC_BLOCK_H) $(CC) -c $(ALL_CFLAGS) -DGENERATOR_FILE $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) rtlanal.o : rtlanal.c $(CONFIG_H) $(SYSTEM_H) toplev.h $(RTL_H) hard-reg-set.h diff --git a/gcc/alias.c b/gcc/alias.c index 53de65fab0c..af0141f8cb3 100644 --- a/gcc/alias.c +++ b/gcc/alias.c @@ -99,7 +99,7 @@ static int can_address_p PARAMS ((tree)); static rtx find_base_value PARAMS ((rtx)); static int mems_in_disjoint_alias_sets_p PARAMS ((rtx, rtx)); static int insert_subset_children PARAMS ((splay_tree_node, void*)); -static tree find_base_decl PARAMS ((tree)); +static tree find_base_decl PARAMS ((tree)); 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))); @@ -458,7 +458,6 @@ HOST_WIDE_INT get_alias_set (t) tree t; { - tree orig_t; HOST_WIDE_INT set; /* If we're not doing any alias analysis, just assume everything @@ -473,14 +472,76 @@ get_alias_set (t) language-specific routine may make mutually-recursive calls to each other to figure out what to do. At each juncture, we see if this is a tree that the language may need to handle specially. First handle things that - aren't types and start by removing nops since we care only about the - actual object. Also replace PLACEHOLDER_EXPRs and pick up the outermost - object that we could have a pointer to. */ + aren't types. */ if (! TYPE_P (t)) { - /* Remove any NOPs and see what any PLACEHOLD_EXPRs will expand to. */ + tree inner = t; + tree placeholder_ptr = 0; + + /* First see if the actual object referenced is an INDIRECT_REF from a + restrict-qualified pointer or a "void *". Start by removing nops + since we care only about the actual object. Also replace + PLACEHOLDER_EXPRs. */ + while (((TREE_CODE (inner) == NOP_EXPR + || TREE_CODE (inner) == CONVERT_EXPR) + && (TYPE_MODE (TREE_TYPE (inner)) + == TYPE_MODE (TREE_TYPE (TREE_OPERAND (inner, 0))))) + || TREE_CODE (inner) == NON_LVALUE_EXPR + || TREE_CODE (inner) == PLACEHOLDER_EXPR + || handled_component_p (inner)) + { + if (TREE_CODE (inner) == PLACEHOLDER_EXPR) + inner = find_placeholder (inner, &placeholder_ptr); + else + inner = TREE_OPERAND (inner, 0); + } + + /* Check for accesses through restrict-qualified pointers. */ + if (TREE_CODE (inner) == INDIRECT_REF) + { + tree decl = find_base_decl (TREE_OPERAND (inner, 0)); + + if (decl && DECL_POINTER_ALIAS_SET_KNOWN_P (decl)) + { + /* If we haven't computed the actual alias set, do it now. */ + if (DECL_POINTER_ALIAS_SET (decl) == -2) + { + /* No two restricted pointers can point at the same thing. + However, a restricted pointer can point at the same thing + as an unrestricted pointer, if that unrestricted pointer + is based on the restricted pointer. So, we make the + alias set for the restricted pointer a subset of the + alias set for the type pointed to by the type of the + decl. */ + HOST_WIDE_INT pointed_to_alias_set + = get_alias_set (TREE_TYPE (TREE_TYPE (decl))); + + if (pointed_to_alias_set == 0) + /* It's not legal to make a subset of alias set zero. */ + ; + else + { + DECL_POINTER_ALIAS_SET (decl) = new_alias_set (); + record_alias_subset (pointed_to_alias_set, + DECL_POINTER_ALIAS_SET (decl)); + } + } + + /* We use the alias set indicated in the declaration. */ + return DECL_POINTER_ALIAS_SET (decl); + } + + /* If we have an INDIRECT_REF via a void pointer, we don't + know anything about what that might alias. */ + else if (TREE_CODE (TREE_TYPE (inner)) == VOID_TYPE) + return 0; + } + + /* Otherwise, pick up the outermost object that we could have a pointer + to, processing conversion and PLACEHOLDER_EXPR as above. */ + placeholder_ptr = 0; while (((TREE_CODE (t) == NOP_EXPR || TREE_CODE (t) == CONVERT_EXPR) - && (TYPE_MODE (TREE_TYPE (t)) + && (TYPE_MODE (TREE_TYPE (t)) == TYPE_MODE (TREE_TYPE (TREE_OPERAND (t, 0))))) || TREE_CODE (t) == NON_LVALUE_EXPR || TREE_CODE (t) == PLACEHOLDER_EXPR @@ -492,44 +553,22 @@ get_alias_set (t) return set; if (TREE_CODE (t) == PLACEHOLDER_EXPR) - t = find_placeholder (t, 0); + t = find_placeholder (t, &placeholder_ptr); else t = TREE_OPERAND (t, 0); } - /* Now give the language a chance to do something but record what we - gave it this time. */ - orig_t = t; + /* Give the language another chance to do something. */ if ((set = lang_get_alias_set (t)) != -1) return set; - /* Check for accesses through restrict-qualified pointers. */ - if (TREE_CODE (t) == INDIRECT_REF) - { - tree decl = find_base_decl (TREE_OPERAND (t, 0)); - - if (decl && DECL_POINTER_ALIAS_SET_KNOWN_P (decl)) - /* We use the alias set indicated in the declaration. */ - return DECL_POINTER_ALIAS_SET (decl); - - /* If we have an INDIRECT_REF via a void pointer, we don't - know anything about what that might alias. */ - if (TREE_CODE (TREE_TYPE (t)) == VOID_TYPE) - return 0; - } - - /* If we've already determined the alias set for this decl, just - return it. This is necessary for C++ anonymous unions, whose - component variables don't look like union members (boo!). */ + /* If we've already determined the alias set for a decl, just return + it. This is necessary for C++ anonymous unions, whose component + variables don't look like union members (boo!). */ if (TREE_CODE (t) == VAR_DECL && DECL_RTL_SET_P (t) && GET_CODE (DECL_RTL (t)) == MEM) return MEM_ALIAS_SET (DECL_RTL (t)); - /* Give the language another chance to do something special. */ - if (orig_t != t - && (set = lang_get_alias_set (t)) != -1) - return set; - /* Now all we care about is the type. */ t = TREE_TYPE (t); } @@ -537,16 +576,12 @@ get_alias_set (t) /* Variant qualifiers don't affect the alias set, so get the main variant. If this is a type with a known alias set, return it. */ t = TYPE_MAIN_VARIANT (t); - if (TYPE_P (t) && TYPE_ALIAS_SET_KNOWN_P (t)) + if (TYPE_ALIAS_SET_KNOWN_P (t)) return TYPE_ALIAS_SET (t); /* See if the language has special handling for this type. */ if ((set = lang_get_alias_set (t)) != -1) - { - /* If the alias set is now known, we are done. */ - if (TYPE_ALIAS_SET_KNOWN_P (t)) - return TYPE_ALIAS_SET (t); - } + return set; /* There are no objects of FUNCTION_TYPE, so there's no point in using up an alias set for them. (There are, of course, pointers diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index eaaf20cbe12..50819c6840c 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -178,6 +178,8 @@ static rtx make_jump_insn_raw PARAMS ((rtx)); static rtx make_call_insn_raw PARAMS ((rtx)); static rtx find_line_note PARAMS ((rtx)); static void mark_sequence_stack PARAMS ((struct sequence_stack *)); +static rtx change_address_1 PARAMS ((rtx, enum machine_mode, rtx, + int)); static void unshare_all_rtl_1 PARAMS ((rtx)); static void unshare_all_decls PARAMS ((tree)); static void reset_used_decls PARAMS ((tree)); @@ -1652,14 +1654,6 @@ set_mem_attributes (ref, t, objectp) type = TYPE_P (t) ? t : TREE_TYPE (t); - /* Get the alias set from the expression or type (perhaps using a - front-end routine) and then copy bits from the type. */ - - /* It is incorrect to set RTX_UNCHANGING_P from TREE_READONLY (type) - here, because, in C and C++, the fact that a location is accessed - through a const expression does not mean that the value there can - never change. */ - /* If we have already set DECL_RTL = ref, get_alias_set will get the wrong answer, as it assumes that DECL_RTL already has the right alias info. Callers should not set DECL_RTL until after the call to @@ -1667,8 +1661,15 @@ set_mem_attributes (ref, t, objectp) if (DECL_P (t) && ref == DECL_RTL_IF_SET (t)) abort (); + /* Get the alias set from the expression or type (perhaps using a + front-end routine). */ set_mem_alias_set (ref, get_alias_set (t)); + /* It is incorrect to set RTX_UNCHANGING_P from TREE_READONLY (type) + here, because, in C and C++, the fact that a location is accessed + through a const expression does not mean that the value there can + never change. */ + MEM_VOLATILE_P (ref) = TYPE_VOLATILE (type); MEM_IN_STRUCT_P (ref) = AGGREGATE_TYPE_P (type); @@ -1677,7 +1678,14 @@ set_mem_attributes (ref, t, objectp) if (objectp && ! AGGREGATE_TYPE_P (type)) MEM_SCALAR_P (ref) = 1; - /* If T is a type, this is all we can do. Otherwise, we may be able + /* If the size is known, we can set that. */ + if (TYPE_SIZE_UNIT (type) && host_integerp (TYPE_SIZE_UNIT (type), 1)) + MEM_ATTRS (ref) + = get_mem_attrs (MEM_ALIAS_SET (ref), MEM_DECL (ref), MEM_OFFSET (ref), + GEN_INT (tree_low_cst (TYPE_SIZE_UNIT (type), 1)), + MEM_ALIGN (ref)); + + /* If T is a type, there's nothing more we can do. Otherwise, we may be able to deduce some more information about the expression. */ if (TYPE_P (t)) return; @@ -1686,17 +1694,27 @@ set_mem_attributes (ref, t, objectp) if (TREE_THIS_VOLATILE (t)) MEM_VOLATILE_P (ref) = 1; - /* Now see if we can say more about whether it's an aggregate or - scalar. If we already know it's an aggregate, don't bother. */ - if (MEM_IN_STRUCT_P (ref)) - return; - /* Now remove any NOPs: they don't change what the underlying object is. Likewise for SAVE_EXPR. */ while (TREE_CODE (t) == NOP_EXPR || TREE_CODE (t) == CONVERT_EXPR || TREE_CODE (t) == NON_LVALUE_EXPR || TREE_CODE (t) == SAVE_EXPR) t = TREE_OPERAND (t, 0); + /* If this is a decl, set the attributes of the MEM from it. */ + if (DECL_P (t)) + MEM_ATTRS (ref) + = get_mem_attrs + (MEM_ALIAS_SET (ref), t, GEN_INT (0), + (TYPE_SIZE_UNIT (TREE_TYPE (t)) + && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (t)), 1)) + ? GEN_INT (tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (t)), 1)) + : 0, DECL_ALIGN (t) / BITS_PER_UNIT); + + /* Now see if we can say more about whether it's an aggregate or + scalar. If we already know it's an aggregate, don't bother. */ + if (MEM_IN_STRUCT_P (ref)) + return; + /* Since we already know the type isn't an aggregate, if this is a decl, it must be a scalar. Or if it is a reference into an aggregate, this is part of an aggregate. Otherwise we don't know. */ @@ -1715,7 +1733,6 @@ set_mem_alias_set (mem, set) rtx mem; HOST_WIDE_INT set; { - /* It would be nice to enable this check, but we can't quite yet. */ #ifdef ENABLE_CHECKING /* If the new and old alias sets don't conflict, something is wrong. */ if (!alias_sets_conflict_p (set, MEM_ALIAS_SET (mem))) @@ -1725,15 +1742,25 @@ set_mem_alias_set (mem, set) MEM_ATTRS (mem) = get_mem_attrs (set, MEM_DECL (mem), MEM_OFFSET (mem), MEM_SIZE (mem), MEM_ALIGN (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. - NULL for ADDR means don't change the address.) - VALIDATE is nonzero if the returned memory location is required to be - valid. */ -rtx +/* Set the alignment of MEM to ALIGN. */ + +void +set_mem_align (mem, align) + rtx mem; + unsigned int align; +{ + MEM_ATTRS (mem) = get_mem_attrs (MEM_ALIAS_SET (mem), MEM_DECL (mem), + MEM_OFFSET (mem), MEM_SIZE (mem), align); +} + +/* 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. + NULL for ADDR means don't change the address.) VALIDATE is nonzero if the + returned memory location is required to be valid. The memory + attributes are not changed. */ + +static rtx change_address_1 (memref, mode, addr, validate) rtx memref; enum machine_mode mode; @@ -1768,21 +1795,42 @@ change_address_1 (memref, mode, addr, validate) return new; } -/* Return a memory reference like MEMREF, but with its mode changed - to MODE and its address offset by OFFSET bytes. */ +/* Like change_address_1 with VALIDATE nonzero, but we are not saying in what + way we are changing MEMREF, so we only preserve the alias set. */ rtx -adjust_address (memref, mode, offset) +change_address (memref, mode, addr) + rtx memref; + enum machine_mode mode; + rtx addr; +{ + rtx new = change_address_1 (memref, mode, addr, 1); + enum machine_mode mmode = GET_MODE (new); + + MEM_ATTRS (new) + = get_mem_attrs (MEM_ALIAS_SET (memref), 0, 0, + mmode == BLKmode ? 0 : GEN_INT (GET_MODE_SIZE (mmode)), + (mmode == BLKmode ? 1 + : GET_MODE_ALIGNMENT (mmode) / BITS_PER_UNIT)); + + return new; +} + +/* Return a memory reference like MEMREF, but with its mode changed + to MODE and its address offset by OFFSET bytes. If VALIDATE is + nonzero, the memory address is forced to be valid. */ + +rtx +adjust_address_1 (memref, mode, offset, validate) rtx memref; enum machine_mode mode; HOST_WIDE_INT offset; + int validate; { - /* For now, this is just a wrapper for change_address, but eventually - will do memref tracking. */ rtx addr = XEXP (memref, 0); - - /* ??? Prefer to create garbage instead of creating shared rtl. */ - addr = copy_rtx (addr); + rtx new; + rtx memoffset = MEM_OFFSET (memref); + unsigned int memalign = MEM_ALIGN (memref); /* If MEMREF is a LO_SUM and the offset is within the alignment of the object, we can merge it into the LO_SUM. */ @@ -1792,36 +1840,36 @@ adjust_address (memref, mode, offset) < GET_MODE_ALIGNMENT (GET_MODE (memref)) / BITS_PER_UNIT) addr = gen_rtx_LO_SUM (Pmode, XEXP (addr, 0), plus_constant (XEXP (addr, 1), offset)); + else if (offset == 0) + /* ??? Prefer to create garbage instead of creating shared rtl. */ + addr = copy_rtx (addr); else addr = plus_constant (addr, offset); - return change_address (memref, mode, addr); -} + new = change_address_1 (memref, mode, addr, validate); -/* Likewise, but the reference is not required to be valid. */ + /* Compute the new values of the memory attributes due to this adjustment. + We add the offsets and update the alignment. */ + if (memoffset) + memoffset = GEN_INT (offset + INTVAL (memoffset)); -rtx -adjust_address_nv (memref, mode, offset) - rtx memref; - enum machine_mode mode; - HOST_WIDE_INT offset; -{ - /* For now, this is just a wrapper for change_address, but eventually - will do memref tracking. */ - rtx addr = XEXP (memref, 0); + /* If the offset is negative, don't try to update the alignment. If it's + zero, the alignment hasn't changed. Otherwise, the known alignment may + be less strict. */ + if (offset < 0) + memalign = 1; - /* If MEMREF is a LO_SUM and the offset is within the size of the - object, we can merge it into the LO_SUM. */ - if (GET_MODE (memref) != BLKmode && GET_CODE (addr) == LO_SUM - && offset >= 0 - && (unsigned HOST_WIDE_INT) offset - < GET_MODE_ALIGNMENT (GET_MODE (memref)) / BITS_PER_UNIT) - addr = gen_rtx_LO_SUM (mode, XEXP (addr, 0), - plus_constant (XEXP (addr, 1), offset)); - else - addr = plus_constant (addr, offset); + while (offset > 0 && (offset % memalign) != 0) + memalign >>= 1; - return change_address_1 (memref, mode, addr, 0); + MEM_ATTRS (new) + = get_mem_attrs (MEM_ALIAS_SET (memref), MEM_DECL (memref), memoffset, + mode == BLKmode + ? 0 : GEN_INT (GET_MODE_SIZE (mode)), memalign); + + /* At some point, we should validate that this offset is within the object, + if all the appropriate values are known. */ + return new; } /* Return a memory reference like MEMREF, but with its address changed to @@ -1834,10 +1882,11 @@ replace_equiv_address (memref, addr) rtx memref; rtx addr; { - /* For now, this is just a wrapper for change_address, but eventually - will do memref tracking. */ - return change_address (memref, VOIDmode, addr); + /* change_address_1 copies the memory attribute structure without change + and that's exactly what we want here. */ + return change_address_1 (memref, VOIDmode, addr, 1); } + /* Likewise, but the reference is not required to be valid. */ rtx @@ -1845,8 +1894,6 @@ replace_equiv_address_nv (memref, addr) rtx memref; rtx addr; { - /* For now, this is just a wrapper for change_address, but eventually - will do memref tracking. */ return change_address_1 (memref, VOIDmode, addr, 0); } diff --git a/gcc/expr.c b/gcc/expr.c index 1c81f73670e..e06d4b10974 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -5403,6 +5403,7 @@ get_inner_reference (exp, pbitsize, pbitpos, poffset, pmode, tree offset = size_zero_node; tree bit_offset = bitsize_zero_node; unsigned int alignment = BIGGEST_ALIGNMENT; + tree placeholder_ptr = 0; tree tem; /* First get the mode, signedness, and size. We do this from just the @@ -5500,6 +5501,11 @@ get_inner_reference (exp, pbitsize, pbitpos, poffset, pmode, unit_size)); } + else if (TREE_CODE (exp) == PLACEHOLDER_EXPR) + { + exp = find_placeholder (exp, &placeholder_ptr); + continue; + } else if (TREE_CODE (exp) != NON_LVALUE_EXPR && ! ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR) @@ -5961,10 +5967,11 @@ check_max_integer_computation_mode (exp) /* Return an object on the placeholder list that matches EXP, a PLACEHOLDER_EXPR. An object "matches" if it is of the type of the - PLACEHOLDER_EXPR or a pointer type to it. For further information, - see tree.def. If no such object is found, abort. If PLIST is nonzero, - it is a location into which a pointer into the placeholder list at - which the object is found is placed. */ + PLACEHOLDER_EXPR or a pointer type to it. For further information, see + tree.def. If no such object is found, abort. If PLIST is nonzero, it is + a location which initially points to a starting location in the + placeholder list (zero means start of the list) and where a pointer into + the placeholder list at which the object is found is placed. */ tree find_placeholder (exp, plist) @@ -5974,7 +5981,9 @@ find_placeholder (exp, plist) tree type = TREE_TYPE (exp); tree placeholder_expr; - for (placeholder_expr = placeholder_list; placeholder_expr != 0; + for (placeholder_expr + = plist && *plist ? TREE_CHAIN (*plist) : placeholder_list; + placeholder_expr != 0; placeholder_expr = TREE_CHAIN (placeholder_expr)) { tree need_type = TYPE_MAIN_VARIANT (type); @@ -6550,7 +6559,7 @@ expand_expr (exp, target, tmode, modifier) case PLACEHOLDER_EXPR: { tree old_list = placeholder_list; - tree placeholder_expr; + tree placeholder_expr = 0; exp = find_placeholder (exp, &placeholder_expr); placeholder_list = TREE_CHAIN (placeholder_expr); diff --git a/gcc/expr.h b/gcc/expr.h index a518cf085fc..af79fd581be 100644 --- a/gcc/expr.h +++ b/gcc/expr.h @@ -500,10 +500,11 @@ extern rtx force_operand PARAMS ((rtx, rtx)); /* Return an object on the placeholder list that matches EXP, a PLACEHOLDER_EXPR. An object "matches" if it is of the type of the - PLACEHOLDER_EXPR or a pointer type to it. For further information, - see tree.def. If no such object is found, abort. If PLIST is nonzero, - it is a location into which a pointer into the placeholder list at - which the object is found is placed. */ + PLACEHOLDER_EXPR or a pointer type to it. For further information, see + tree.def. If no such object is found, abort. If PLIST is nonzero, it is + a location which initially points to a starting location in the + placeholder list (zero means start of the list) and where a pointer into + the placeholder list at which the object is found is placed. */ extern tree find_placeholder PARAMS ((tree, tree *)); /* Generate code for computing expression EXP. @@ -611,23 +612,26 @@ extern rtx memory_address_noforce PARAMS ((enum machine_mode, rtx)); /* Set the alias set of MEM to SET. */ extern void set_mem_alias_set PARAMS ((rtx, HOST_WIDE_INT)); +/* Set the alignment of MEM to ALIGN. */ +extern void set_mem_align PARAMS ((rtx, unsigned int)); + /* 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. - NULL for ADDR means don't change the address.) - VALIDATE is nonzero if the returned memory location is required to be - valid. */ -extern rtx change_address_1 PARAMS ((rtx, enum machine_mode, rtx, int)); - -#define change_address(MEMREF, MODE, ADDR) \ - change_address_1 (MEMREF, MODE, ADDR, 1) + NULL for ADDR means don't change the address.) */ +extern rtx change_address PARAMS ((rtx, enum machine_mode, rtx)); /* Return a memory reference like MEMREF, but with its mode changed to MODE and its address offset by OFFSET bytes. */ -extern rtx adjust_address PARAMS ((rtx, enum machine_mode, HOST_WIDE_INT)); +#define adjust_address(MEMREF, MODE, OFFSET) \ + adjust_address_1 (MEMREF, MODE, OFFSET, 1) /* Likewise, but the reference is not required to be valid. */ -extern rtx adjust_address_nv PARAMS ((rtx, enum machine_mode, HOST_WIDE_INT)); +#define adjust_address_nv(MEMREF, MODE, OFFSET) \ + adjust_address_1 (MEMREF, MODE, OFFSET, 0) + +extern rtx adjust_address_1 PARAMS ((rtx, enum machine_mode, HOST_WIDE_INT, + int)); /* Return a memory reference like MEMREF, but with its address changed to ADDR. The caller is asserting that the actual piece of memory pointed diff --git a/gcc/print-rtl.c b/gcc/print-rtl.c index f2025b500ba..3d78dd392f0 100644 --- a/gcc/print-rtl.c +++ b/gcc/print-rtl.c @@ -23,6 +23,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "config.h" #include "system.h" #include "rtl.h" + +/* We don't want the tree code checking code for the access to the + DECL_NAME to be included in the gen* programs. */ +#undef ENABLE_TREE_CHECKING +#include "tree.h" #include "real.h" #include "flags.h" #include "hard-reg-set.h" @@ -446,8 +451,30 @@ print_rtx (in_rtx) switch (GET_CODE (in_rtx)) { case MEM: - fputc (' ', outfile); + fputs (" [", outfile); fprintf (outfile, HOST_WIDE_INT_PRINT_DEC, MEM_ALIAS_SET (in_rtx)); + if (MEM_DECL (in_rtx) && DECL_NAME (MEM_DECL (in_rtx))) + fprintf (outfile, " %s", + IDENTIFIER_POINTER (DECL_NAME (MEM_DECL (in_rtx)))); + + if (MEM_OFFSET (in_rtx)) + { + fputc ('+', outfile); + fprintf (outfile, HOST_WIDE_INT_PRINT_DEC, + INTVAL (MEM_OFFSET (in_rtx))); + } + + if (MEM_SIZE (in_rtx)) + { + fputs (" S", outfile); + fprintf (outfile, HOST_WIDE_INT_PRINT_DEC, + INTVAL (MEM_SIZE (in_rtx))); + } + + if (MEM_ALIGN (in_rtx) != 1) + fprintf (outfile, " A%u", MEM_ALIGN (in_rtx)); + + fputc (']', outfile); break; #if HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT && MAX_LONG_DOUBLE_TYPE_SIZE == 64