Makefile.in (print-rtl.o): Depend on TREE_H.

* 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.

From-SVN: r46313
This commit is contained in:
Richard Kenner 2001-10-17 09:31:36 +00:00 committed by Richard Kenner
parent 4d8f669f94
commit 738cc47245
7 changed files with 264 additions and 121 deletions

View File

@ -1,3 +1,24 @@
Wed Oct 17 05:26:39 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* 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 <rth@redhat.com>
* config/alpha/alpha.c (direct_call_operand): Don't fall off end.

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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);

View File

@ -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

View File

@ -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