invoke.texi (-fstrict-aliasing): Document.

* invoke.texi (-fstrict-aliasing): Document.
	* rtl.texi (MEM_ALIAS_SET): Document.
	* flags.h (flag_strict_aliasing): Declare.
	* toplev.c (flag_strict_aliasing): Define.
	(f_options): Add -strict-aliasing.
	(main): Set flag_strict_aliasing if -O2 or higher.
	* tree.h (tree_type): Add alias_set field.
	(TYPE_ALIAS_SET): New macro.
	(TYPE_ALIAS_SET_KNOWN_P): Likewise.
	(get_alias_set): Declare.
	* tree.c (lang_get_alias_set): Define.
	(make_node): Initialize TYPE_ALIAS_SET.
	(get_alias_set): New function.
	* print-tree.c (print_node): Dump the alias set for a type.
	* c-tree.h (c_get_alias_set): Declare.
	* c-common.c (c_get_alias_set): New function.
	* c-decl.c (init_decl_processing): Set lang_get_alias_set.
	* expr.c (protect_from_queue): Propogage alias sets.
	(expand_assignment): Calculate alias set for new MEMs.
	(expand_expr): Likewise.
	* function.c (put_var_into_stack): Likewise.
	(put_reg_into_stack): Likewise.
	(gen_mem_addressof): Likewise.
	(assign_parms): Likewise.
	* stmt.c (expand_decl): Likewise.
	* varasm.c (make_decl_rtl): Eliminate redundant clearing of
	DECL_RTL.  Calculate alias set for new MEMs.
	* rtl.def (REG): Add dummy operand.
	(MEM): Add extra operand to store the MEM_ALIAS_SET.
	* rtl.h (MEM_ALIAS_SET): New macro.
	(gen_rtx_MEM): Declare.
	* emit-rtl.c (gen_rtx_MEM): New function.
	* gengenrtl.c (sepcial_rtx): Make MEMs special.
	* alias.c (CHECK_ALIAS_SETS_FOR_CONSISTENCY): New macro.
	(DIFFERENT_ALIAS_SETS_P): Likewise.
	(canon_rtx): Propogate the alias set to the new MEM.
	(true_dependence): Check the alias sets.
	(anti_dependence): Likewise.
	(output_dependence): Likewise.
	* explow.c (stabilize): Progoate alias sets.
	* integrate.c (copy_rtx_and_substitute): Likewise.
	* final.c (alter_subreg): Make sure not to leave MEM_IN_STRUCT_P
	in an unpredictable state.  Propogate alias sets.
	* reload1.c (reload): Clear MEM_ALIAS_SET for new MEMs about which
	we have no alias information.

From-SVN: r20719
This commit is contained in:
Mark Mitchell 1998-06-25 15:14:41 +00:00 committed by Mark Mitchell
parent 9c606f693d
commit 41472af877
24 changed files with 369 additions and 18 deletions

View file

@ -1,3 +1,57 @@
Thu Jun 25 15:08:16 1998 Mark Mitchell <mark@markmitchell.com>
* invoke.texi (-fstrict-aliasing): Document.
* rtl.texi (MEM_ALIAS_SET): Document.
* flags.h (flag_strict_aliasing): Declare.
* toplev.c (flag_strict_aliasing): Define.
(f_options): Add -strict-aliasing.
(main): Set flag_strict_aliasing if -O2 or higher.
* tree.h (tree_type): Add alias_set field.
(TYPE_ALIAS_SET): New macro.
(TYPE_ALIAS_SET_KNOWN_P): Likewise.
(get_alias_set): Declare.
* tree.c (lang_get_alias_set): Define.
(make_node): Initialize TYPE_ALIAS_SET.
(get_alias_set): New function.
* print-tree.c (print_node): Dump the alias set for a type.
* c-tree.h (c_get_alias_set): Declare.
* c-common.c (c_get_alias_set): New function.
* c-decl.c (init_decl_processing): Set lang_get_alias_set.
* expr.c (protect_from_queue): Propogage alias sets.
(expand_assignment): Calculate alias set for new MEMs.
(expand_expr): Likewise.
* function.c (put_var_into_stack): Likewise.
(put_reg_into_stack): Likewise.
(gen_mem_addressof): Likewise.
(assign_parms): Likewise.
* stmt.c (expand_decl): Likewise.
* varasm.c (make_decl_rtl): Eliminate redundant clearing of
DECL_RTL. Calculate alias set for new MEMs.
* rtl.def (REG): Add dummy operand.
(MEM): Add extra operand to store the MEM_ALIAS_SET.
* rtl.h (MEM_ALIAS_SET): New macro.
(gen_rtx_MEM): Declare.
* emit-rtl.c (gen_rtx_MEM): New function.
* gengenrtl.c (sepcial_rtx): Make MEMs special.
* alias.c (CHECK_ALIAS_SETS_FOR_CONSISTENCY): New macro.
(DIFFERENT_ALIAS_SETS_P): Likewise.
(canon_rtx): Propogate the alias set to the new MEM.
(true_dependence): Check the alias sets.
(anti_dependence): Likewise.
(output_dependence): Likewise.
* explow.c (stabilize): Progoate alias sets.
* integrate.c (copy_rtx_and_substitute): Likewise.
* final.c (alter_subreg): Make sure not to leave MEM_IN_STRUCT_P
in an unpredictable state. Propogate alias sets.
* reload1.c (reload): Clear MEM_ALIAS_SET for new MEMs about which
we have no alias information.
Thu Jun 25 16:59:18 EDT 1998 Andrew MacLeod <amacleod@cygnus.com>
* except.h (CATCH_ALL_TYPE): Definition moved to eh-common.h.

View file

@ -42,6 +42,28 @@ static rtx find_base_value PROTO((rtx));
#define SIZE_FOR_MODE(X) (GET_MODE_SIZE (GET_MODE (X)))
/* Perform a basic sanity check. Namely, that there are
no alias sets if we're not doing strict aliasing. This helps
to catch bugs whereby someone uses PUT_CODE, but doesn't clear
MEM_ALIAS_SET, or where a MEM is allocated in some way other
than by the use of gen_rtx_MEM, and the MEM_ALIAS_SET is not
cleared. */
#ifdef ENABLE_CHECKING
#define CHECK_ALIAS_SETS_FOR_CONSISTENCY(MEM1, MEM2) \
(!flag_strict_aliasing \
&& (MEM_ALIAS_SET (MEM1) || MEM_ALIAS_SET (MEM2)) \
? (abort (), 0) : 0)
#else
#define CHECK_ALIAS_SETS_FOR_CONSISTENCY(MEM1, MEM2) 0
#endif
/* Returns nonzero if MEM1 and MEM2 do not alias because they are in
different alias sets. */
#define DIFFERENT_ALIAS_SETS_P(MEM1, MEM2) \
(CHECK_ALIAS_SETS_FOR_CONSISTENCY(MEM1, MEM2), \
MEM_ALIAS_SET (MEM1) && MEM_ALIAS_SET (MEM2) \
&& MEM_ALIAS_SET (MEM1) != MEM_ALIAS_SET (MEM2))
/* Cap the number of passes we make over the insns propagating alias
information through set chains.
@ -372,6 +394,7 @@ canon_rtx (x)
MEM_VOLATILE_P (new) = MEM_VOLATILE_P (x);
RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (x);
MEM_IN_STRUCT_P (new) = MEM_IN_STRUCT_P (x);
MEM_ALIAS_SET (new) = MEM_ALIAS_SET (x);
x = new;
}
}
@ -874,6 +897,9 @@ true_dependence (mem, mem_mode, x, varies)
if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem))
return 1;
if (DIFFERENT_ALIAS_SETS_P (x, mem))
return 0;
/* If X is an unchanging read, then it can't possibly conflict with any
non-unchanging store. It may conflict with an unchanging write though,
because there may be a single store to this address to initialize it.
@ -947,6 +973,9 @@ anti_dependence (mem, x)
x = canon_rtx (x);
mem = canon_rtx (mem);
if (DIFFERENT_ALIAS_SETS_P (x, mem))
return 0;
x_addr = XEXP (x, 0);
mem_addr = XEXP (mem, 0);
@ -978,6 +1007,9 @@ output_dependence (mem, x)
x = canon_rtx (x);
mem = canon_rtx (mem);
if (DIFFERENT_ALIAS_SETS_P (x, mem))
return 0;
return (memrefs_conflict_p (SIZE_FOR_MODE (mem), XEXP (mem, 0),
SIZE_FOR_MODE (x), XEXP (x, 0), 0)
&& ! (MEM_IN_STRUCT_P (mem) && rtx_addr_varies_p (mem)

View file

@ -2880,3 +2880,90 @@ c_build_type_variant (type, constp, volatilep)
TYPE_DOMAIN (type));
return build_type_variant (type, constp, volatilep);
}
/* Return the typed-based alias set for T, which may be an expression
or a type. */
int
c_get_alias_set (t)
tree t;
{
static int next_set = 0;
tree type;
if (t == error_mark_node)
return 0;
type = (TREE_CODE_CLASS (TREE_CODE (t)) == 't')
? t : TREE_TYPE (t);
if (type == error_mark_node)
return 0;
if (TYPE_ALIAS_SET_KNOWN_P (type))
/* If we've already calculated the value, just return it. */
return TYPE_ALIAS_SET (type);
if (TREE_CODE (t) == BIT_FIELD_REF)
/* Perhaps reads and writes to this piece of data alias fields
neighboring the bitfield. Perhaps that's impossible. For now,
let's just assume that bitfields can alias everything, which is
the conservative assumption. */
return 0;
if (TREE_CODE (t) == COMPONENT_REF
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == UNION_TYPE)
/* Permit type-punning when accessing a union, provided the
access is directly through the union. For example, this code does
not permit taking the address of a union member and then
storing through it. Even the type-punning allowed here is a
GCC extension, albeit a common and useful one; the C standard
says that such accesses have implementation-defined behavior. */
return 0;
else if (TYPE_MAIN_VARIANT (type) != type)
{
/* The C standard specifically allows aliasing between
cv-qualified variants of types. */
TYPE_ALIAS_SET (type) = c_get_alias_set (TYPE_MAIN_VARIANT (type));
return TYPE_ALIAS_SET (type);
}
else if (TREE_CODE (type) == INTEGER_TYPE)
{
tree signed_variant;
/* The C standard specifically allows aliasing between signed and
unsigned variants of the same type. We treat the signed
variant as canonical. */
signed_variant = signed_type (type);
if (signed_variant != type)
{
TYPE_ALIAS_SET (type) = c_get_alias_set (signed_variant);
return TYPE_ALIAS_SET (type);
}
else if (signed_variant == signed_char_type_node)
/* The C standard guarantess that any object may be accessed
via an lvalue that has character type. We don't have to
check for unsigned_char_type_node or char_type_node because
we are specifically looking at the signed variant. */
{
TYPE_ALIAS_SET (type) = 0;
return TYPE_ALIAS_SET (type);
}
}
else if (TREE_CODE (type) == RECORD_TYPE
|| TREE_CODE (type) == UNION_TYPE)
{
/* If TYPE is a struct or union type then we're reading or
writing an entire struct. Thus, we don't know anything about
aliasing. (In theory, such an access can only alias objects
whose type is the same as one of the fields, recursively, but
we don't yet make any use of that information.) */
TYPE_ALIAS_SET (type) = 0;
return TYPE_ALIAS_SET (type);
}
/* TYPE is something we haven't seen before. Put it in a new alias
set. */
TYPE_ALIAS_SET (type) = ++next_set;
return TYPE_ALIAS_SET (type);
}

View file

@ -3513,6 +3513,8 @@ init_decl_processing ()
init_iterators ();
incomplete_decl_finalize_hook = finish_incomplete_decl;
lang_get_alias_set = &c_get_alias_set;
}
/* Return a definition for a builtin function named NAME and whose data type

View file

@ -164,6 +164,7 @@ extern void declare_function_name PROTO((void));
extern void decl_attributes PROTO((tree, tree, tree));
extern void init_function_format_info PROTO((void));
extern void check_function_format PROTO((tree, tree, tree));
extern int c_get_alias_set PROTO((tree));
/* Print an error message for invalid operands to arith operation CODE.
NOP_EXPR is used as a special case (see truthvalue_conversion). */
extern void binary_op_error PROTO((enum tree_code));

View file

@ -301,6 +301,20 @@ gen_rtx_REG (mode, regno)
return gen_rtx_raw_REG (mode, regno);
}
rtx
gen_rtx_MEM (mode, addr)
enum machine_mode mode;
rtx addr;
{
rtx rt = gen_rtx_raw_MEM (mode, addr);
/* This field is not cleared by the mere allocation of the rtx, so
we clear it here. */
MEM_ALIAS_SET (rt) = 0;
return rt;
}
/* rtx gen_rtx (code, mode, [element1, ..., elementn])
**
** This routine generates an RTX of the size specified by

View file

@ -592,6 +592,11 @@ stabilize (x)
MEM_IN_STRUCT_P (mem) = MEM_IN_STRUCT_P (x) || GET_CODE (addr) == PLUS;
RTX_UNCHANGING_P (mem) = RTX_UNCHANGING_P (x);
MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (x);
/* Since the new MEM is just like the old X, it can alias only
the things that X could. */
MEM_ALIAS_SET (mem) = MEM_ALIAS_SET (x);
return mem;
}
return x;

View file

@ -415,6 +415,7 @@ protect_from_queue (x, modify)
MEM_IN_STRUCT_P (new) = MEM_IN_STRUCT_P (x);
RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (x);
MEM_VOLATILE_P (new) = MEM_VOLATILE_P (x);
MEM_ALIAS_SET (new) = MEM_ALIAS_SET (x);
if (QUEUED_INSN (y))
{
@ -3063,7 +3064,11 @@ expand_assignment (to, from, want_value, suggest_reg)
Don't re-expand if it was expanded already (in COMPONENT_REF case). */
if (to_rtx == 0)
to_rtx = expand_expr (to, NULL_RTX, VOIDmode, EXPAND_MEMORY_USE_WO);
{
to_rtx = expand_expr (to, NULL_RTX, VOIDmode, EXPAND_MEMORY_USE_WO);
if (GET_CODE (to_rtx) == MEM)
MEM_ALIAS_SET (to_rtx) = get_alias_set (to);
}
/* Don't move directly into a return register. */
if (TREE_CODE (to) == RESULT_DECL && GET_CODE (to_rtx) == REG)
@ -5719,6 +5724,7 @@ expand_expr (exp, target, tmode, modifier)
&& AGGREGATE_TYPE_P (TREE_TYPE (exp2))))
MEM_IN_STRUCT_P (temp) = 1;
MEM_VOLATILE_P (temp) = TREE_THIS_VOLATILE (exp) | flag_volatile;
MEM_ALIAS_SET (temp) = get_alias_set (exp);
/* It is incorrect to set RTX_UNCHANGING_P from TREE_READONLY
here, because, in C and C++, the fact that a location is accessed
@ -6094,6 +6100,10 @@ expand_expr (exp, target, tmode, modifier)
op0 = change_address (op0, mode1,
plus_constant (XEXP (op0, 0),
(bitpos / BITS_PER_UNIT)));
if (GET_CODE (op0) == MEM)
MEM_ALIAS_SET (op0) = get_alias_set (exp);
if (GET_CODE (XEXP (op0, 0)) == REG)
mark_reg_pointer (XEXP (op0, 0), alignment);

View file

@ -3020,6 +3020,8 @@ alter_subreg (x)
- MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (y))));
PUT_CODE (x, MEM);
MEM_VOLATILE_P (x) = MEM_VOLATILE_P (y);
MEM_IN_STRUCT_P (x) = MEM_IN_STRUCT_P (y);
MEM_ALIAS_SET (x) = MEM_ALIAS_SET (y);
XEXP (x, 0) = plus_constant (XEXP (y, 0), offset);
}

View file

@ -432,6 +432,12 @@ extern int flag_pack_struct;
The value is ignored if flag_alias_check is 0. */
extern int flag_argument_noalias;
/* Nonzero if we should do (language-dependent) alias analysis.
Typically, this analysis will assume that expressions of certain
types do not alias expressions of certain other types. Only used
if alias analysis (in general) is enabled. */
extern int flag_strict_aliasing;
/* Emit code to check for stack overflow; also may cause large objects
to be allocated dynamically. */
extern int flag_stack_check;

View file

@ -1466,6 +1466,7 @@ put_var_into_stack (decl)
/* Change the CONCAT into a combined MEM for both parts. */
PUT_CODE (reg, MEM);
MEM_VOLATILE_P (reg) = MEM_VOLATILE_P (XEXP (reg, 0));
MEM_ALIAS_SET (reg) = get_alias_set (decl);
/* The two parts are in memory order already.
Use the lower parts address as ours. */
@ -1538,6 +1539,7 @@ put_reg_into_stack (function, reg, type, promoted_mode, decl_mode, volatile_p,
case it was set for other reasons. For instance, it is set for
__builtin_va_alist. */
MEM_IN_STRUCT_P (reg) = AGGREGATE_TYPE_P (type) | MEM_IN_STRUCT_P (new);
MEM_ALIAS_SET (reg) = get_alias_set (type);
/* Now make sure that all refs to the variable, previously made
when it was a register, are fixed up to be valid again. */
@ -2735,6 +2737,7 @@ gen_mem_addressof (reg, decl)
PUT_MODE (reg, DECL_MODE (decl));
MEM_VOLATILE_P (reg) = TREE_SIDE_EFFECTS (decl);
MEM_IN_STRUCT_P (reg) = AGGREGATE_TYPE_P (type);
MEM_ALIAS_SET (reg) = get_alias_set (decl);
if (TREE_USED (decl) || DECL_INITIAL (decl) != 0)
fixup_var_refs (reg, GET_MODE (reg), TREE_UNSIGNED (type));
@ -3908,6 +3911,7 @@ assign_parms (fndecl, second_time)
is readonly. */
MEM_IN_STRUCT_P (stack_parm) = aggregate;
RTX_UNCHANGING_P (stack_parm) = TREE_READONLY (parm);
MEM_ALIAS_SET (stack_parm) = get_alias_set (parm);
}
/* If this parameter was passed both in registers and in the stack,

View file

@ -129,7 +129,8 @@ special_rtx (idx)
int idx;
{
return (strcmp (defs[idx].enumname, "CONST_INT") == 0
|| strcmp (defs[idx].enumname, "REG") == 0);
|| strcmp (defs[idx].enumname, "REG") == 0
|| strcmp (defs[idx].enumname, "MEM") == 0);
}
static void

View file

@ -2688,6 +2688,7 @@ copy_rtx_and_substitute (orig, map)
XEXP (copy, 0) = copy_rtx_and_substitute (XEXP (orig, 0), map);
MEM_IN_STRUCT_P (copy) = MEM_IN_STRUCT_P (orig);
MEM_VOLATILE_P (copy) = MEM_VOLATILE_P (orig);
MEM_ALIAS_SET (copy) = MEM_ALIAS_SET (orig);
/* If doing function inlining, this MEM might not be const in the
function that it is being inlined into, and thus may not be

View file

@ -156,7 +156,7 @@ in the following sections.
-frerun-cse-after-loop -frerun-loop-opt -fschedule-insns
-fschedule-insns2 -fstrength-reduce -fthread-jumps
-funroll-all-loops -funroll-loops
-fmove-all-movables -freduce-all-givs
-fmove-all-movables -freduce-all-givs -fstrict-aliasing
-O -O0 -O1 -O2 -O3 -Os
@end smallexample
@ -2419,6 +2419,57 @@ Some machines only support 2 operands per instruction. On such
machines, GNU CC might have to do extra copies. The @samp{-fregmove}
option overrides the default for the machine to do the copy before
register allocation.
@item -fstrict-aliasing
Allows the compiler to assume the strictest aliasing rules applicable to
the language being compiled. For C (and C++), this activates
optimizations based on the type of expressions. In particular, an
object of one type is assumed never to reside at the same address as an
object of a different type, unless the types are almost the same. For
example, an @code{unsigned int} can alias an @code{int}, but not a
@code{void*} or a @code{double}. A character type may alias any other
type.
Pay special attention to code like this:
@example
union a_union @{
int i;
double d;
@};
int f() @{
a_union t;
t.d = 3.0;
return t.i;
@}
@end example
The practice of reading from a different union member than the one most
recently written to (called ``type-punning'') is common. Even with
@samp{-fstrict-aliasing}, type-punning is allowed, provided the memory
is accessed through the union type. So, the code above will work as
expected. However, this code might not:
@example
int f() @{
a_union t;
int* ip;
t.d = 3.0;
ip = &t.i;
return *ip;
@}
@end example
This option is not enabled by default at any optimization level because
it is new and has yet to be subjected to thorough testing. You may
of course enable it manually with @samp{-fstrict-aliasing}.
@ifset INTERNALS
Every language that wishes to perform language-specific alias analysis
should define a function that computes, given an @code{tree}
node, an alias set for the node. Nodes in different alias sets are not
allowed to alias. For an example, see the C front-end function
@code{c_get_alias_set}.
@end ifset
@end table
@node Preprocessor Options

View file

@ -479,6 +479,7 @@ print_node (file, prefix, node, indent)
fprintf (file, " align %d", TYPE_ALIGN (node));
fprintf (file, " symtab %d", TYPE_SYMTAB_ADDRESS (node));
fprintf (file, " alias set %d", TYPE_ALIAS_SET (node));
print_node (file, "attributes", TYPE_ATTRIBUTES (node), indent + 4);

View file

@ -2095,6 +2095,9 @@ reload (first, global, dumpfile)
XEXP (reg, 0) = addr;
REG_USERVAR_P (reg) = 0;
MEM_IN_STRUCT_P (reg) = in_struct;
/* We have no alias information about this newly created
MEM. */
MEM_ALIAS_SET (reg) = 0;
PUT_CODE (reg, MEM);
}
else if (reg_equiv_mem[i])

View file

@ -537,10 +537,16 @@ DEF_RTL_EXPR(CONST, "const", "e", 'o')
by a SET whose first operand is (PC). */
DEF_RTL_EXPR(PC, "pc", "", 'o')
/* A register. The "operand" is the register number, accessed
with the REGNO macro. If this number is less than FIRST_PSEUDO_REGISTER
than a hardware register is being referred to. */
DEF_RTL_EXPR(REG, "reg", "i", 'o')
/* A register. The "operand" is the register number, accessed with
the REGNO macro. If this number is less than FIRST_PSEUDO_REGISTER
than a hardware register is being referred to. The second operand
doesn't really exist. Unfortunately, however, the compiler
implicitly assumes that a REG can be transformed in place into a
MEM, and therefore that a REG is at least as big as a MEM. To
avoid this memory overhead, which is likely to be substantial,
search for uses of PUT_CODE that turn REGs into MEMs, and fix them
somehow. Then, the trailing `0' can be removed here. */
DEF_RTL_EXPR(REG, "reg", "i0", 'o')
/* A scratch register. This represents a register used only within a
single insn. It will be turned into a REG during register allocation
@ -578,9 +584,11 @@ DEF_RTL_EXPR(STRICT_LOW_PART, "strict_low_part", "e", 'x')
in DECL_RTLs and during RTL generation, but not in the insn chain. */
DEF_RTL_EXPR(CONCAT, "concat", "ee", 'o')
/* A memory location; operand is the address.
Can be nested inside a VOLATILE. */
DEF_RTL_EXPR(MEM, "mem", "e", 'o')
/* A memory location; operand is the address. Can be nested inside a
VOLATILE. The second operand is the alias set to which this MEM
belongs. We use `0' instead of `i' for this field so that the
field need not be specified in machine descriptions. */
DEF_RTL_EXPR(MEM, "mem", "e0", 'o')
/* Reference to an assembler label in the code for this function.
The operand is a CODE_LABEL found in the insn chain.

View file

@ -561,6 +561,17 @@ extern char *note_insn_name[];
/* For a MEM rtx, 1 if it refers to a field of an aggregate. */
#define MEM_IN_STRUCT_P(RTX) ((RTX)->in_struct)
/* 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
language-dependent manner in the front-end, and should not be
altered in the back-end. These set numbers are tested for zero,
and compared for equality; they have no other significance. In
some front-ends, these numbers may correspond in some way to types,
or other language-level entities, but they need not, and the
back-end makes no such assumptions. */
#define MEM_ALIAS_SET(RTX) (XINT (RTX, 1))
/* For a LABEL_REF, 1 means that this reference is to a label outside the
loop containing the reference. */
#define LABEL_OUTSIDE_LOOP_P(RTX) ((RTX)->in_struct)
@ -1057,11 +1068,13 @@ extern rtx static_chain_incoming_rtx;
#include "genrtl.h"
#endif
/* There are two RTL codes that require special attention; the generation
functions included above do the raw handling. */
/* There are some RTL codes that require special attention; the
generation functions included above do the raw handling. If you
add to this list, modify special_rtx in gengenrtl.c as well. */
extern rtx gen_rtx_CONST_INT PROTO((enum machine_mode, HOST_WIDE_INT));
extern rtx gen_rtx_REG PROTO((enum machine_mode, int));
extern rtx gen_rtx_MEM PROTO((enum machine_mode, rtx));
/* We need the cast here to ensure that we get the same result both with
and without prototypes. */

View file

@ -287,9 +287,9 @@ to access them.
@section Flags in an RTL Expression
@cindex flags in RTL expression
RTL expressions contain several flags (one-bit bitfields) that are used
in certain types of expression. Most often they are accessed with the
following macros:
RTL expressions contain several flags (one-bit bitfields) and other
values that are used in certain types of expression. Most often they
are accessed with the following macros:
@table @code
@findex MEM_VOLATILE_P
@ -310,6 +310,15 @@ structure, union or array, or to a component of one. Zero for
references to a scalar variable or through a pointer to a scalar.
Stored in the @code{in_struct} field and printed as @samp{/s}.
@findex MEM_ALIAS_SET
@item MEM_ALIAS_SET (@var{x})
In @code{mem} expressions, the alias set to which @var{x} belongs. If
zero, @var{x} is not in any alias set, and may alias anything. If
nonzero, @var{x} may only alias objects in the same alias set. This
value is set (in a language-specific manner) by the front-end. This
field is not a bit-field; it is in an integer, found as the second
argument to the @code{mem}.
@findex REG_LOOP_TEST_P
@cindex @code{reg} and @samp{/s}
@cindex @code{in_struct}, in @code{reg}

View file

@ -3178,6 +3178,8 @@ expand_decl (decl)
if (flag_float_store && TREE_CODE (type) == REAL_TYPE)
MEM_VOLATILE_P (DECL_RTL (decl)) = 1;
#endif
MEM_ALIAS_SET (DECL_RTL (decl)) = get_alias_set (decl);
}
else
/* Dynamic-size object: must push space on the stack. */

View file

@ -711,6 +711,12 @@ int flag_regmove = 0;
This defaults to 0 for C. */
int flag_argument_noalias = 0;
/* Nonzero if we should do (language-dependent) alias analysis.
Typically, this analysis will assume that expressions of certain
types do not alias expressions of certain other types. Only used
if alias analysis (in general) is enabled. */
int flag_strict_aliasing = 0;
/* Table of language-independent -f options.
STRING is the option name. VARIABLE is the address of the variable.
ON_VALUE is the value to store in VARIABLE
@ -782,6 +788,7 @@ struct { char *string; int *variable; int on_value;} f_options[] =
{"argument-alias", &flag_argument_noalias, 0},
{"argument-noalias", &flag_argument_noalias, 1},
{"argument-noalias-global", &flag_argument_noalias, 2},
{"strict-aliasing", &flag_strict_aliasing, 1},
{"check-memory-usage", &flag_check_memory_usage, 1},
{"prefix-function-name", &flag_prefix_function_name, 1}
};
@ -3839,6 +3846,9 @@ main (argc, argv, envp)
flag_schedule_insns_after_reload = 1;
#endif
flag_regmove = 1;
/* We don't set flag_strict_aliasing here because we're still
testing the functionality. After it has been tested, it
should be turned on here. */
}
if (optimize >= 3)

View file

@ -261,6 +261,10 @@ static int next_decl_uid;
/* Unique id for next type created. */
static int next_type_uid = 1;
/* The language-specific function for alias analysis. If NULL, the
language does not do any special alias analysis. */
int (*lang_get_alias_set) PROTO((tree));
/* Here is how primitive or already-canonicalized types' hash
codes are made. */
#define TYPE_HASH(TYPE) ((unsigned long) (TYPE) & 0777777)
@ -1112,6 +1116,9 @@ make_node (code)
#ifdef SET_DEFAULT_TYPE_ATTRIBUTES
SET_DEFAULT_TYPE_ATTRIBUTES (t);
#endif
/* Note that we have not yet computed the alias set for this
type. */
TYPE_ALIAS_SET (t) = -1;
break;
case 'c':
@ -5019,3 +5026,17 @@ expr_check (node, ignored, file, line, nofatal)
return node;
}
#endif
/* Return the alias set for T, which may be either a type or an
expression. */
int get_alias_set (t)
tree t;
{
if (!flag_strict_aliasing || !lang_get_alias_set)
/* If we're not doing any lanaguage-specific alias analysis, just
assume everything aliases everything else. */
return 0;
else
return (*lang_get_alias_set) (t);
}

View file

@ -776,6 +776,18 @@ struct tree_block
#define TYPE_OBSTACK(NODE) (TYPE_CHECK (NODE)->type.obstack)
#define TYPE_LANG_SPECIFIC(NODE) (TYPE_CHECK (NODE)->type.lang_specific)
/* The (language-specific) typed-based alias set for this type.
Objects whose TYPE_ALIAS_SETs are different cannot alias each
other. If the TYPE_ALIAS_SET is -1, no alias set has yet been
assigned to this type. If the TYPE_ALIAS_SET is 0, objects of this
type can alias objects of any type. */
#define TYPE_ALIAS_SET(NODE) (TYPE_CHECK (NODE)->type.alias_set)
/* Nonzero iff the typed-based alias set for this type has been
calculated. */
#define TYPE_ALIAS_SET_KNOWN_P(NODE) \
(TYPE_CHECK (NODE)->type.alias_set != -1)
/* A TREE_LIST of IDENTIFIER nodes of the attributes that apply
to this type. */
#define TYPE_ATTRIBUTES(NODE) (TYPE_CHECK (NODE)->type.attributes)
@ -870,6 +882,7 @@ struct tree_type
union tree_node *noncopied_parts;
union tree_node *context;
struct obstack *obstack;
int alias_set;
/* Points to a structure whose details depend on the language in use. */
struct lang_type *lang_specific;
};
@ -1811,6 +1824,8 @@ extern tree get_file_function_name PROTO((int));
extern tree get_set_constructor_bits PROTO((tree, char *, int));
extern tree get_set_constructor_bytes PROTO((tree,
unsigned char *, int));
extern int get_alias_set PROTO((tree));
extern int (*lang_get_alias_set) PROTO((tree));
/* In stmt.c */

View file

@ -662,8 +662,6 @@ make_decl_rtl (decl, asmspec, top_level)
same DECL node. Don't discard the RTL already made. */
if (DECL_RTL (decl) == 0)
{
DECL_RTL (decl) = 0;
/* First detect errors in declaring global registers. */
if (TREE_CODE (decl) != FUNCTION_DECL
&& DECL_REGISTER (decl) && reg_number == -1)
@ -767,7 +765,8 @@ make_decl_rtl (decl, asmspec, top_level)
DECL_RTL (decl) = gen_rtx_MEM (DECL_MODE (decl),
gen_rtx_SYMBOL_REF (Pmode, name));
MEM_ALIAS_SET (DECL_RTL (decl)) = get_alias_set (decl);
/* If this variable is to be treated as volatile, show its
tree node has side effects. If it has side effects, either
because of this test or from TREE_THIS_VOLATILE also