alias.c revision 132718
150397Sobrien/* Alias analysis for GNU C
2132718Skan   Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
3117395Skan   Free Software Foundation, Inc.
450397Sobrien   Contributed by John Carr (jfc@mit.edu).
550397Sobrien
690075SobrienThis file is part of GCC.
750397Sobrien
890075SobrienGCC is free software; you can redistribute it and/or modify it under
990075Sobrienthe terms of the GNU General Public License as published by the Free
1090075SobrienSoftware Foundation; either version 2, or (at your option) any later
1190075Sobrienversion.
1250397Sobrien
1390075SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY
1490075SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or
1590075SobrienFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1690075Sobrienfor more details.
1750397Sobrien
1850397SobrienYou should have received a copy of the GNU General Public License
1990075Sobrienalong with GCC; see the file COPYING.  If not, write to the Free
2090075SobrienSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA
2190075Sobrien02111-1307, USA.  */
2250397Sobrien
2350397Sobrien#include "config.h"
2450397Sobrien#include "system.h"
25132718Skan#include "coretypes.h"
26132718Skan#include "tm.h"
2750397Sobrien#include "rtl.h"
2890075Sobrien#include "tree.h"
2990075Sobrien#include "tm_p.h"
3090075Sobrien#include "function.h"
3150397Sobrien#include "expr.h"
3250397Sobrien#include "regs.h"
3350397Sobrien#include "hard-reg-set.h"
3490075Sobrien#include "basic-block.h"
3550397Sobrien#include "flags.h"
3652284Sobrien#include "output.h"
3750397Sobrien#include "toplev.h"
3890075Sobrien#include "cselib.h"
3952284Sobrien#include "splay-tree.h"
4090075Sobrien#include "ggc.h"
4190075Sobrien#include "langhooks.h"
42132718Skan#include "timevar.h"
43117395Skan#include "target.h"
44132718Skan#include "cgraph.h"
45132718Skan#include "varray.h"
4650397Sobrien
4752284Sobrien/* The alias sets assigned to MEMs assist the back-end in determining
4852284Sobrien   which MEMs can alias which other MEMs.  In general, two MEMs in
4990075Sobrien   different alias sets cannot alias each other, with one important
5090075Sobrien   exception.  Consider something like:
5152284Sobrien
52132718Skan     struct S { int i; double d; };
5352284Sobrien
5452284Sobrien   a store to an `S' can alias something of either type `int' or type
5552284Sobrien   `double'.  (However, a store to an `int' cannot alias a `double'
5652284Sobrien   and vice versa.)  We indicate this via a tree structure that looks
5752284Sobrien   like:
5852284Sobrien           struct S
5952284Sobrien            /   \
6052284Sobrien	   /     \
6152284Sobrien         |/_     _\|
6252284Sobrien         int    double
6352284Sobrien
6490075Sobrien   (The arrows are directed and point downwards.)
6590075Sobrien    In this situation we say the alias set for `struct S' is the
6690075Sobrien   `superset' and that those for `int' and `double' are `subsets'.
6752284Sobrien
6890075Sobrien   To see whether two alias sets can point to the same memory, we must
6990075Sobrien   see if either alias set is a subset of the other. We need not trace
70132718Skan   past immediate descendants, however, since we propagate all
7190075Sobrien   grandchildren up one level.
7290075Sobrien
7352284Sobrien   Alias set zero is implicitly a superset of all other alias sets.
7452284Sobrien   However, this is no actual entry for alias set zero.  It is an
7552284Sobrien   error to attempt to explicitly construct a subset of zero.  */
7652284Sobrien
77132718Skanstruct alias_set_entry GTY(())
7890075Sobrien{
7952284Sobrien  /* The alias set number, as stored in MEM_ALIAS_SET.  */
8090075Sobrien  HOST_WIDE_INT alias_set;
8152284Sobrien
8252284Sobrien  /* The children of the alias set.  These are not just the immediate
83132718Skan     children, but, in fact, all descendants.  So, if we have:
8452284Sobrien
85117395Skan       struct T { struct S s; float f; }
8652284Sobrien
8752284Sobrien     continuing our example above, the children here will be all of
8852284Sobrien     `int', `double', `float', and `struct S'.  */
89132718Skan  splay_tree GTY((param1_is (int), param2_is (int))) children;
9052284Sobrien
9190075Sobrien  /* Nonzero if would have a child of zero: this effectively makes this
9290075Sobrien     alias set the same as alias set zero.  */
9390075Sobrien  int has_zero_child;
94132718Skan};
95132718Skantypedef struct alias_set_entry *alias_set_entry;
9650397Sobrien
97132718Skanstatic int rtx_equal_for_memref_p (rtx, rtx);
98132718Skanstatic rtx find_symbolic_term (rtx);
99132718Skanstatic int memrefs_conflict_p (int, rtx, int, rtx, HOST_WIDE_INT);
100132718Skanstatic void record_set (rtx, rtx, void *);
101132718Skanstatic int base_alias_check (rtx, rtx, enum machine_mode,
102132718Skan			     enum machine_mode);
103132718Skanstatic rtx find_base_value (rtx);
104132718Skanstatic int mems_in_disjoint_alias_sets_p (rtx, rtx);
105132718Skanstatic int insert_subset_children (splay_tree_node, void*);
106132718Skanstatic tree find_base_decl (tree);
107132718Skanstatic alias_set_entry get_alias_set_entry (HOST_WIDE_INT);
108132718Skanstatic rtx fixed_scalar_and_varying_struct_p (rtx, rtx, rtx, rtx,
109132718Skan					      int (*) (rtx, int));
110132718Skanstatic int aliases_everything_p (rtx);
111132718Skanstatic bool nonoverlapping_component_refs_p (tree, tree);
112132718Skanstatic tree decl_for_component_ref (tree);
113132718Skanstatic rtx adjust_offset_for_component_ref (tree, rtx);
114132718Skanstatic int nonoverlapping_memrefs_p (rtx, rtx);
115132718Skanstatic int write_dependence_p (rtx, rtx, int, int);
116117395Skan
117132718Skanstatic int nonlocal_mentioned_p_1 (rtx *, void *);
118132718Skanstatic int nonlocal_mentioned_p (rtx);
119132718Skanstatic int nonlocal_referenced_p_1 (rtx *, void *);
120132718Skanstatic int nonlocal_referenced_p (rtx);
121132718Skanstatic int nonlocal_set_p_1 (rtx *, void *);
122132718Skanstatic int nonlocal_set_p (rtx);
123132718Skanstatic void memory_modified_1 (rtx, rtx, void *);
12490075Sobrien
12550397Sobrien/* Set up all info needed to perform alias analysis on memory references.  */
12650397Sobrien
12790075Sobrien/* Returns the size in bytes of the mode of X.  */
12850397Sobrien#define SIZE_FOR_MODE(X) (GET_MODE_SIZE (GET_MODE (X)))
12950397Sobrien
13050397Sobrien/* Returns nonzero if MEM1 and MEM2 do not alias because they are in
13152284Sobrien   different alias sets.  We ignore alias sets in functions making use
13252284Sobrien   of variable arguments because the va_arg macros on some systems are
13352284Sobrien   not legal ANSI C.  */
13452284Sobrien#define DIFFERENT_ALIAS_SETS_P(MEM1, MEM2)			\
13552284Sobrien  mems_in_disjoint_alias_sets_p (MEM1, MEM2)
13650397Sobrien
13750397Sobrien/* Cap the number of passes we make over the insns propagating alias
13890075Sobrien   information through set chains.   10 is a completely arbitrary choice.  */
13950397Sobrien#define MAX_ALIAS_LOOP_PASSES 10
140117395Skan
14150397Sobrien/* reg_base_value[N] gives an address to which register N is related.
14250397Sobrien   If all sets after the first add or subtract to the current value
14350397Sobrien   or otherwise modify it so it does not point to a different top level
14450397Sobrien   object, reg_base_value[N] is equal to the address part of the source
14550397Sobrien   of the first set.
14650397Sobrien
14750397Sobrien   A base address can be an ADDRESS, SYMBOL_REF, or LABEL_REF.  ADDRESS
14850397Sobrien   expressions represent certain special values: function arguments and
149117395Skan   the stack, frame, and argument pointers.
15050397Sobrien
15190075Sobrien   The contents of an ADDRESS is not normally used, the mode of the
15290075Sobrien   ADDRESS determines whether the ADDRESS is a function argument or some
15390075Sobrien   other special value.  Pointer equality, not rtx_equal_p, determines whether
15490075Sobrien   two ADDRESS expressions refer to the same base address.
15590075Sobrien
15690075Sobrien   The only use of the contents of an ADDRESS is for determining if the
15790075Sobrien   current function performs nonlocal memory memory references for the
15890075Sobrien   purposes of marking the function as a constant function.  */
15990075Sobrien
160132718Skanstatic GTY(()) varray_type reg_base_value;
16190075Sobrienstatic rtx *new_reg_base_value;
16290075Sobrien
163132718Skan/* We preserve the copy of old array around to avoid amount of garbage
164132718Skan   produced.  About 8% of garbage produced were attributed to this
165132718Skan   array.  */
166132718Skanstatic GTY((deletable (""))) varray_type old_reg_base_value;
167132718Skan
168117395Skan/* Static hunks of RTL used by the aliasing code; these are initialized
169117395Skan   once per function to avoid unnecessary RTL allocations.  */
170117395Skanstatic GTY (()) rtx static_reg_base_value[FIRST_PSEUDO_REGISTER];
171117395Skan
17250397Sobrien#define REG_BASE_VALUE(X) \
173132718Skan  (reg_base_value && REGNO (X) < VARRAY_SIZE (reg_base_value) \
174132718Skan   ? VARRAY_RTX (reg_base_value, REGNO (X)) : 0)
17550397Sobrien
17650397Sobrien/* Vector of known invariant relationships between registers.  Set in
17750397Sobrien   loop unrolling.  Indexed by register number, if nonzero the value
17850397Sobrien   is an expression describing this register in terms of another.
17950397Sobrien
18050397Sobrien   The length of this array is REG_BASE_VALUE_SIZE.
18150397Sobrien
18250397Sobrien   Because this array contains only pseudo registers it has no effect
18350397Sobrien   after reload.  */
184132718Skanstatic GTY((length("alias_invariant_size"))) rtx *alias_invariant;
185132718Skanunsigned GTY(()) int alias_invariant_size;
18650397Sobrien
18790075Sobrien/* Vector indexed by N giving the initial (unchanging) value known for
188132718Skan   pseudo-register N.  This array is initialized in init_alias_analysis,
189132718Skan   and does not change until end_alias_analysis is called.  */
190132718Skanstatic GTY((length("reg_known_value_size"))) rtx *reg_known_value;
19150397Sobrien
19250397Sobrien/* Indicates number of valid entries in reg_known_value.  */
193132718Skanstatic GTY(()) unsigned int reg_known_value_size;
19450397Sobrien
19550397Sobrien/* Vector recording for each reg_known_value whether it is due to a
19650397Sobrien   REG_EQUIV note.  Future passes (viz., reload) may replace the
19750397Sobrien   pseudo with the equivalent expression and so we account for the
19890075Sobrien   dependences that would be introduced if that happens.
19990075Sobrien
20090075Sobrien   The REG_EQUIV notes created in assign_parms may mention the arg
20190075Sobrien   pointer, and there are explicit insns in the RTL that modify the
20290075Sobrien   arg pointer.  Thus we must ensure that such insns don't get
20390075Sobrien   scheduled across each other because that would invalidate the
20490075Sobrien   REG_EQUIV notes.  One could argue that the REG_EQUIV notes are
20590075Sobrien   wrong, but solving the problem in the scheduler will likely give
20690075Sobrien   better code, so we do it here.  */
207132718Skanstatic bool *reg_known_equiv_p;
20850397Sobrien
20950397Sobrien/* True when scanning insns from the start of the rtl to the
21050397Sobrien   NOTE_INSN_FUNCTION_BEG note.  */
211117395Skanstatic bool copying_arguments;
21250397Sobrien
21352284Sobrien/* The splay-tree used to store the various alias set entries.  */
214132718Skanstatic GTY ((param_is (struct alias_set_entry))) varray_type alias_sets;
21590075Sobrien
21652284Sobrien/* Returns a pointer to the alias set entry for ALIAS_SET, if there is
21752284Sobrien   such an entry, or NULL otherwise.  */
21852284Sobrien
219132718Skanstatic inline alias_set_entry
220132718Skanget_alias_set_entry (HOST_WIDE_INT alias_set)
22152284Sobrien{
222132718Skan  return (alias_set_entry)VARRAY_GENERIC_PTR (alias_sets, alias_set);
22352284Sobrien}
22452284Sobrien
22590075Sobrien/* Returns nonzero if the alias sets for MEM1 and MEM2 are such that
22690075Sobrien   the two MEMs cannot alias each other.  */
22752284Sobrien
228132718Skanstatic inline int
229132718Skanmems_in_disjoint_alias_sets_p (rtx mem1, rtx mem2)
23052284Sobrien{
231117395Skan#ifdef ENABLE_CHECKING
23252284Sobrien/* Perform a basic sanity check.  Namely, that there are no alias sets
23352284Sobrien   if we're not using strict aliasing.  This helps to catch bugs
23452284Sobrien   whereby someone uses PUT_CODE, but doesn't clear MEM_ALIAS_SET, or
23552284Sobrien   where a MEM is allocated in some way other than by the use of
23652284Sobrien   gen_rtx_MEM, and the MEM_ALIAS_SET is not cleared.  If we begin to
23752284Sobrien   use alias sets to indicate that spilled registers cannot alias each
23852284Sobrien   other, we might need to remove this check.  */
23990075Sobrien  if (! flag_strict_aliasing
24090075Sobrien      && (MEM_ALIAS_SET (mem1) != 0 || MEM_ALIAS_SET (mem2) != 0))
24152284Sobrien    abort ();
24252284Sobrien#endif
24352284Sobrien
24490075Sobrien  return ! alias_sets_conflict_p (MEM_ALIAS_SET (mem1), MEM_ALIAS_SET (mem2));
24590075Sobrien}
24690075Sobrien
24790075Sobrien/* Insert the NODE into the splay tree given by DATA.  Used by
24890075Sobrien   record_alias_subset via splay_tree_foreach.  */
24990075Sobrien
25090075Sobrienstatic int
251132718Skaninsert_subset_children (splay_tree_node node, void *data)
25290075Sobrien{
25390075Sobrien  splay_tree_insert ((splay_tree) data, node->key, node->value);
25490075Sobrien
25590075Sobrien  return 0;
25690075Sobrien}
25790075Sobrien
25890075Sobrien/* Return 1 if the two specified alias sets may conflict.  */
25990075Sobrien
26090075Sobrienint
261132718Skanalias_sets_conflict_p (HOST_WIDE_INT set1, HOST_WIDE_INT set2)
26290075Sobrien{
26390075Sobrien  alias_set_entry ase;
26490075Sobrien
26590075Sobrien  /* If have no alias set information for one of the operands, we have
26690075Sobrien     to assume it can alias anything.  */
26790075Sobrien  if (set1 == 0 || set2 == 0
26890075Sobrien      /* If the two alias sets are the same, they may alias.  */
26990075Sobrien      || set1 == set2)
27090075Sobrien    return 1;
27190075Sobrien
27290075Sobrien  /* See if the first alias set is a subset of the second.  */
27390075Sobrien  ase = get_alias_set_entry (set1);
27490075Sobrien  if (ase != 0
27590075Sobrien      && (ase->has_zero_child
27690075Sobrien	  || splay_tree_lookup (ase->children,
27790075Sobrien				(splay_tree_key) set2)))
27890075Sobrien    return 1;
27990075Sobrien
28090075Sobrien  /* Now do the same, but with the alias sets reversed.  */
28190075Sobrien  ase = get_alias_set_entry (set2);
28290075Sobrien  if (ase != 0
28390075Sobrien      && (ase->has_zero_child
28490075Sobrien	  || splay_tree_lookup (ase->children,
28590075Sobrien				(splay_tree_key) set1)))
28690075Sobrien    return 1;
28790075Sobrien
28890075Sobrien  /* The two alias sets are distinct and neither one is the
28990075Sobrien     child of the other.  Therefore, they cannot alias.  */
29090075Sobrien  return 0;
29190075Sobrien}
29290075Sobrien
29390075Sobrien/* Return 1 if TYPE is a RECORD_TYPE, UNION_TYPE, or QUAL_UNION_TYPE and has
29490075Sobrien   has any readonly fields.  If any of the fields have types that
29590075Sobrien   contain readonly fields, return true as well.  */
29690075Sobrien
29790075Sobrienint
298132718Skanreadonly_fields_p (tree type)
29990075Sobrien{
30090075Sobrien  tree field;
30190075Sobrien
30290075Sobrien  if (TREE_CODE (type) != RECORD_TYPE && TREE_CODE (type) != UNION_TYPE
30390075Sobrien      && TREE_CODE (type) != QUAL_UNION_TYPE)
30452284Sobrien    return 0;
30552284Sobrien
30690075Sobrien  for (field = TYPE_FIELDS (type); field != 0; field = TREE_CHAIN (field))
30790075Sobrien    if (TREE_CODE (field) == FIELD_DECL
30890075Sobrien	&& (TREE_READONLY (field)
30990075Sobrien	    || readonly_fields_p (TREE_TYPE (field))))
31090075Sobrien      return 1;
31190075Sobrien
31290075Sobrien  return 0;
31390075Sobrien}
31490075Sobrien
31590075Sobrien/* Return 1 if any MEM object of type T1 will always conflict (using the
31690075Sobrien   dependency routines in this file) with any MEM object of type T2.
31790075Sobrien   This is used when allocating temporary storage.  If T1 and/or T2 are
31890075Sobrien   NULL_TREE, it means we know nothing about the storage.  */
31990075Sobrien
32090075Sobrienint
321132718Skanobjects_must_conflict_p (tree t1, tree t2)
32290075Sobrien{
323117395Skan  HOST_WIDE_INT set1, set2;
324117395Skan
32590075Sobrien  /* If neither has a type specified, we don't know if they'll conflict
32690075Sobrien     because we may be using them to store objects of various types, for
32790075Sobrien     example the argument and local variables areas of inlined functions.  */
32890075Sobrien  if (t1 == 0 && t2 == 0)
32952284Sobrien    return 0;
33052284Sobrien
33190075Sobrien  /* If one or the other has readonly fields or is readonly,
33290075Sobrien     then they may not conflict.  */
33390075Sobrien  if ((t1 != 0 && readonly_fields_p (t1))
33490075Sobrien      || (t2 != 0 && readonly_fields_p (t2))
335107590Sobrien      || (t1 != 0 && lang_hooks.honor_readonly && TYPE_READONLY (t1))
336107590Sobrien      || (t2 != 0 && lang_hooks.honor_readonly && TYPE_READONLY (t2)))
33752284Sobrien    return 0;
33852284Sobrien
33990075Sobrien  /* If they are the same type, they must conflict.  */
34090075Sobrien  if (t1 == t2
34190075Sobrien      /* Likewise if both are volatile.  */
34290075Sobrien      || (t1 != 0 && TYPE_VOLATILE (t1) && t2 != 0 && TYPE_VOLATILE (t2)))
34390075Sobrien    return 1;
34452284Sobrien
345117395Skan  set1 = t1 ? get_alias_set (t1) : 0;
346117395Skan  set2 = t2 ? get_alias_set (t2) : 0;
34752284Sobrien
348117395Skan  /* Otherwise they conflict if they have no alias set or the same. We
349117395Skan     can't simply use alias_sets_conflict_p here, because we must make
350117395Skan     sure that every subtype of t1 will conflict with every subtype of
351117395Skan     t2 for which a pair of subobjects of these respective subtypes
352117395Skan     overlaps on the stack.  */
353117395Skan  return set1 == 0 || set2 == 0 || set1 == set2;
35452284Sobrien}
35590075Sobrien
35690075Sobrien/* T is an expression with pointer type.  Find the DECL on which this
35790075Sobrien   expression is based.  (For example, in `a[i]' this would be `a'.)
35890075Sobrien   If there is no such DECL, or a unique decl cannot be determined,
35990075Sobrien   NULL_TREE is returned.  */
36052284Sobrien
36190075Sobrienstatic tree
362132718Skanfind_base_decl (tree t)
36390075Sobrien{
36490075Sobrien  tree d0, d1, d2;
36552284Sobrien
36690075Sobrien  if (t == 0 || t == error_mark_node || ! POINTER_TYPE_P (TREE_TYPE (t)))
36790075Sobrien    return 0;
36890075Sobrien
36990075Sobrien  /* If this is a declaration, return it.  */
37090075Sobrien  if (TREE_CODE_CLASS (TREE_CODE (t)) == 'd')
37190075Sobrien    return t;
37290075Sobrien
37390075Sobrien  /* Handle general expressions.  It would be nice to deal with
37490075Sobrien     COMPONENT_REFs here.  If we could tell that `a' and `b' were the
37590075Sobrien     same, then `a->f' and `b->f' are also the same.  */
37690075Sobrien  switch (TREE_CODE_CLASS (TREE_CODE (t)))
37790075Sobrien    {
37890075Sobrien    case '1':
37990075Sobrien      return find_base_decl (TREE_OPERAND (t, 0));
38090075Sobrien
38190075Sobrien    case '2':
38290075Sobrien      /* Return 0 if found in neither or both are the same.  */
38390075Sobrien      d0 = find_base_decl (TREE_OPERAND (t, 0));
38490075Sobrien      d1 = find_base_decl (TREE_OPERAND (t, 1));
38590075Sobrien      if (d0 == d1)
38690075Sobrien	return d0;
38790075Sobrien      else if (d0 == 0)
38890075Sobrien	return d1;
38990075Sobrien      else if (d1 == 0)
39090075Sobrien	return d0;
39190075Sobrien      else
39290075Sobrien	return 0;
39390075Sobrien
39490075Sobrien    case '3':
39590075Sobrien      d0 = find_base_decl (TREE_OPERAND (t, 0));
39690075Sobrien      d1 = find_base_decl (TREE_OPERAND (t, 1));
39790075Sobrien      d2 = find_base_decl (TREE_OPERAND (t, 2));
39890075Sobrien
39990075Sobrien      /* Set any nonzero values from the last, then from the first.  */
40090075Sobrien      if (d1 == 0) d1 = d2;
40190075Sobrien      if (d0 == 0) d0 = d1;
40290075Sobrien      if (d1 == 0) d1 = d0;
40390075Sobrien      if (d2 == 0) d2 = d1;
40490075Sobrien
40590075Sobrien      /* At this point all are nonzero or all are zero.  If all three are the
40690075Sobrien	 same, return it.  Otherwise, return zero.  */
40790075Sobrien      return (d0 == d1 && d1 == d2) ? d0 : 0;
40890075Sobrien
40990075Sobrien    default:
41090075Sobrien      return 0;
41190075Sobrien    }
41290075Sobrien}
41390075Sobrien
41490075Sobrien/* Return 1 if all the nested component references handled by
41590075Sobrien   get_inner_reference in T are such that we can address the object in T.  */
41690075Sobrien
41790075Sobrienint
418132718Skancan_address_p (tree t)
41952284Sobrien{
42090075Sobrien  /* If we're at the end, it is vacuously addressable.  */
42190075Sobrien  if (! handled_component_p (t))
42290075Sobrien    return 1;
42352284Sobrien
42490075Sobrien  /* Bitfields are never addressable.  */
42590075Sobrien  else if (TREE_CODE (t) == BIT_FIELD_REF)
42690075Sobrien    return 0;
42790075Sobrien
42890075Sobrien  /* Fields are addressable unless they are marked as nonaddressable or
42990075Sobrien     the containing type has alias set 0.  */
43090075Sobrien  else if (TREE_CODE (t) == COMPONENT_REF
43190075Sobrien	   && ! DECL_NONADDRESSABLE_P (TREE_OPERAND (t, 1))
43290075Sobrien	   && get_alias_set (TREE_TYPE (TREE_OPERAND (t, 0))) != 0
43390075Sobrien	   && can_address_p (TREE_OPERAND (t, 0)))
43490075Sobrien    return 1;
43590075Sobrien
43690075Sobrien  /* Likewise for arrays.  */
43790075Sobrien  else if ((TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
43890075Sobrien	   && ! TYPE_NONALIASED_COMPONENT (TREE_TYPE (TREE_OPERAND (t, 0)))
43990075Sobrien	   && get_alias_set (TREE_TYPE (TREE_OPERAND (t, 0))) != 0
44090075Sobrien	   && can_address_p (TREE_OPERAND (t, 0)))
44190075Sobrien    return 1;
44290075Sobrien
44352284Sobrien  return 0;
44452284Sobrien}
44552284Sobrien
44690075Sobrien/* Return the alias set for T, which may be either a type or an
44790075Sobrien   expression.  Call language-specific routine for help, if needed.  */
44890075Sobrien
44990075SobrienHOST_WIDE_INT
450132718Skanget_alias_set (tree t)
45190075Sobrien{
45290075Sobrien  HOST_WIDE_INT set;
45390075Sobrien
45490075Sobrien  /* If we're not doing any alias analysis, just assume everything
45590075Sobrien     aliases everything else.  Also return 0 if this or its type is
45690075Sobrien     an error.  */
45790075Sobrien  if (! flag_strict_aliasing || t == error_mark_node
45890075Sobrien      || (! TYPE_P (t)
45990075Sobrien	  && (TREE_TYPE (t) == 0 || TREE_TYPE (t) == error_mark_node)))
46090075Sobrien    return 0;
46190075Sobrien
46290075Sobrien  /* We can be passed either an expression or a type.  This and the
46390075Sobrien     language-specific routine may make mutually-recursive calls to each other
46490075Sobrien     to figure out what to do.  At each juncture, we see if this is a tree
46590075Sobrien     that the language may need to handle specially.  First handle things that
46690075Sobrien     aren't types.  */
46790075Sobrien  if (! TYPE_P (t))
46890075Sobrien    {
46990075Sobrien      tree inner = t;
47090075Sobrien      tree placeholder_ptr = 0;
47190075Sobrien
47290075Sobrien      /* Remove any nops, then give the language a chance to do
47390075Sobrien	 something with this tree before we look at it.  */
47490075Sobrien      STRIP_NOPS (t);
47590075Sobrien      set = (*lang_hooks.get_alias_set) (t);
47690075Sobrien      if (set != -1)
47790075Sobrien	return set;
47890075Sobrien
47990075Sobrien      /* First see if the actual object referenced is an INDIRECT_REF from a
48090075Sobrien	 restrict-qualified pointer or a "void *".  Replace
48190075Sobrien	 PLACEHOLDER_EXPRs.  */
48290075Sobrien      while (TREE_CODE (inner) == PLACEHOLDER_EXPR
48390075Sobrien	     || handled_component_p (inner))
48490075Sobrien	{
48590075Sobrien	  if (TREE_CODE (inner) == PLACEHOLDER_EXPR)
48690075Sobrien	    inner = find_placeholder (inner, &placeholder_ptr);
48790075Sobrien	  else
48890075Sobrien	    inner = TREE_OPERAND (inner, 0);
48990075Sobrien
49090075Sobrien	  STRIP_NOPS (inner);
49190075Sobrien	}
49290075Sobrien
49390075Sobrien      /* Check for accesses through restrict-qualified pointers.  */
49490075Sobrien      if (TREE_CODE (inner) == INDIRECT_REF)
49590075Sobrien	{
49690075Sobrien	  tree decl = find_base_decl (TREE_OPERAND (inner, 0));
49790075Sobrien
49890075Sobrien	  if (decl && DECL_POINTER_ALIAS_SET_KNOWN_P (decl))
49990075Sobrien	    {
50090075Sobrien	      /* If we haven't computed the actual alias set, do it now.  */
50190075Sobrien	      if (DECL_POINTER_ALIAS_SET (decl) == -2)
50290075Sobrien		{
503132718Skan		  tree pointed_to_type = TREE_TYPE (TREE_TYPE (decl));
504132718Skan
50590075Sobrien		  /* No two restricted pointers can point at the same thing.
50690075Sobrien		     However, a restricted pointer can point at the same thing
50790075Sobrien		     as an unrestricted pointer, if that unrestricted pointer
50890075Sobrien		     is based on the restricted pointer.  So, we make the
50990075Sobrien		     alias set for the restricted pointer a subset of the
51090075Sobrien		     alias set for the type pointed to by the type of the
51190075Sobrien		     decl.  */
51290075Sobrien		  HOST_WIDE_INT pointed_to_alias_set
513132718Skan		    = get_alias_set (pointed_to_type);
51490075Sobrien
51590075Sobrien		  if (pointed_to_alias_set == 0)
51690075Sobrien		    /* It's not legal to make a subset of alias set zero.  */
517132718Skan		    DECL_POINTER_ALIAS_SET (decl) = 0;
518132718Skan		  else if (AGGREGATE_TYPE_P (pointed_to_type))
519132718Skan		    /* For an aggregate, we must treat the restricted
520132718Skan		       pointer the same as an ordinary pointer.  If we
521132718Skan		       were to make the type pointed to by the
522132718Skan		       restricted pointer a subset of the pointed-to
523132718Skan		       type, then we would believe that other subsets
524132718Skan		       of the pointed-to type (such as fields of that
525132718Skan		       type) do not conflict with the type pointed to
526132718Skan		       by the restricted pointer.   */
527132718Skan		    DECL_POINTER_ALIAS_SET (decl)
528132718Skan		      = pointed_to_alias_set;
52990075Sobrien		  else
53090075Sobrien		    {
53190075Sobrien		      DECL_POINTER_ALIAS_SET (decl) = new_alias_set ();
532117395Skan		      record_alias_subset (pointed_to_alias_set,
533117395Skan					   DECL_POINTER_ALIAS_SET (decl));
53490075Sobrien		    }
53590075Sobrien		}
53690075Sobrien
53790075Sobrien	      /* We use the alias set indicated in the declaration.  */
53890075Sobrien	      return DECL_POINTER_ALIAS_SET (decl);
53990075Sobrien	    }
54090075Sobrien
54190075Sobrien	  /* If we have an INDIRECT_REF via a void pointer, we don't
54290075Sobrien	     know anything about what that might alias.  */
54390075Sobrien	  else if (TREE_CODE (TREE_TYPE (inner)) == VOID_TYPE)
54490075Sobrien	    return 0;
54590075Sobrien	}
54690075Sobrien
54790075Sobrien      /* Otherwise, pick up the outermost object that we could have a pointer
54890075Sobrien	 to, processing conversion and PLACEHOLDER_EXPR as above.  */
54990075Sobrien      placeholder_ptr = 0;
55090075Sobrien      while (TREE_CODE (t) == PLACEHOLDER_EXPR
55190075Sobrien	     || (handled_component_p (t) && ! can_address_p (t)))
55290075Sobrien	{
55390075Sobrien	  if (TREE_CODE (t) == PLACEHOLDER_EXPR)
55490075Sobrien	    t = find_placeholder (t, &placeholder_ptr);
55590075Sobrien	  else
55690075Sobrien	    t = TREE_OPERAND (t, 0);
55790075Sobrien
55890075Sobrien	  STRIP_NOPS (t);
55990075Sobrien	}
56090075Sobrien
56190075Sobrien      /* If we've already determined the alias set for a decl, just return
56290075Sobrien	 it.  This is necessary for C++ anonymous unions, whose component
56390075Sobrien	 variables don't look like union members (boo!).  */
56490075Sobrien      if (TREE_CODE (t) == VAR_DECL
56590075Sobrien	  && DECL_RTL_SET_P (t) && GET_CODE (DECL_RTL (t)) == MEM)
56690075Sobrien	return MEM_ALIAS_SET (DECL_RTL (t));
56790075Sobrien
56890075Sobrien      /* Now all we care about is the type.  */
56990075Sobrien      t = TREE_TYPE (t);
57090075Sobrien    }
57190075Sobrien
57290075Sobrien  /* Variant qualifiers don't affect the alias set, so get the main
57390075Sobrien     variant. If this is a type with a known alias set, return it.  */
57490075Sobrien  t = TYPE_MAIN_VARIANT (t);
57590075Sobrien  if (TYPE_ALIAS_SET_KNOWN_P (t))
57690075Sobrien    return TYPE_ALIAS_SET (t);
57790075Sobrien
57890075Sobrien  /* See if the language has special handling for this type.  */
57990075Sobrien  set = (*lang_hooks.get_alias_set) (t);
58090075Sobrien  if (set != -1)
58190075Sobrien    return set;
58290075Sobrien
58390075Sobrien  /* There are no objects of FUNCTION_TYPE, so there's no point in
58490075Sobrien     using up an alias set for them.  (There are, of course, pointers
58590075Sobrien     and references to functions, but that's different.)  */
58690075Sobrien  else if (TREE_CODE (t) == FUNCTION_TYPE)
58790075Sobrien    set = 0;
588102780Skan
589102780Skan  /* Unless the language specifies otherwise, let vector types alias
590102780Skan     their components.  This avoids some nasty type punning issues in
591102780Skan     normal usage.  And indeed lets vectors be treated more like an
592102780Skan     array slice.  */
593102780Skan  else if (TREE_CODE (t) == VECTOR_TYPE)
594102780Skan    set = get_alias_set (TREE_TYPE (t));
595102780Skan
59690075Sobrien  else
59790075Sobrien    /* Otherwise make a new alias set for this type.  */
59890075Sobrien    set = new_alias_set ();
59990075Sobrien
60090075Sobrien  TYPE_ALIAS_SET (t) = set;
60190075Sobrien
60290075Sobrien  /* If this is an aggregate type, we must record any component aliasing
60390075Sobrien     information.  */
60490075Sobrien  if (AGGREGATE_TYPE_P (t) || TREE_CODE (t) == COMPLEX_TYPE)
60590075Sobrien    record_component_aliases (t);
60690075Sobrien
60790075Sobrien  return set;
60890075Sobrien}
60990075Sobrien
61090075Sobrien/* Return a brand-new alias set.  */
61190075Sobrien
612132718Skanstatic GTY(()) HOST_WIDE_INT last_alias_set;
613132718Skan
61490075SobrienHOST_WIDE_INT
615132718Skannew_alias_set (void)
61690075Sobrien{
61790075Sobrien  if (flag_strict_aliasing)
618132718Skan    {
619132718Skan      if (!alias_sets)
620132718Skan	VARRAY_GENERIC_PTR_INIT (alias_sets, 10, "alias sets");
621132718Skan      else
622132718Skan	VARRAY_GROW (alias_sets, last_alias_set + 2);
623132718Skan      return ++last_alias_set;
624132718Skan    }
62590075Sobrien  else
62690075Sobrien    return 0;
62790075Sobrien}
62890075Sobrien
629132718Skan/* Indicate that things in SUBSET can alias things in SUPERSET, but that
630132718Skan   not everything that aliases SUPERSET also aliases SUBSET.  For example,
631132718Skan   in C, a store to an `int' can alias a load of a structure containing an
632132718Skan   `int', and vice versa.  But it can't alias a load of a 'double' member
633132718Skan   of the same structure.  Here, the structure would be the SUPERSET and
634132718Skan   `int' the SUBSET.  This relationship is also described in the comment at
635132718Skan   the beginning of this file.
63652284Sobrien
637132718Skan   This function should be called only once per SUPERSET/SUBSET pair.
638132718Skan
63952284Sobrien   It is illegal for SUPERSET to be zero; everything is implicitly a
64052284Sobrien   subset of alias set zero.  */
64152284Sobrien
64252284Sobrienvoid
643132718Skanrecord_alias_subset (HOST_WIDE_INT superset, HOST_WIDE_INT subset)
64452284Sobrien{
64552284Sobrien  alias_set_entry superset_entry;
64652284Sobrien  alias_set_entry subset_entry;
64752284Sobrien
64890075Sobrien  /* It is possible in complex type situations for both sets to be the same,
64990075Sobrien     in which case we can ignore this operation.  */
65090075Sobrien  if (superset == subset)
65190075Sobrien    return;
65290075Sobrien
65352284Sobrien  if (superset == 0)
65452284Sobrien    abort ();
65552284Sobrien
65652284Sobrien  superset_entry = get_alias_set_entry (superset);
657117395Skan  if (superset_entry == 0)
65852284Sobrien    {
65952284Sobrien      /* Create an entry for the SUPERSET, so that we have a place to
66052284Sobrien	 attach the SUBSET.  */
661132718Skan      superset_entry = ggc_alloc (sizeof (struct alias_set_entry));
66252284Sobrien      superset_entry->alias_set = superset;
663117395Skan      superset_entry->children
664132718Skan	= splay_tree_new_ggc (splay_tree_compare_ints);
66590075Sobrien      superset_entry->has_zero_child = 0;
666132718Skan      VARRAY_GENERIC_PTR (alias_sets, superset) = superset_entry;
66790075Sobrien    }
66852284Sobrien
66990075Sobrien  if (subset == 0)
67090075Sobrien    superset_entry->has_zero_child = 1;
67190075Sobrien  else
67290075Sobrien    {
67390075Sobrien      subset_entry = get_alias_set_entry (subset);
67490075Sobrien      /* If there is an entry for the subset, enter all of its children
67590075Sobrien	 (if they are not already present) as children of the SUPERSET.  */
676117395Skan      if (subset_entry)
67790075Sobrien	{
67890075Sobrien	  if (subset_entry->has_zero_child)
67990075Sobrien	    superset_entry->has_zero_child = 1;
68090075Sobrien
68190075Sobrien	  splay_tree_foreach (subset_entry->children, insert_subset_children,
68290075Sobrien			      superset_entry->children);
68390075Sobrien	}
68490075Sobrien
68590075Sobrien      /* Enter the SUBSET itself as a child of the SUPERSET.  */
686117395Skan      splay_tree_insert (superset_entry->children,
68790075Sobrien			 (splay_tree_key) subset, 0);
68852284Sobrien    }
68990075Sobrien}
69052284Sobrien
69190075Sobrien/* Record that component types of TYPE, if any, are part of that type for
69290075Sobrien   aliasing purposes.  For record types, we only record component types
69390075Sobrien   for fields that are marked addressable.  For array types, we always
69490075Sobrien   record the component types, so the front end should not call this
69590075Sobrien   function if the individual component aren't addressable.  */
69652284Sobrien
69790075Sobrienvoid
698132718Skanrecord_component_aliases (tree type)
69990075Sobrien{
70090075Sobrien  HOST_WIDE_INT superset = get_alias_set (type);
70190075Sobrien  tree field;
70290075Sobrien
70390075Sobrien  if (superset == 0)
70490075Sobrien    return;
70590075Sobrien
70690075Sobrien  switch (TREE_CODE (type))
70790075Sobrien    {
70890075Sobrien    case ARRAY_TYPE:
70990075Sobrien      if (! TYPE_NONALIASED_COMPONENT (type))
71090075Sobrien	record_alias_subset (superset, get_alias_set (TREE_TYPE (type)));
71190075Sobrien      break;
71290075Sobrien
71390075Sobrien    case RECORD_TYPE:
71490075Sobrien    case UNION_TYPE:
71590075Sobrien    case QUAL_UNION_TYPE:
716132718Skan      /* Recursively record aliases for the base classes, if there are any.  */
717117395Skan      if (TYPE_BINFO (type) != NULL && TYPE_BINFO_BASETYPES (type) != NULL)
718117395Skan	{
719117395Skan	  int i;
720117395Skan	  for (i = 0; i < TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (type)); i++)
721117395Skan	    {
722117395Skan	      tree binfo = TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), i);
723117395Skan	      record_alias_subset (superset,
724117395Skan				   get_alias_set (BINFO_TYPE (binfo)));
725117395Skan	    }
726117395Skan	}
72790075Sobrien      for (field = TYPE_FIELDS (type); field != 0; field = TREE_CHAIN (field))
72890075Sobrien	if (TREE_CODE (field) == FIELD_DECL && ! DECL_NONADDRESSABLE_P (field))
72990075Sobrien	  record_alias_subset (superset, get_alias_set (TREE_TYPE (field)));
73090075Sobrien      break;
73190075Sobrien
73290075Sobrien    case COMPLEX_TYPE:
73390075Sobrien      record_alias_subset (superset, get_alias_set (TREE_TYPE (type)));
73490075Sobrien      break;
73590075Sobrien
73690075Sobrien    default:
73790075Sobrien      break;
73890075Sobrien    }
73952284Sobrien}
74052284Sobrien
74190075Sobrien/* Allocate an alias set for use in storing and reading from the varargs
74290075Sobrien   spill area.  */
74390075Sobrien
744132718Skanstatic GTY(()) HOST_WIDE_INT varargs_set = -1;
745132718Skan
74690075SobrienHOST_WIDE_INT
747132718Skanget_varargs_alias_set (void)
74890075Sobrien{
749132718Skan  if (varargs_set == -1)
750132718Skan    varargs_set = new_alias_set ();
75190075Sobrien
752132718Skan  return varargs_set;
75390075Sobrien}
75490075Sobrien
75590075Sobrien/* Likewise, but used for the fixed portions of the frame, e.g., register
75690075Sobrien   save areas.  */
75790075Sobrien
758132718Skanstatic GTY(()) HOST_WIDE_INT frame_set = -1;
759132718Skan
76090075SobrienHOST_WIDE_INT
761132718Skanget_frame_alias_set (void)
76290075Sobrien{
763132718Skan  if (frame_set == -1)
764132718Skan    frame_set = new_alias_set ();
76590075Sobrien
766132718Skan  return frame_set;
76790075Sobrien}
76890075Sobrien
76950397Sobrien/* Inside SRC, the source of a SET, find a base address.  */
77050397Sobrien
77150397Sobrienstatic rtx
772132718Skanfind_base_value (rtx src)
77350397Sobrien{
77490075Sobrien  unsigned int regno;
77596263Sobrien
77650397Sobrien  switch (GET_CODE (src))
77750397Sobrien    {
77850397Sobrien    case SYMBOL_REF:
77950397Sobrien    case LABEL_REF:
78050397Sobrien      return src;
78150397Sobrien
78250397Sobrien    case REG:
78390075Sobrien      regno = REGNO (src);
78490075Sobrien      /* At the start of a function, argument registers have known base
78550397Sobrien	 values which may be lost later.  Returning an ADDRESS
78650397Sobrien	 expression here allows optimization based on argument values
78750397Sobrien	 even when the argument registers are used for other purposes.  */
78890075Sobrien      if (regno < FIRST_PSEUDO_REGISTER && copying_arguments)
78990075Sobrien	return new_reg_base_value[regno];
79050397Sobrien
79150397Sobrien      /* If a pseudo has a known base value, return it.  Do not do this
79296263Sobrien	 for non-fixed hard regs since it can result in a circular
79396263Sobrien	 dependency chain for registers which have values at function entry.
79450397Sobrien
79550397Sobrien	 The test above is not sufficient because the scheduler may move
79650397Sobrien	 a copy out of an arg reg past the NOTE_INSN_FUNCTION_BEGIN.  */
79796263Sobrien      if ((regno >= FIRST_PSEUDO_REGISTER || fixed_regs[regno])
798132718Skan	  && regno < VARRAY_SIZE (reg_base_value))
799117395Skan	{
800117395Skan	  /* If we're inside init_alias_analysis, use new_reg_base_value
801117395Skan	     to reduce the number of relaxation iterations.  */
802117395Skan	  if (new_reg_base_value && new_reg_base_value[regno]
803117395Skan	      && REG_N_SETS (regno) == 1)
804117395Skan	    return new_reg_base_value[regno];
80550397Sobrien
806132718Skan	  if (VARRAY_RTX (reg_base_value, regno))
807132718Skan	    return VARRAY_RTX (reg_base_value, regno);
808117395Skan	}
809117395Skan
810122180Skan      return 0;
81150397Sobrien
81250397Sobrien    case MEM:
81350397Sobrien      /* Check for an argument passed in memory.  Only record in the
81450397Sobrien	 copying-arguments block; it is too hard to track changes
81550397Sobrien	 otherwise.  */
81650397Sobrien      if (copying_arguments
81750397Sobrien	  && (XEXP (src, 0) == arg_pointer_rtx
81850397Sobrien	      || (GET_CODE (XEXP (src, 0)) == PLUS
81950397Sobrien		  && XEXP (XEXP (src, 0), 0) == arg_pointer_rtx)))
82050397Sobrien	return gen_rtx_ADDRESS (VOIDmode, src);
82150397Sobrien      return 0;
82250397Sobrien
82350397Sobrien    case CONST:
82450397Sobrien      src = XEXP (src, 0);
82550397Sobrien      if (GET_CODE (src) != PLUS && GET_CODE (src) != MINUS)
82650397Sobrien	break;
82750397Sobrien
82890075Sobrien      /* ... fall through ...  */
82990075Sobrien
83050397Sobrien    case PLUS:
83150397Sobrien    case MINUS:
83250397Sobrien      {
83350397Sobrien	rtx temp, src_0 = XEXP (src, 0), src_1 = XEXP (src, 1);
83450397Sobrien
83590075Sobrien	/* If either operand is a REG that is a known pointer, then it
83690075Sobrien	   is the base.  */
83790075Sobrien	if (REG_P (src_0) && REG_POINTER (src_0))
83890075Sobrien	  return find_base_value (src_0);
83990075Sobrien	if (REG_P (src_1) && REG_POINTER (src_1))
84090075Sobrien	  return find_base_value (src_1);
84190075Sobrien
84250397Sobrien	/* If either operand is a REG, then see if we already have
84350397Sobrien	   a known value for it.  */
84490075Sobrien	if (REG_P (src_0))
84550397Sobrien	  {
84650397Sobrien	    temp = find_base_value (src_0);
84790075Sobrien	    if (temp != 0)
84850397Sobrien	      src_0 = temp;
84950397Sobrien	  }
85050397Sobrien
85190075Sobrien	if (REG_P (src_1))
85250397Sobrien	  {
85350397Sobrien	    temp = find_base_value (src_1);
85490075Sobrien	    if (temp!= 0)
85550397Sobrien	      src_1 = temp;
85650397Sobrien	  }
85750397Sobrien
85890075Sobrien	/* If either base is named object or a special address
85990075Sobrien	   (like an argument or stack reference), then use it for the
86090075Sobrien	   base term.  */
86190075Sobrien	if (src_0 != 0
86290075Sobrien	    && (GET_CODE (src_0) == SYMBOL_REF
86390075Sobrien		|| GET_CODE (src_0) == LABEL_REF
86490075Sobrien		|| (GET_CODE (src_0) == ADDRESS
86590075Sobrien		    && GET_MODE (src_0) != VOIDmode)))
86690075Sobrien	  return src_0;
86750397Sobrien
86890075Sobrien	if (src_1 != 0
86990075Sobrien	    && (GET_CODE (src_1) == SYMBOL_REF
87090075Sobrien		|| GET_CODE (src_1) == LABEL_REF
87190075Sobrien		|| (GET_CODE (src_1) == ADDRESS
87290075Sobrien		    && GET_MODE (src_1) != VOIDmode)))
87390075Sobrien	  return src_1;
87490075Sobrien
87590075Sobrien	/* Guess which operand is the base address:
87650397Sobrien	   If either operand is a symbol, then it is the base.  If
87750397Sobrien	   either operand is a CONST_INT, then the other is the base.  */
87890075Sobrien	if (GET_CODE (src_1) == CONST_INT || CONSTANT_P (src_0))
87950397Sobrien	  return find_base_value (src_0);
88090075Sobrien	else if (GET_CODE (src_0) == CONST_INT || CONSTANT_P (src_1))
88150397Sobrien	  return find_base_value (src_1);
88250397Sobrien
88350397Sobrien	return 0;
88450397Sobrien      }
88550397Sobrien
88650397Sobrien    case LO_SUM:
88750397Sobrien      /* The standard form is (lo_sum reg sym) so look only at the
88850397Sobrien	 second operand.  */
88950397Sobrien      return find_base_value (XEXP (src, 1));
89050397Sobrien
89150397Sobrien    case AND:
89250397Sobrien      /* If the second operand is constant set the base
89390075Sobrien	 address to the first operand.  */
89450397Sobrien      if (GET_CODE (XEXP (src, 1)) == CONST_INT && INTVAL (XEXP (src, 1)) != 0)
89550397Sobrien	return find_base_value (XEXP (src, 0));
89650397Sobrien      return 0;
89750397Sobrien
89890075Sobrien    case TRUNCATE:
89990075Sobrien      if (GET_MODE_SIZE (GET_MODE (src)) < GET_MODE_SIZE (Pmode))
90090075Sobrien	break;
90190075Sobrien      /* Fall through.  */
90250397Sobrien    case HIGH:
90390075Sobrien    case PRE_INC:
90490075Sobrien    case PRE_DEC:
90590075Sobrien    case POST_INC:
90690075Sobrien    case POST_DEC:
90790075Sobrien    case PRE_MODIFY:
90890075Sobrien    case POST_MODIFY:
90950397Sobrien      return find_base_value (XEXP (src, 0));
91050397Sobrien
91196263Sobrien    case ZERO_EXTEND:
91296263Sobrien    case SIGN_EXTEND:	/* used for NT/Alpha pointers */
91396263Sobrien      {
91496263Sobrien	rtx temp = find_base_value (XEXP (src, 0));
91596263Sobrien
916132718Skan	if (temp != 0 && CONSTANT_P (temp))
91796263Sobrien	  temp = convert_memory_address (Pmode, temp);
91896263Sobrien
91996263Sobrien	return temp;
92096263Sobrien      }
92196263Sobrien
92250397Sobrien    default:
92350397Sobrien      break;
92450397Sobrien    }
92550397Sobrien
92650397Sobrien  return 0;
92750397Sobrien}
92850397Sobrien
92950397Sobrien/* Called from init_alias_analysis indirectly through note_stores.  */
93050397Sobrien
93190075Sobrien/* While scanning insns to find base values, reg_seen[N] is nonzero if
93250397Sobrien   register N has been set in this function.  */
93350397Sobrienstatic char *reg_seen;
93450397Sobrien
93550397Sobrien/* Addresses which are known not to alias anything else are identified
93650397Sobrien   by a unique integer.  */
93750397Sobrienstatic int unique_id;
93850397Sobrien
93950397Sobrienstatic void
940132718Skanrecord_set (rtx dest, rtx set, void *data ATTRIBUTE_UNUSED)
94150397Sobrien{
94290075Sobrien  unsigned regno;
94350397Sobrien  rtx src;
944132718Skan  int n;
94550397Sobrien
94650397Sobrien  if (GET_CODE (dest) != REG)
94750397Sobrien    return;
94850397Sobrien
94950397Sobrien  regno = REGNO (dest);
95050397Sobrien
951132718Skan  if (regno >= VARRAY_SIZE (reg_base_value))
95290075Sobrien    abort ();
95390075Sobrien
954132718Skan  /* If this spans multiple hard registers, then we must indicate that every
955132718Skan     register has an unusable value.  */
956132718Skan  if (regno < FIRST_PSEUDO_REGISTER)
957132718Skan    n = HARD_REGNO_NREGS (regno, GET_MODE (dest));
958132718Skan  else
959132718Skan    n = 1;
960132718Skan  if (n != 1)
961132718Skan    {
962132718Skan      while (--n >= 0)
963132718Skan	{
964132718Skan	  reg_seen[regno + n] = 1;
965132718Skan	  new_reg_base_value[regno + n] = 0;
966132718Skan	}
967132718Skan      return;
968132718Skan    }
969132718Skan
97050397Sobrien  if (set)
97150397Sobrien    {
97250397Sobrien      /* A CLOBBER wipes out any old value but does not prevent a previously
97350397Sobrien	 unset register from acquiring a base address (i.e. reg_seen is not
97450397Sobrien	 set).  */
97550397Sobrien      if (GET_CODE (set) == CLOBBER)
97650397Sobrien	{
97750397Sobrien	  new_reg_base_value[regno] = 0;
97850397Sobrien	  return;
97950397Sobrien	}
98050397Sobrien      src = SET_SRC (set);
98150397Sobrien    }
98250397Sobrien  else
98350397Sobrien    {
98450397Sobrien      if (reg_seen[regno])
98550397Sobrien	{
98650397Sobrien	  new_reg_base_value[regno] = 0;
98750397Sobrien	  return;
98850397Sobrien	}
98950397Sobrien      reg_seen[regno] = 1;
99050397Sobrien      new_reg_base_value[regno] = gen_rtx_ADDRESS (Pmode,
99150397Sobrien						   GEN_INT (unique_id++));
99250397Sobrien      return;
99350397Sobrien    }
99450397Sobrien
99550397Sobrien  /* This is not the first set.  If the new value is not related to the
99650397Sobrien     old value, forget the base value. Note that the following code is
99750397Sobrien     not detected:
99850397Sobrien     extern int x, y;  int *p = &x; p += (&y-&x);
99950397Sobrien     ANSI C does not allow computing the difference of addresses
100050397Sobrien     of distinct top level objects.  */
100150397Sobrien  if (new_reg_base_value[regno])
100250397Sobrien    switch (GET_CODE (src))
100350397Sobrien      {
100450397Sobrien      case LO_SUM:
100550397Sobrien      case MINUS:
100650397Sobrien	if (XEXP (src, 0) != dest && XEXP (src, 1) != dest)
100750397Sobrien	  new_reg_base_value[regno] = 0;
100850397Sobrien	break;
100990075Sobrien      case PLUS:
101090075Sobrien	/* If the value we add in the PLUS is also a valid base value,
101190075Sobrien	   this might be the actual base value, and the original value
101290075Sobrien	   an index.  */
101390075Sobrien	{
101490075Sobrien	  rtx other = NULL_RTX;
101590075Sobrien
101690075Sobrien	  if (XEXP (src, 0) == dest)
101790075Sobrien	    other = XEXP (src, 1);
101890075Sobrien	  else if (XEXP (src, 1) == dest)
101990075Sobrien	    other = XEXP (src, 0);
102090075Sobrien
102190075Sobrien	  if (! other || find_base_value (other))
102290075Sobrien	    new_reg_base_value[regno] = 0;
102390075Sobrien	  break;
102490075Sobrien	}
102550397Sobrien      case AND:
102650397Sobrien	if (XEXP (src, 0) != dest || GET_CODE (XEXP (src, 1)) != CONST_INT)
102750397Sobrien	  new_reg_base_value[regno] = 0;
102850397Sobrien	break;
102950397Sobrien      default:
103050397Sobrien	new_reg_base_value[regno] = 0;
103150397Sobrien	break;
103250397Sobrien      }
103350397Sobrien  /* If this is the first set of a register, record the value.  */
103450397Sobrien  else if ((regno >= FIRST_PSEUDO_REGISTER || ! fixed_regs[regno])
103550397Sobrien	   && ! reg_seen[regno] && new_reg_base_value[regno] == 0)
103650397Sobrien    new_reg_base_value[regno] = find_base_value (src);
103750397Sobrien
103850397Sobrien  reg_seen[regno] = 1;
103950397Sobrien}
104050397Sobrien
104190075Sobrien/* Called from loop optimization when a new pseudo-register is
104290075Sobrien   created.  It indicates that REGNO is being set to VAL.  f INVARIANT
104390075Sobrien   is true then this value also describes an invariant relationship
104490075Sobrien   which can be used to deduce that two registers with unknown values
104590075Sobrien   are different.  */
104690075Sobrien
104750397Sobrienvoid
1048132718Skanrecord_base_value (unsigned int regno, rtx val, int invariant)
104950397Sobrien{
1050132718Skan  if (invariant && alias_invariant && regno < alias_invariant_size)
105150397Sobrien    alias_invariant[regno] = val;
105250397Sobrien
1053132718Skan  if (regno >= VARRAY_SIZE (reg_base_value))
1054132718Skan    VARRAY_GROW (reg_base_value, max_reg_num ());
1055132718Skan
105650397Sobrien  if (GET_CODE (val) == REG)
105750397Sobrien    {
1058132718Skan      VARRAY_RTX (reg_base_value, regno)
1059132718Skan	 = REG_BASE_VALUE (val);
106050397Sobrien      return;
106150397Sobrien    }
1062132718Skan  VARRAY_RTX (reg_base_value, regno)
1063132718Skan     = find_base_value (val);
106450397Sobrien}
106550397Sobrien
106690075Sobrien/* Clear alias info for a register.  This is used if an RTL transformation
106790075Sobrien   changes the value of a register.  This is used in flow by AUTO_INC_DEC
106890075Sobrien   optimizations.  We don't need to clear reg_base_value, since flow only
106990075Sobrien   changes the offset.  */
107090075Sobrien
107190075Sobrienvoid
1072132718Skanclear_reg_alias_info (rtx reg)
107390075Sobrien{
107490075Sobrien  unsigned int regno = REGNO (reg);
107590075Sobrien
1076132718Skan  if (regno >= FIRST_PSEUDO_REGISTER)
1077132718Skan    {
1078132718Skan      regno -= FIRST_PSEUDO_REGISTER;
1079132718Skan      if (regno < reg_known_value_size)
1080132718Skan	{
1081132718Skan	  reg_known_value[regno] = reg;
1082132718Skan	  reg_known_equiv_p[regno] = false;
1083132718Skan	}
1084132718Skan    }
108590075Sobrien}
108690075Sobrien
1087132718Skan/* If a value is known for REGNO, return it.  */
1088132718Skan
1089132718Skanrtx
1090132718Skanget_reg_known_value (unsigned int regno)
1091132718Skan{
1092132718Skan  if (regno >= FIRST_PSEUDO_REGISTER)
1093132718Skan    {
1094132718Skan      regno -= FIRST_PSEUDO_REGISTER;
1095132718Skan      if (regno < reg_known_value_size)
1096132718Skan	return reg_known_value[regno];
1097132718Skan    }
1098132718Skan  return NULL;
1099132718Skan}
1100132718Skan
1101132718Skan/* Set it.  */
1102132718Skan
1103132718Skanstatic void
1104132718Skanset_reg_known_value (unsigned int regno, rtx val)
1105132718Skan{
1106132718Skan  if (regno >= FIRST_PSEUDO_REGISTER)
1107132718Skan    {
1108132718Skan      regno -= FIRST_PSEUDO_REGISTER;
1109132718Skan      if (regno < reg_known_value_size)
1110132718Skan	reg_known_value[regno] = val;
1111132718Skan    }
1112132718Skan}
1113132718Skan
1114132718Skan/* Similarly for reg_known_equiv_p.  */
1115132718Skan
1116132718Skanbool
1117132718Skanget_reg_known_equiv_p (unsigned int regno)
1118132718Skan{
1119132718Skan  if (regno >= FIRST_PSEUDO_REGISTER)
1120132718Skan    {
1121132718Skan      regno -= FIRST_PSEUDO_REGISTER;
1122132718Skan      if (regno < reg_known_value_size)
1123132718Skan	return reg_known_equiv_p[regno];
1124132718Skan    }
1125132718Skan  return false;
1126132718Skan}
1127132718Skan
1128132718Skanstatic void
1129132718Skanset_reg_known_equiv_p (unsigned int regno, bool val)
1130132718Skan{
1131132718Skan  if (regno >= FIRST_PSEUDO_REGISTER)
1132132718Skan    {
1133132718Skan      regno -= FIRST_PSEUDO_REGISTER;
1134132718Skan      if (regno < reg_known_value_size)
1135132718Skan	reg_known_equiv_p[regno] = val;
1136132718Skan    }
1137132718Skan}
1138132718Skan
1139132718Skan
114090075Sobrien/* Returns a canonical version of X, from the point of view alias
114190075Sobrien   analysis.  (For example, if X is a MEM whose address is a register,
114290075Sobrien   and the register has a known value (say a SYMBOL_REF), then a MEM
114390075Sobrien   whose address is the SYMBOL_REF is returned.)  */
114490075Sobrien
114590075Sobrienrtx
1146132718Skancanon_rtx (rtx x)
114750397Sobrien{
114850397Sobrien  /* Recursively look for equivalences.  */
1149132718Skan  if (GET_CODE (x) == REG && REGNO (x) >= FIRST_PSEUDO_REGISTER)
115050397Sobrien    {
1151132718Skan      rtx t = get_reg_known_value (REGNO (x));
1152132718Skan      if (t == x)
1153132718Skan	return x;
1154132718Skan      if (t)
1155132718Skan	return canon_rtx (t);
1156132718Skan    }
1157132718Skan
1158132718Skan  if (GET_CODE (x) == PLUS)
1159132718Skan    {
116050397Sobrien      rtx x0 = canon_rtx (XEXP (x, 0));
116150397Sobrien      rtx x1 = canon_rtx (XEXP (x, 1));
116250397Sobrien
116350397Sobrien      if (x0 != XEXP (x, 0) || x1 != XEXP (x, 1))
116450397Sobrien	{
116550397Sobrien	  if (GET_CODE (x0) == CONST_INT)
116690075Sobrien	    return plus_constant (x1, INTVAL (x0));
116750397Sobrien	  else if (GET_CODE (x1) == CONST_INT)
116890075Sobrien	    return plus_constant (x0, INTVAL (x1));
116950397Sobrien	  return gen_rtx_PLUS (GET_MODE (x), x0, x1);
117050397Sobrien	}
117150397Sobrien    }
117290075Sobrien
117350397Sobrien  /* This gives us much better alias analysis when called from
117450397Sobrien     the loop optimizer.   Note we want to leave the original
117550397Sobrien     MEM alone, but need to return the canonicalized MEM with
117650397Sobrien     all the flags with their original values.  */
117750397Sobrien  else if (GET_CODE (x) == MEM)
117890075Sobrien    x = replace_equiv_address_nv (x, canon_rtx (XEXP (x, 0)));
117990075Sobrien
118050397Sobrien  return x;
118150397Sobrien}
118250397Sobrien
118350397Sobrien/* Return 1 if X and Y are identical-looking rtx's.
1184132718Skan   Expect that X and Y has been already canonicalized.
118550397Sobrien
118650397Sobrien   We use the data in reg_known_value above to see if two registers with
118750397Sobrien   different numbers are, in fact, equivalent.  */
118850397Sobrien
118950397Sobrienstatic int
1190132718Skanrtx_equal_for_memref_p (rtx x, rtx y)
119150397Sobrien{
119290075Sobrien  int i;
119390075Sobrien  int j;
119490075Sobrien  enum rtx_code code;
119590075Sobrien  const char *fmt;
119650397Sobrien
119750397Sobrien  if (x == 0 && y == 0)
119850397Sobrien    return 1;
119950397Sobrien  if (x == 0 || y == 0)
120050397Sobrien    return 0;
120190075Sobrien
120250397Sobrien  if (x == y)
120350397Sobrien    return 1;
120450397Sobrien
120550397Sobrien  code = GET_CODE (x);
120650397Sobrien  /* Rtx's of different codes cannot be equal.  */
120750397Sobrien  if (code != GET_CODE (y))
120850397Sobrien    return 0;
120950397Sobrien
121050397Sobrien  /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent.
121150397Sobrien     (REG:SI x) and (REG:HI x) are NOT equivalent.  */
121250397Sobrien
121350397Sobrien  if (GET_MODE (x) != GET_MODE (y))
121450397Sobrien    return 0;
121550397Sobrien
121690075Sobrien  /* Some RTL can be compared without a recursive examination.  */
121790075Sobrien  switch (code)
121890075Sobrien    {
121990075Sobrien    case REG:
122090075Sobrien      return REGNO (x) == REGNO (y);
122150397Sobrien
122290075Sobrien    case LABEL_REF:
122390075Sobrien      return XEXP (x, 0) == XEXP (y, 0);
1224117395Skan
122590075Sobrien    case SYMBOL_REF:
122690075Sobrien      return XSTR (x, 0) == XSTR (y, 0);
122790075Sobrien
1228132718Skan    case VALUE:
122990075Sobrien    case CONST_INT:
123090075Sobrien    case CONST_DOUBLE:
123190075Sobrien      /* There's no need to compare the contents of CONST_DOUBLEs or
123290075Sobrien	 CONST_INTs because pointer equality is a good enough
123390075Sobrien	 comparison for these nodes.  */
123490075Sobrien      return 0;
123590075Sobrien
123690075Sobrien    case ADDRESSOF:
123790075Sobrien      return (XINT (x, 1) == XINT (y, 1)
1238132718Skan	      && rtx_equal_for_memref_p (XEXP (x, 0),
1239132718Skan					 XEXP (y, 0)));
124090075Sobrien
124190075Sobrien    default:
124290075Sobrien      break;
124390075Sobrien    }
124490075Sobrien
1245132718Skan  /* canon_rtx knows how to handle plus.  No need to canonicalize.  */
1246132718Skan  if (code == PLUS)
124750397Sobrien    return ((rtx_equal_for_memref_p (XEXP (x, 0), XEXP (y, 0))
124850397Sobrien	     && rtx_equal_for_memref_p (XEXP (x, 1), XEXP (y, 1)))
124950397Sobrien	    || (rtx_equal_for_memref_p (XEXP (x, 0), XEXP (y, 1))
125050397Sobrien		&& rtx_equal_for_memref_p (XEXP (x, 1), XEXP (y, 0))));
1251132718Skan  /* For commutative operations, the RTX match if the operand match in any
1252132718Skan     order.  Also handle the simple binary and unary cases without a loop.  */
1253132718Skan  if (code == EQ || code == NE || GET_RTX_CLASS (code) == 'c')
1254132718Skan    {
1255132718Skan      rtx xop0 = canon_rtx (XEXP (x, 0));
1256132718Skan      rtx yop0 = canon_rtx (XEXP (y, 0));
1257132718Skan      rtx yop1 = canon_rtx (XEXP (y, 1));
1258132718Skan
1259132718Skan      return ((rtx_equal_for_memref_p (xop0, yop0)
1260132718Skan	       && rtx_equal_for_memref_p (canon_rtx (XEXP (x, 1)), yop1))
1261132718Skan	      || (rtx_equal_for_memref_p (xop0, yop1)
1262132718Skan		  && rtx_equal_for_memref_p (canon_rtx (XEXP (x, 1)), yop0)));
1263132718Skan    }
126450397Sobrien  else if (GET_RTX_CLASS (code) == '<' || GET_RTX_CLASS (code) == '2')
1265132718Skan    {
1266132718Skan      return (rtx_equal_for_memref_p (canon_rtx (XEXP (x, 0)),
1267132718Skan				      canon_rtx (XEXP (y, 0)))
1268132718Skan	      && rtx_equal_for_memref_p (canon_rtx (XEXP (x, 1)),
1269132718Skan					 canon_rtx (XEXP (y, 1))));
1270132718Skan    }
127150397Sobrien  else if (GET_RTX_CLASS (code) == '1')
1272132718Skan    return rtx_equal_for_memref_p (canon_rtx (XEXP (x, 0)),
1273132718Skan				   canon_rtx (XEXP (y, 0)));
127450397Sobrien
127550397Sobrien  /* Compare the elements.  If any pair of corresponding elements
127650397Sobrien     fail to match, return 0 for the whole things.
127750397Sobrien
127850397Sobrien     Limit cases to types which actually appear in addresses.  */
127950397Sobrien
128050397Sobrien  fmt = GET_RTX_FORMAT (code);
128150397Sobrien  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
128250397Sobrien    {
128350397Sobrien      switch (fmt[i])
128450397Sobrien	{
128550397Sobrien	case 'i':
128650397Sobrien	  if (XINT (x, i) != XINT (y, i))
128750397Sobrien	    return 0;
128850397Sobrien	  break;
128950397Sobrien
129050397Sobrien	case 'E':
129150397Sobrien	  /* Two vectors must have the same length.  */
129250397Sobrien	  if (XVECLEN (x, i) != XVECLEN (y, i))
129350397Sobrien	    return 0;
129450397Sobrien
129550397Sobrien	  /* And the corresponding elements must match.  */
129650397Sobrien	  for (j = 0; j < XVECLEN (x, i); j++)
1297132718Skan	    if (rtx_equal_for_memref_p (canon_rtx (XVECEXP (x, i, j)),
1298132718Skan					canon_rtx (XVECEXP (y, i, j))) == 0)
129950397Sobrien	      return 0;
130050397Sobrien	  break;
130150397Sobrien
130250397Sobrien	case 'e':
1303132718Skan	  if (rtx_equal_for_memref_p (canon_rtx (XEXP (x, i)),
1304132718Skan				      canon_rtx (XEXP (y, i))) == 0)
130550397Sobrien	    return 0;
130650397Sobrien	  break;
130750397Sobrien
130890075Sobrien	  /* This can happen for asm operands.  */
130990075Sobrien	case 's':
131090075Sobrien	  if (strcmp (XSTR (x, i), XSTR (y, i)))
131190075Sobrien	    return 0;
131290075Sobrien	  break;
131390075Sobrien
131450397Sobrien	/* This can happen for an asm which clobbers memory.  */
131550397Sobrien	case '0':
131650397Sobrien	  break;
131750397Sobrien
131850397Sobrien	  /* It is believed that rtx's at this level will never
131950397Sobrien	     contain anything but integers and other rtx's,
132050397Sobrien	     except for within LABEL_REFs and SYMBOL_REFs.  */
132150397Sobrien	default:
132250397Sobrien	  abort ();
132350397Sobrien	}
132450397Sobrien    }
132550397Sobrien  return 1;
132650397Sobrien}
132750397Sobrien
132850397Sobrien/* Given an rtx X, find a SYMBOL_REF or LABEL_REF within
132950397Sobrien   X and return it, or return 0 if none found.  */
133050397Sobrien
133150397Sobrienstatic rtx
1332132718Skanfind_symbolic_term (rtx x)
133350397Sobrien{
133490075Sobrien  int i;
133590075Sobrien  enum rtx_code code;
133690075Sobrien  const char *fmt;
133750397Sobrien
133850397Sobrien  code = GET_CODE (x);
133950397Sobrien  if (code == SYMBOL_REF || code == LABEL_REF)
134050397Sobrien    return x;
134150397Sobrien  if (GET_RTX_CLASS (code) == 'o')
134250397Sobrien    return 0;
134350397Sobrien
134450397Sobrien  fmt = GET_RTX_FORMAT (code);
134550397Sobrien  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
134650397Sobrien    {
134750397Sobrien      rtx t;
134850397Sobrien
134950397Sobrien      if (fmt[i] == 'e')
135050397Sobrien	{
135150397Sobrien	  t = find_symbolic_term (XEXP (x, i));
135250397Sobrien	  if (t != 0)
135350397Sobrien	    return t;
135450397Sobrien	}
135550397Sobrien      else if (fmt[i] == 'E')
135650397Sobrien	break;
135750397Sobrien    }
135850397Sobrien  return 0;
135950397Sobrien}
136050397Sobrien
1361132718Skanrtx
1362132718Skanfind_base_term (rtx x)
136350397Sobrien{
136490075Sobrien  cselib_val *val;
136590075Sobrien  struct elt_loc_list *l;
136690075Sobrien
136790075Sobrien#if defined (FIND_BASE_TERM)
136890075Sobrien  /* Try machine-dependent ways to find the base term.  */
136990075Sobrien  x = FIND_BASE_TERM (x);
137090075Sobrien#endif
137190075Sobrien
137250397Sobrien  switch (GET_CODE (x))
137350397Sobrien    {
137450397Sobrien    case REG:
137550397Sobrien      return REG_BASE_VALUE (x);
137650397Sobrien
137790075Sobrien    case TRUNCATE:
137890075Sobrien      if (GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (Pmode))
1379117395Skan	return 0;
138090075Sobrien      /* Fall through.  */
138150397Sobrien    case HIGH:
138250397Sobrien    case PRE_INC:
138350397Sobrien    case PRE_DEC:
138450397Sobrien    case POST_INC:
138550397Sobrien    case POST_DEC:
138690075Sobrien    case PRE_MODIFY:
138790075Sobrien    case POST_MODIFY:
138850397Sobrien      return find_base_term (XEXP (x, 0));
138950397Sobrien
139096263Sobrien    case ZERO_EXTEND:
139196263Sobrien    case SIGN_EXTEND:	/* Used for Alpha/NT pointers */
139296263Sobrien      {
139396263Sobrien	rtx temp = find_base_term (XEXP (x, 0));
139496263Sobrien
1395132718Skan	if (temp != 0 && CONSTANT_P (temp))
139696263Sobrien	  temp = convert_memory_address (Pmode, temp);
139796263Sobrien
139896263Sobrien	return temp;
139996263Sobrien      }
140096263Sobrien
140190075Sobrien    case VALUE:
140290075Sobrien      val = CSELIB_VAL_PTR (x);
1403132718Skan      if (!val)
1404132718Skan	return 0;
140590075Sobrien      for (l = val->locs; l; l = l->next)
140690075Sobrien	if ((x = find_base_term (l->loc)) != 0)
140790075Sobrien	  return x;
140890075Sobrien      return 0;
140990075Sobrien
141050397Sobrien    case CONST:
141150397Sobrien      x = XEXP (x, 0);
141250397Sobrien      if (GET_CODE (x) != PLUS && GET_CODE (x) != MINUS)
141350397Sobrien	return 0;
1414132718Skan      /* Fall through.  */
141550397Sobrien    case LO_SUM:
141650397Sobrien    case PLUS:
141750397Sobrien    case MINUS:
141850397Sobrien      {
141952284Sobrien	rtx tmp1 = XEXP (x, 0);
142052284Sobrien	rtx tmp2 = XEXP (x, 1);
142152284Sobrien
142290075Sobrien	/* This is a little bit tricky since we have to determine which of
142352284Sobrien	   the two operands represents the real base address.  Otherwise this
142452284Sobrien	   routine may return the index register instead of the base register.
142552284Sobrien
142652284Sobrien	   That may cause us to believe no aliasing was possible, when in
142752284Sobrien	   fact aliasing is possible.
142852284Sobrien
142952284Sobrien	   We use a few simple tests to guess the base register.  Additional
143052284Sobrien	   tests can certainly be added.  For example, if one of the operands
143152284Sobrien	   is a shift or multiply, then it must be the index register and the
143252284Sobrien	   other operand is the base register.  */
1433117395Skan
143490075Sobrien	if (tmp1 == pic_offset_table_rtx && CONSTANT_P (tmp2))
143590075Sobrien	  return find_base_term (tmp2);
143690075Sobrien
143752284Sobrien	/* If either operand is known to be a pointer, then use it
143852284Sobrien	   to determine the base term.  */
143990075Sobrien	if (REG_P (tmp1) && REG_POINTER (tmp1))
144052284Sobrien	  return find_base_term (tmp1);
144152284Sobrien
144290075Sobrien	if (REG_P (tmp2) && REG_POINTER (tmp2))
144352284Sobrien	  return find_base_term (tmp2);
144452284Sobrien
144552284Sobrien	/* Neither operand was known to be a pointer.  Go ahead and find the
144652284Sobrien	   base term for both operands.  */
144752284Sobrien	tmp1 = find_base_term (tmp1);
144852284Sobrien	tmp2 = find_base_term (tmp2);
144952284Sobrien
145052284Sobrien	/* If either base term is named object or a special address
145152284Sobrien	   (like an argument or stack reference), then use it for the
145252284Sobrien	   base term.  */
145390075Sobrien	if (tmp1 != 0
145452284Sobrien	    && (GET_CODE (tmp1) == SYMBOL_REF
145552284Sobrien		|| GET_CODE (tmp1) == LABEL_REF
145652284Sobrien		|| (GET_CODE (tmp1) == ADDRESS
145752284Sobrien		    && GET_MODE (tmp1) != VOIDmode)))
145852284Sobrien	  return tmp1;
145952284Sobrien
146090075Sobrien	if (tmp2 != 0
146152284Sobrien	    && (GET_CODE (tmp2) == SYMBOL_REF
146252284Sobrien		|| GET_CODE (tmp2) == LABEL_REF
146352284Sobrien		|| (GET_CODE (tmp2) == ADDRESS
146452284Sobrien		    && GET_MODE (tmp2) != VOIDmode)))
146552284Sobrien	  return tmp2;
146652284Sobrien
146752284Sobrien	/* We could not determine which of the two operands was the
146852284Sobrien	   base register and which was the index.  So we can determine
146952284Sobrien	   nothing from the base alias check.  */
147052284Sobrien	return 0;
147150397Sobrien      }
147250397Sobrien
147350397Sobrien    case AND:
147490075Sobrien      if (GET_CODE (XEXP (x, 1)) == CONST_INT && INTVAL (XEXP (x, 1)) != 0)
147590075Sobrien	return find_base_term (XEXP (x, 0));
147650397Sobrien      return 0;
147750397Sobrien
147850397Sobrien    case SYMBOL_REF:
147950397Sobrien    case LABEL_REF:
148050397Sobrien      return x;
148150397Sobrien
148290075Sobrien    case ADDRESSOF:
148390075Sobrien      return REG_BASE_VALUE (frame_pointer_rtx);
148490075Sobrien
148550397Sobrien    default:
148650397Sobrien      return 0;
148750397Sobrien    }
148850397Sobrien}
148950397Sobrien
149050397Sobrien/* Return 0 if the addresses X and Y are known to point to different
149150397Sobrien   objects, 1 if they might be pointers to the same object.  */
149250397Sobrien
149350397Sobrienstatic int
1494132718Skanbase_alias_check (rtx x, rtx y, enum machine_mode x_mode,
1495132718Skan		  enum machine_mode y_mode)
149650397Sobrien{
149750397Sobrien  rtx x_base = find_base_term (x);
149850397Sobrien  rtx y_base = find_base_term (y);
149950397Sobrien
150050397Sobrien  /* If the address itself has no known base see if a known equivalent
150150397Sobrien     value has one.  If either address still has no known base, nothing
150250397Sobrien     is known about aliasing.  */
150350397Sobrien  if (x_base == 0)
150450397Sobrien    {
150550397Sobrien      rtx x_c;
150690075Sobrien
150750397Sobrien      if (! flag_expensive_optimizations || (x_c = canon_rtx (x)) == x)
150850397Sobrien	return 1;
150990075Sobrien
151050397Sobrien      x_base = find_base_term (x_c);
151150397Sobrien      if (x_base == 0)
151250397Sobrien	return 1;
151350397Sobrien    }
151450397Sobrien
151550397Sobrien  if (y_base == 0)
151650397Sobrien    {
151750397Sobrien      rtx y_c;
151850397Sobrien      if (! flag_expensive_optimizations || (y_c = canon_rtx (y)) == y)
151950397Sobrien	return 1;
152090075Sobrien
152150397Sobrien      y_base = find_base_term (y_c);
152250397Sobrien      if (y_base == 0)
152350397Sobrien	return 1;
152450397Sobrien    }
152550397Sobrien
152650397Sobrien  /* If the base addresses are equal nothing is known about aliasing.  */
152750397Sobrien  if (rtx_equal_p (x_base, y_base))
152850397Sobrien    return 1;
152950397Sobrien
1530117395Skan  /* The base addresses of the read and write are different expressions.
153152284Sobrien     If they are both symbols and they are not accessed via AND, there is
153252284Sobrien     no conflict.  We can bring knowledge of object alignment into play
153352284Sobrien     here.  For example, on alpha, "char a, b;" can alias one another,
153452284Sobrien     though "char a; long b;" cannot.  */
153550397Sobrien  if (GET_CODE (x_base) != ADDRESS && GET_CODE (y_base) != ADDRESS)
153650397Sobrien    {
153752284Sobrien      if (GET_CODE (x) == AND && GET_CODE (y) == AND)
153852284Sobrien	return 1;
153952284Sobrien      if (GET_CODE (x) == AND
154052284Sobrien	  && (GET_CODE (XEXP (x, 1)) != CONST_INT
154190075Sobrien	      || (int) GET_MODE_UNIT_SIZE (y_mode) < -INTVAL (XEXP (x, 1))))
154252284Sobrien	return 1;
154352284Sobrien      if (GET_CODE (y) == AND
154452284Sobrien	  && (GET_CODE (XEXP (y, 1)) != CONST_INT
154590075Sobrien	      || (int) GET_MODE_UNIT_SIZE (x_mode) < -INTVAL (XEXP (y, 1))))
154652284Sobrien	return 1;
154752284Sobrien      /* Differing symbols never alias.  */
154852284Sobrien      return 0;
154950397Sobrien    }
155050397Sobrien
155150397Sobrien  /* If one address is a stack reference there can be no alias:
155250397Sobrien     stack references using different base registers do not alias,
155350397Sobrien     a stack reference can not alias a parameter, and a stack reference
155450397Sobrien     can not alias a global.  */
155550397Sobrien  if ((GET_CODE (x_base) == ADDRESS && GET_MODE (x_base) == Pmode)
155650397Sobrien      || (GET_CODE (y_base) == ADDRESS && GET_MODE (y_base) == Pmode))
155750397Sobrien    return 0;
155850397Sobrien
155950397Sobrien  if (! flag_argument_noalias)
156050397Sobrien    return 1;
156150397Sobrien
156250397Sobrien  if (flag_argument_noalias > 1)
156350397Sobrien    return 0;
156450397Sobrien
156590075Sobrien  /* Weak noalias assertion (arguments are distinct, but may match globals).  */
156650397Sobrien  return ! (GET_MODE (x_base) == VOIDmode && GET_MODE (y_base) == VOIDmode);
156750397Sobrien}
156850397Sobrien
156990075Sobrien/* Convert the address X into something we can use.  This is done by returning
157090075Sobrien   it unchanged unless it is a value; in the latter case we call cselib to get
157190075Sobrien   a more useful rtx.  */
157290075Sobrien
157390075Sobrienrtx
1574132718Skanget_addr (rtx x)
157590075Sobrien{
157690075Sobrien  cselib_val *v;
157790075Sobrien  struct elt_loc_list *l;
157890075Sobrien
157990075Sobrien  if (GET_CODE (x) != VALUE)
158090075Sobrien    return x;
158190075Sobrien  v = CSELIB_VAL_PTR (x);
1582132718Skan  if (v)
1583132718Skan    {
1584132718Skan      for (l = v->locs; l; l = l->next)
1585132718Skan	if (CONSTANT_P (l->loc))
1586132718Skan	  return l->loc;
1587132718Skan      for (l = v->locs; l; l = l->next)
1588132718Skan	if (GET_CODE (l->loc) != REG && GET_CODE (l->loc) != MEM)
1589132718Skan	  return l->loc;
1590132718Skan      if (v->locs)
1591132718Skan	return v->locs->loc;
1592132718Skan    }
159390075Sobrien  return x;
159490075Sobrien}
159590075Sobrien
159652284Sobrien/*  Return the address of the (N_REFS + 1)th memory reference to ADDR
159752284Sobrien    where SIZE is the size in bytes of the memory reference.  If ADDR
159852284Sobrien    is not modified by the memory reference then ADDR is returned.  */
159952284Sobrien
160052284Sobrienrtx
1601132718Skanaddr_side_effect_eval (rtx addr, int size, int n_refs)
160252284Sobrien{
160352284Sobrien  int offset = 0;
1604117395Skan
160552284Sobrien  switch (GET_CODE (addr))
160652284Sobrien    {
160752284Sobrien    case PRE_INC:
160852284Sobrien      offset = (n_refs + 1) * size;
160952284Sobrien      break;
161052284Sobrien    case PRE_DEC:
161152284Sobrien      offset = -(n_refs + 1) * size;
161252284Sobrien      break;
161352284Sobrien    case POST_INC:
161452284Sobrien      offset = n_refs * size;
161552284Sobrien      break;
161652284Sobrien    case POST_DEC:
161752284Sobrien      offset = -n_refs * size;
161852284Sobrien      break;
161952284Sobrien
162052284Sobrien    default:
162152284Sobrien      return addr;
162252284Sobrien    }
1623117395Skan
162452284Sobrien  if (offset)
1625132718Skan    addr = gen_rtx_PLUS (GET_MODE (addr), XEXP (addr, 0),
1626132718Skan		         GEN_INT (offset));
162752284Sobrien  else
162852284Sobrien    addr = XEXP (addr, 0);
1629132718Skan  addr = canon_rtx (addr);
163052284Sobrien
163152284Sobrien  return addr;
163252284Sobrien}
163352284Sobrien
163450397Sobrien/* Return nonzero if X and Y (memory addresses) could reference the
163550397Sobrien   same location in memory.  C is an offset accumulator.  When
163650397Sobrien   C is nonzero, we are testing aliases between X and Y + C.
163750397Sobrien   XSIZE is the size in bytes of the X reference,
163850397Sobrien   similarly YSIZE is the size in bytes for Y.
1639132718Skan   Expect that canon_rtx has been already called for X and Y.
164050397Sobrien
164150397Sobrien   If XSIZE or YSIZE is zero, we do not know the amount of memory being
164250397Sobrien   referenced (the reference was BLKmode), so make the most pessimistic
164350397Sobrien   assumptions.
164450397Sobrien
164550397Sobrien   If XSIZE or YSIZE is negative, we may access memory outside the object
164650397Sobrien   being referenced as a side effect.  This can happen when using AND to
164750397Sobrien   align memory references, as is done on the Alpha.
164850397Sobrien
164950397Sobrien   Nice to notice that varying addresses cannot conflict with fp if no
165050397Sobrien   local variables had their addresses taken, but that's too hard now.  */
165150397Sobrien
165250397Sobrienstatic int
1653132718Skanmemrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c)
165450397Sobrien{
165590075Sobrien  if (GET_CODE (x) == VALUE)
165690075Sobrien    x = get_addr (x);
165790075Sobrien  if (GET_CODE (y) == VALUE)
165890075Sobrien    y = get_addr (y);
165950397Sobrien  if (GET_CODE (x) == HIGH)
166050397Sobrien    x = XEXP (x, 0);
166150397Sobrien  else if (GET_CODE (x) == LO_SUM)
166250397Sobrien    x = XEXP (x, 1);
166350397Sobrien  else
1664132718Skan    x = addr_side_effect_eval (x, xsize, 0);
166550397Sobrien  if (GET_CODE (y) == HIGH)
166650397Sobrien    y = XEXP (y, 0);
166750397Sobrien  else if (GET_CODE (y) == LO_SUM)
166850397Sobrien    y = XEXP (y, 1);
166950397Sobrien  else
1670132718Skan    y = addr_side_effect_eval (y, ysize, 0);
167150397Sobrien
167250397Sobrien  if (rtx_equal_for_memref_p (x, y))
167350397Sobrien    {
167450397Sobrien      if (xsize <= 0 || ysize <= 0)
167550397Sobrien	return 1;
167650397Sobrien      if (c >= 0 && xsize > c)
167750397Sobrien	return 1;
167850397Sobrien      if (c < 0 && ysize+c > 0)
167950397Sobrien	return 1;
168050397Sobrien      return 0;
168150397Sobrien    }
168250397Sobrien
168350397Sobrien  /* This code used to check for conflicts involving stack references and
168450397Sobrien     globals but the base address alias code now handles these cases.  */
168550397Sobrien
168650397Sobrien  if (GET_CODE (x) == PLUS)
168750397Sobrien    {
168850397Sobrien      /* The fact that X is canonicalized means that this
168950397Sobrien	 PLUS rtx is canonicalized.  */
169050397Sobrien      rtx x0 = XEXP (x, 0);
169150397Sobrien      rtx x1 = XEXP (x, 1);
169250397Sobrien
169350397Sobrien      if (GET_CODE (y) == PLUS)
169450397Sobrien	{
169550397Sobrien	  /* The fact that Y is canonicalized means that this
169650397Sobrien	     PLUS rtx is canonicalized.  */
169750397Sobrien	  rtx y0 = XEXP (y, 0);
169850397Sobrien	  rtx y1 = XEXP (y, 1);
169950397Sobrien
170050397Sobrien	  if (rtx_equal_for_memref_p (x1, y1))
170150397Sobrien	    return memrefs_conflict_p (xsize, x0, ysize, y0, c);
170250397Sobrien	  if (rtx_equal_for_memref_p (x0, y0))
170350397Sobrien	    return memrefs_conflict_p (xsize, x1, ysize, y1, c);
170450397Sobrien	  if (GET_CODE (x1) == CONST_INT)
170552284Sobrien	    {
170652284Sobrien	      if (GET_CODE (y1) == CONST_INT)
170752284Sobrien		return memrefs_conflict_p (xsize, x0, ysize, y0,
170852284Sobrien					   c - INTVAL (x1) + INTVAL (y1));
170952284Sobrien	      else
171052284Sobrien		return memrefs_conflict_p (xsize, x0, ysize, y,
171152284Sobrien					   c - INTVAL (x1));
171252284Sobrien	    }
171350397Sobrien	  else if (GET_CODE (y1) == CONST_INT)
171450397Sobrien	    return memrefs_conflict_p (xsize, x, ysize, y0, c + INTVAL (y1));
171550397Sobrien
171650397Sobrien	  return 1;
171750397Sobrien	}
171850397Sobrien      else if (GET_CODE (x1) == CONST_INT)
171950397Sobrien	return memrefs_conflict_p (xsize, x0, ysize, y, c - INTVAL (x1));
172050397Sobrien    }
172150397Sobrien  else if (GET_CODE (y) == PLUS)
172250397Sobrien    {
172350397Sobrien      /* The fact that Y is canonicalized means that this
172450397Sobrien	 PLUS rtx is canonicalized.  */
172550397Sobrien      rtx y0 = XEXP (y, 0);
172650397Sobrien      rtx y1 = XEXP (y, 1);
172750397Sobrien
172850397Sobrien      if (GET_CODE (y1) == CONST_INT)
172950397Sobrien	return memrefs_conflict_p (xsize, x, ysize, y0, c + INTVAL (y1));
173050397Sobrien      else
173150397Sobrien	return 1;
173250397Sobrien    }
173350397Sobrien
173450397Sobrien  if (GET_CODE (x) == GET_CODE (y))
173550397Sobrien    switch (GET_CODE (x))
173650397Sobrien      {
173750397Sobrien      case MULT:
173850397Sobrien	{
173950397Sobrien	  /* Handle cases where we expect the second operands to be the
174050397Sobrien	     same, and check only whether the first operand would conflict
174150397Sobrien	     or not.  */
174250397Sobrien	  rtx x0, y0;
174350397Sobrien	  rtx x1 = canon_rtx (XEXP (x, 1));
174450397Sobrien	  rtx y1 = canon_rtx (XEXP (y, 1));
174550397Sobrien	  if (! rtx_equal_for_memref_p (x1, y1))
174650397Sobrien	    return 1;
174750397Sobrien	  x0 = canon_rtx (XEXP (x, 0));
174850397Sobrien	  y0 = canon_rtx (XEXP (y, 0));
174950397Sobrien	  if (rtx_equal_for_memref_p (x0, y0))
175050397Sobrien	    return (xsize == 0 || ysize == 0
175150397Sobrien		    || (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0));
175250397Sobrien
175350397Sobrien	  /* Can't properly adjust our sizes.  */
175450397Sobrien	  if (GET_CODE (x1) != CONST_INT)
175550397Sobrien	    return 1;
175650397Sobrien	  xsize /= INTVAL (x1);
175750397Sobrien	  ysize /= INTVAL (x1);
175850397Sobrien	  c /= INTVAL (x1);
175950397Sobrien	  return memrefs_conflict_p (xsize, x0, ysize, y0, c);
176050397Sobrien	}
176150397Sobrien
176250397Sobrien      case REG:
176350397Sobrien	/* Are these registers known not to be equal?  */
176450397Sobrien	if (alias_invariant)
176550397Sobrien	  {
176652284Sobrien	    unsigned int r_x = REGNO (x), r_y = REGNO (y);
176750397Sobrien	    rtx i_x, i_y;	/* invariant relationships of X and Y */
176850397Sobrien
1769132718Skan	    i_x = r_x >= alias_invariant_size ? 0 : alias_invariant[r_x];
1770132718Skan	    i_y = r_y >= alias_invariant_size ? 0 : alias_invariant[r_y];
177150397Sobrien
177250397Sobrien	    if (i_x == 0 && i_y == 0)
177350397Sobrien	      break;
177450397Sobrien
177550397Sobrien	    if (! memrefs_conflict_p (xsize, i_x ? i_x : x,
177650397Sobrien				      ysize, i_y ? i_y : y, c))
177750397Sobrien	      return 0;
177850397Sobrien	  }
177950397Sobrien	break;
178050397Sobrien
178150397Sobrien      default:
178250397Sobrien	break;
178350397Sobrien      }
178450397Sobrien
178550397Sobrien  /* Treat an access through an AND (e.g. a subword access on an Alpha)
1786117395Skan     as an access with indeterminate size.  Assume that references
178752284Sobrien     besides AND are aligned, so if the size of the other reference is
178852284Sobrien     at least as large as the alignment, assume no other overlap.  */
178950397Sobrien  if (GET_CODE (x) == AND && GET_CODE (XEXP (x, 1)) == CONST_INT)
179052284Sobrien    {
179152284Sobrien      if (GET_CODE (y) == AND || ysize < -INTVAL (XEXP (x, 1)))
179252284Sobrien	xsize = -1;
1793132718Skan      return memrefs_conflict_p (xsize, canon_rtx (XEXP (x, 0)), ysize, y, c);
179452284Sobrien    }
179550397Sobrien  if (GET_CODE (y) == AND && GET_CODE (XEXP (y, 1)) == CONST_INT)
179650397Sobrien    {
179752284Sobrien      /* ??? If we are indexing far enough into the array/structure, we
1798117395Skan	 may yet be able to determine that we can not overlap.  But we
179950397Sobrien	 also need to that we are far enough from the end not to overlap
180052284Sobrien	 a following reference, so we do nothing with that for now.  */
180152284Sobrien      if (GET_CODE (x) == AND || xsize < -INTVAL (XEXP (y, 1)))
180252284Sobrien	ysize = -1;
1803132718Skan      return memrefs_conflict_p (xsize, x, ysize, canon_rtx (XEXP (y, 0)), c);
180450397Sobrien    }
180550397Sobrien
180690075Sobrien  if (GET_CODE (x) == ADDRESSOF)
180790075Sobrien    {
180890075Sobrien      if (y == frame_pointer_rtx
180990075Sobrien	  || GET_CODE (y) == ADDRESSOF)
181090075Sobrien	return xsize <= 0 || ysize <= 0;
181190075Sobrien    }
181290075Sobrien  if (GET_CODE (y) == ADDRESSOF)
181390075Sobrien    {
181490075Sobrien      if (x == frame_pointer_rtx)
181590075Sobrien	return xsize <= 0 || ysize <= 0;
181690075Sobrien    }
181790075Sobrien
181850397Sobrien  if (CONSTANT_P (x))
181950397Sobrien    {
182050397Sobrien      if (GET_CODE (x) == CONST_INT && GET_CODE (y) == CONST_INT)
182150397Sobrien	{
182250397Sobrien	  c += (INTVAL (y) - INTVAL (x));
182350397Sobrien	  return (xsize <= 0 || ysize <= 0
182450397Sobrien		  || (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0));
182550397Sobrien	}
182650397Sobrien
182750397Sobrien      if (GET_CODE (x) == CONST)
182850397Sobrien	{
182950397Sobrien	  if (GET_CODE (y) == CONST)
183050397Sobrien	    return memrefs_conflict_p (xsize, canon_rtx (XEXP (x, 0)),
183150397Sobrien				       ysize, canon_rtx (XEXP (y, 0)), c);
183250397Sobrien	  else
183350397Sobrien	    return memrefs_conflict_p (xsize, canon_rtx (XEXP (x, 0)),
183450397Sobrien				       ysize, y, c);
183550397Sobrien	}
183650397Sobrien      if (GET_CODE (y) == CONST)
183750397Sobrien	return memrefs_conflict_p (xsize, x, ysize,
183850397Sobrien				   canon_rtx (XEXP (y, 0)), c);
183950397Sobrien
184050397Sobrien      if (CONSTANT_P (y))
184190075Sobrien	return (xsize <= 0 || ysize <= 0
184250397Sobrien		|| (rtx_equal_for_memref_p (x, y)
184390075Sobrien		    && ((c >= 0 && xsize > c) || (c < 0 && ysize+c > 0))));
184450397Sobrien
184550397Sobrien      return 1;
184650397Sobrien    }
184750397Sobrien  return 1;
184850397Sobrien}
184950397Sobrien
185050397Sobrien/* Functions to compute memory dependencies.
185150397Sobrien
185250397Sobrien   Since we process the insns in execution order, we can build tables
185350397Sobrien   to keep track of what registers are fixed (and not aliased), what registers
185450397Sobrien   are varying in known ways, and what registers are varying in unknown
185550397Sobrien   ways.
185650397Sobrien
185750397Sobrien   If both memory references are volatile, then there must always be a
185850397Sobrien   dependence between the two references, since their order can not be
185950397Sobrien   changed.  A volatile and non-volatile reference can be interchanged
1860117395Skan   though.
186150397Sobrien
186290075Sobrien   A MEM_IN_STRUCT reference at a non-AND varying address can never
186390075Sobrien   conflict with a non-MEM_IN_STRUCT reference at a fixed address.  We
186490075Sobrien   also must allow AND addresses, because they may generate accesses
186590075Sobrien   outside the object being referenced.  This is used to generate
186690075Sobrien   aligned addresses from unaligned addresses, for instance, the alpha
186790075Sobrien   storeqi_unaligned pattern.  */
186850397Sobrien
186950397Sobrien/* Read dependence: X is read after read in MEM takes place.  There can
187050397Sobrien   only be a dependence here if both reads are volatile.  */
187150397Sobrien
187250397Sobrienint
1873132718Skanread_dependence (rtx mem, rtx x)
187450397Sobrien{
187550397Sobrien  return MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem);
187650397Sobrien}
187750397Sobrien
187852284Sobrien/* Returns MEM1 if and only if MEM1 is a scalar at a fixed address and
187952284Sobrien   MEM2 is a reference to a structure at a varying address, or returns
188052284Sobrien   MEM2 if vice versa.  Otherwise, returns NULL_RTX.  If a non-NULL
188152284Sobrien   value is returned MEM1 and MEM2 can never alias.  VARIES_P is used
188252284Sobrien   to decide whether or not an address may vary; it should return
188390075Sobrien   nonzero whenever variation is possible.
188490075Sobrien   MEM1_ADDR and MEM2_ADDR are the addresses of MEM1 and MEM2.  */
1885117395Skan
188690075Sobrienstatic rtx
1887132718Skanfixed_scalar_and_varying_struct_p (rtx mem1, rtx mem2, rtx mem1_addr,
1888132718Skan				   rtx mem2_addr,
1889132718Skan				   int (*varies_p) (rtx, int))
1890117395Skan{
189190075Sobrien  if (! flag_strict_aliasing)
189290075Sobrien    return NULL_RTX;
189352284Sobrien
1894117395Skan  if (MEM_SCALAR_P (mem1) && MEM_IN_STRUCT_P (mem2)
189590075Sobrien      && !varies_p (mem1_addr, 1) && varies_p (mem2_addr, 1))
189652284Sobrien    /* MEM1 is a scalar at a fixed address; MEM2 is a struct at a
189752284Sobrien       varying address.  */
189852284Sobrien    return mem1;
189952284Sobrien
1900117395Skan  if (MEM_IN_STRUCT_P (mem1) && MEM_SCALAR_P (mem2)
190190075Sobrien      && varies_p (mem1_addr, 1) && !varies_p (mem2_addr, 1))
190252284Sobrien    /* MEM2 is a scalar at a fixed address; MEM1 is a struct at a
190352284Sobrien       varying address.  */
190452284Sobrien    return mem2;
190552284Sobrien
190652284Sobrien  return NULL_RTX;
190752284Sobrien}
190852284Sobrien
190952284Sobrien/* Returns nonzero if something about the mode or address format MEM1
191052284Sobrien   indicates that it might well alias *anything*.  */
191152284Sobrien
191252284Sobrienstatic int
1913132718Skanaliases_everything_p (rtx mem)
191452284Sobrien{
191552284Sobrien  if (GET_CODE (XEXP (mem, 0)) == AND)
191652284Sobrien    /* If the address is an AND, its very hard to know at what it is
191752284Sobrien       actually pointing.  */
191852284Sobrien    return 1;
1919117395Skan
192052284Sobrien  return 0;
192152284Sobrien}
192252284Sobrien
192390075Sobrien/* Return true if we can determine that the fields referenced cannot
192490075Sobrien   overlap for any pair of objects.  */
192590075Sobrien
192690075Sobrienstatic bool
1927132718Skannonoverlapping_component_refs_p (tree x, tree y)
192890075Sobrien{
192990075Sobrien  tree fieldx, fieldy, typex, typey, orig_y;
193090075Sobrien
193190075Sobrien  do
193290075Sobrien    {
193390075Sobrien      /* The comparison has to be done at a common type, since we don't
193490075Sobrien	 know how the inheritance hierarchy works.  */
193590075Sobrien      orig_y = y;
193690075Sobrien      do
193790075Sobrien	{
193890075Sobrien	  fieldx = TREE_OPERAND (x, 1);
193990075Sobrien	  typex = DECL_FIELD_CONTEXT (fieldx);
194090075Sobrien
194190075Sobrien	  y = orig_y;
194290075Sobrien	  do
194390075Sobrien	    {
194490075Sobrien	      fieldy = TREE_OPERAND (y, 1);
194590075Sobrien	      typey = DECL_FIELD_CONTEXT (fieldy);
194690075Sobrien
194790075Sobrien	      if (typex == typey)
194890075Sobrien		goto found;
194990075Sobrien
195090075Sobrien	      y = TREE_OPERAND (y, 0);
195190075Sobrien	    }
195290075Sobrien	  while (y && TREE_CODE (y) == COMPONENT_REF);
195390075Sobrien
195490075Sobrien	  x = TREE_OPERAND (x, 0);
195590075Sobrien	}
195690075Sobrien      while (x && TREE_CODE (x) == COMPONENT_REF);
195790075Sobrien
195890075Sobrien      /* Never found a common type.  */
195990075Sobrien      return false;
196090075Sobrien
196190075Sobrien    found:
196290075Sobrien      /* If we're left with accessing different fields of a structure,
196390075Sobrien	 then no overlap.  */
196490075Sobrien      if (TREE_CODE (typex) == RECORD_TYPE
196590075Sobrien	  && fieldx != fieldy)
196690075Sobrien	return true;
196790075Sobrien
196890075Sobrien      /* The comparison on the current field failed.  If we're accessing
196990075Sobrien	 a very nested structure, look at the next outer level.  */
197090075Sobrien      x = TREE_OPERAND (x, 0);
197190075Sobrien      y = TREE_OPERAND (y, 0);
197290075Sobrien    }
197390075Sobrien  while (x && y
197490075Sobrien	 && TREE_CODE (x) == COMPONENT_REF
197590075Sobrien	 && TREE_CODE (y) == COMPONENT_REF);
1976117395Skan
197790075Sobrien  return false;
197890075Sobrien}
197990075Sobrien
198090075Sobrien/* Look at the bottom of the COMPONENT_REF list for a DECL, and return it.  */
198190075Sobrien
198290075Sobrienstatic tree
1983132718Skandecl_for_component_ref (tree x)
198490075Sobrien{
198590075Sobrien  do
198690075Sobrien    {
198790075Sobrien      x = TREE_OPERAND (x, 0);
198890075Sobrien    }
198990075Sobrien  while (x && TREE_CODE (x) == COMPONENT_REF);
199090075Sobrien
199190075Sobrien  return x && DECL_P (x) ? x : NULL_TREE;
199290075Sobrien}
199390075Sobrien
199490075Sobrien/* Walk up the COMPONENT_REF list and adjust OFFSET to compensate for the
199590075Sobrien   offset of the field reference.  */
199690075Sobrien
199790075Sobrienstatic rtx
1998132718Skanadjust_offset_for_component_ref (tree x, rtx offset)
199990075Sobrien{
200090075Sobrien  HOST_WIDE_INT ioffset;
200190075Sobrien
200290075Sobrien  if (! offset)
200390075Sobrien    return NULL_RTX;
200490075Sobrien
200590075Sobrien  ioffset = INTVAL (offset);
2006117395Skan  do
200790075Sobrien    {
200890075Sobrien      tree field = TREE_OPERAND (x, 1);
200990075Sobrien
201090075Sobrien      if (! host_integerp (DECL_FIELD_OFFSET (field), 1))
201190075Sobrien	return NULL_RTX;
201290075Sobrien      ioffset += (tree_low_cst (DECL_FIELD_OFFSET (field), 1)
201390075Sobrien		  + (tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
201490075Sobrien		     / BITS_PER_UNIT));
201590075Sobrien
201690075Sobrien      x = TREE_OPERAND (x, 0);
201790075Sobrien    }
201890075Sobrien  while (x && TREE_CODE (x) == COMPONENT_REF);
201990075Sobrien
202090075Sobrien  return GEN_INT (ioffset);
202190075Sobrien}
202290075Sobrien
2023132718Skan/* Return nonzero if we can determine the exprs corresponding to memrefs
202490075Sobrien   X and Y and they do not overlap.  */
202590075Sobrien
202690075Sobrienstatic int
2027132718Skannonoverlapping_memrefs_p (rtx x, rtx y)
202890075Sobrien{
202990075Sobrien  tree exprx = MEM_EXPR (x), expry = MEM_EXPR (y);
203090075Sobrien  rtx rtlx, rtly;
203190075Sobrien  rtx basex, basey;
203290075Sobrien  rtx moffsetx, moffsety;
203390075Sobrien  HOST_WIDE_INT offsetx = 0, offsety = 0, sizex, sizey, tem;
203490075Sobrien
203590075Sobrien  /* Unless both have exprs, we can't tell anything.  */
203690075Sobrien  if (exprx == 0 || expry == 0)
203790075Sobrien    return 0;
203890075Sobrien
203990075Sobrien  /* If both are field references, we may be able to determine something.  */
204090075Sobrien  if (TREE_CODE (exprx) == COMPONENT_REF
204190075Sobrien      && TREE_CODE (expry) == COMPONENT_REF
204290075Sobrien      && nonoverlapping_component_refs_p (exprx, expry))
204390075Sobrien    return 1;
204490075Sobrien
204590075Sobrien  /* If the field reference test failed, look at the DECLs involved.  */
204690075Sobrien  moffsetx = MEM_OFFSET (x);
204790075Sobrien  if (TREE_CODE (exprx) == COMPONENT_REF)
204890075Sobrien    {
204990075Sobrien      tree t = decl_for_component_ref (exprx);
205090075Sobrien      if (! t)
205190075Sobrien	return 0;
205290075Sobrien      moffsetx = adjust_offset_for_component_ref (exprx, moffsetx);
205390075Sobrien      exprx = t;
205490075Sobrien    }
2055110611Skan  else if (TREE_CODE (exprx) == INDIRECT_REF)
2056110611Skan    {
2057110611Skan      exprx = TREE_OPERAND (exprx, 0);
2058110611Skan      if (flag_argument_noalias < 2
2059110611Skan	  || TREE_CODE (exprx) != PARM_DECL)
2060110611Skan	return 0;
2061110611Skan    }
2062110611Skan
206390075Sobrien  moffsety = MEM_OFFSET (y);
206490075Sobrien  if (TREE_CODE (expry) == COMPONENT_REF)
206590075Sobrien    {
206690075Sobrien      tree t = decl_for_component_ref (expry);
206790075Sobrien      if (! t)
206890075Sobrien	return 0;
206990075Sobrien      moffsety = adjust_offset_for_component_ref (expry, moffsety);
207090075Sobrien      expry = t;
207190075Sobrien    }
2072110611Skan  else if (TREE_CODE (expry) == INDIRECT_REF)
2073110611Skan    {
2074110611Skan      expry = TREE_OPERAND (expry, 0);
2075110611Skan      if (flag_argument_noalias < 2
2076110611Skan	  || TREE_CODE (expry) != PARM_DECL)
2077110611Skan	return 0;
2078110611Skan    }
207990075Sobrien
208090075Sobrien  if (! DECL_P (exprx) || ! DECL_P (expry))
208190075Sobrien    return 0;
208290075Sobrien
208390075Sobrien  rtlx = DECL_RTL (exprx);
208490075Sobrien  rtly = DECL_RTL (expry);
208590075Sobrien
208690075Sobrien  /* If either RTL is not a MEM, it must be a REG or CONCAT, meaning they
208790075Sobrien     can't overlap unless they are the same because we never reuse that part
208890075Sobrien     of the stack frame used for locals for spilled pseudos.  */
208990075Sobrien  if ((GET_CODE (rtlx) != MEM || GET_CODE (rtly) != MEM)
209090075Sobrien      && ! rtx_equal_p (rtlx, rtly))
209190075Sobrien    return 1;
209290075Sobrien
209390075Sobrien  /* Get the base and offsets of both decls.  If either is a register, we
209490075Sobrien     know both are and are the same, so use that as the base.  The only
209590075Sobrien     we can avoid overlap is if we can deduce that they are nonoverlapping
209690075Sobrien     pieces of that decl, which is very rare.  */
209790075Sobrien  basex = GET_CODE (rtlx) == MEM ? XEXP (rtlx, 0) : rtlx;
209890075Sobrien  if (GET_CODE (basex) == PLUS && GET_CODE (XEXP (basex, 1)) == CONST_INT)
209990075Sobrien    offsetx = INTVAL (XEXP (basex, 1)), basex = XEXP (basex, 0);
210090075Sobrien
210190075Sobrien  basey = GET_CODE (rtly) == MEM ? XEXP (rtly, 0) : rtly;
210290075Sobrien  if (GET_CODE (basey) == PLUS && GET_CODE (XEXP (basey, 1)) == CONST_INT)
210390075Sobrien    offsety = INTVAL (XEXP (basey, 1)), basey = XEXP (basey, 0);
210490075Sobrien
210590075Sobrien  /* If the bases are different, we know they do not overlap if both
2106117395Skan     are constants or if one is a constant and the other a pointer into the
210790075Sobrien     stack frame.  Otherwise a different base means we can't tell if they
210890075Sobrien     overlap or not.  */
210990075Sobrien  if (! rtx_equal_p (basex, basey))
2110117395Skan    return ((CONSTANT_P (basex) && CONSTANT_P (basey))
2111117395Skan	    || (CONSTANT_P (basex) && REG_P (basey)
2112117395Skan		&& REGNO_PTR_FRAME_P (REGNO (basey)))
2113117395Skan	    || (CONSTANT_P (basey) && REG_P (basex)
2114117395Skan		&& REGNO_PTR_FRAME_P (REGNO (basex))));
211590075Sobrien
211690075Sobrien  sizex = (GET_CODE (rtlx) != MEM ? (int) GET_MODE_SIZE (GET_MODE (rtlx))
211790075Sobrien	   : MEM_SIZE (rtlx) ? INTVAL (MEM_SIZE (rtlx))
211890075Sobrien	   : -1);
211990075Sobrien  sizey = (GET_CODE (rtly) != MEM ? (int) GET_MODE_SIZE (GET_MODE (rtly))
212090075Sobrien	   : MEM_SIZE (rtly) ? INTVAL (MEM_SIZE (rtly)) :
212190075Sobrien	   -1);
212290075Sobrien
212390075Sobrien  /* If we have an offset for either memref, it can update the values computed
212490075Sobrien     above.  */
212590075Sobrien  if (moffsetx)
212690075Sobrien    offsetx += INTVAL (moffsetx), sizex -= INTVAL (moffsetx);
212790075Sobrien  if (moffsety)
212890075Sobrien    offsety += INTVAL (moffsety), sizey -= INTVAL (moffsety);
212990075Sobrien
213090075Sobrien  /* If a memref has both a size and an offset, we can use the smaller size.
213190075Sobrien     We can't do this if the offset isn't known because we must view this
213290075Sobrien     memref as being anywhere inside the DECL's MEM.  */
213390075Sobrien  if (MEM_SIZE (x) && moffsetx)
213490075Sobrien    sizex = INTVAL (MEM_SIZE (x));
213590075Sobrien  if (MEM_SIZE (y) && moffsety)
213690075Sobrien    sizey = INTVAL (MEM_SIZE (y));
213790075Sobrien
213890075Sobrien  /* Put the values of the memref with the lower offset in X's values.  */
213990075Sobrien  if (offsetx > offsety)
214090075Sobrien    {
214190075Sobrien      tem = offsetx, offsetx = offsety, offsety = tem;
214290075Sobrien      tem = sizex, sizex = sizey, sizey = tem;
214390075Sobrien    }
214490075Sobrien
214590075Sobrien  /* If we don't know the size of the lower-offset value, we can't tell
214690075Sobrien     if they conflict.  Otherwise, we do the test.  */
2147110611Skan  return sizex >= 0 && offsety >= offsetx + sizex;
214890075Sobrien}
214990075Sobrien
215050397Sobrien/* True dependence: X is read after store in MEM takes place.  */
215150397Sobrien
215250397Sobrienint
2153132718Skantrue_dependence (rtx mem, enum machine_mode mem_mode, rtx x,
2154132718Skan		 int (*varies) (rtx, int))
215550397Sobrien{
215690075Sobrien  rtx x_addr, mem_addr;
215790075Sobrien  rtx base;
215850397Sobrien
215950397Sobrien  if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem))
216050397Sobrien    return 1;
216150397Sobrien
216296263Sobrien  /* (mem:BLK (scratch)) is a special mechanism to conflict with everything.
216396263Sobrien     This is used in epilogue deallocation functions.  */
216496263Sobrien  if (GET_MODE (x) == BLKmode && GET_CODE (XEXP (x, 0)) == SCRATCH)
216596263Sobrien    return 1;
216696263Sobrien  if (GET_MODE (mem) == BLKmode && GET_CODE (XEXP (mem, 0)) == SCRATCH)
216796263Sobrien    return 1;
216896263Sobrien
216950397Sobrien  if (DIFFERENT_ALIAS_SETS_P (x, mem))
217050397Sobrien    return 0;
217150397Sobrien
217290075Sobrien  /* Unchanging memory can't conflict with non-unchanging memory.
217390075Sobrien     A non-unchanging read can conflict with a non-unchanging write.
217490075Sobrien     An unchanging read can conflict with an unchanging write since
217590075Sobrien     there may be a single store to this address to initialize it.
217690075Sobrien     Note that an unchanging store can conflict with a non-unchanging read
217790075Sobrien     since we have to make conservative assumptions when we have a
217890075Sobrien     record with readonly fields and we are copying the whole thing.
217990075Sobrien     Just fall through to the code below to resolve potential conflicts.
218090075Sobrien     This won't handle all cases optimally, but the possible performance
218190075Sobrien     loss should be negligible.  */
218290075Sobrien  if (RTX_UNCHANGING_P (x) && ! RTX_UNCHANGING_P (mem))
218390075Sobrien    return 0;
218490075Sobrien
218590075Sobrien  if (nonoverlapping_memrefs_p (mem, x))
218690075Sobrien    return 0;
218790075Sobrien
218890075Sobrien  if (mem_mode == VOIDmode)
218990075Sobrien    mem_mode = GET_MODE (mem);
219090075Sobrien
219190075Sobrien  x_addr = get_addr (XEXP (x, 0));
219290075Sobrien  mem_addr = get_addr (XEXP (mem, 0));
219390075Sobrien
219490075Sobrien  base = find_base_term (x_addr);
219590075Sobrien  if (base && (GET_CODE (base) == LABEL_REF
219690075Sobrien	       || (GET_CODE (base) == SYMBOL_REF
219790075Sobrien		   && CONSTANT_POOL_ADDRESS_P (base))))
219890075Sobrien    return 0;
219990075Sobrien
220090075Sobrien  if (! base_alias_check (x_addr, mem_addr, GET_MODE (x), mem_mode))
220190075Sobrien    return 0;
220290075Sobrien
220390075Sobrien  x_addr = canon_rtx (x_addr);
220490075Sobrien  mem_addr = canon_rtx (mem_addr);
220590075Sobrien
220690075Sobrien  if (! memrefs_conflict_p (GET_MODE_SIZE (mem_mode), mem_addr,
220790075Sobrien			    SIZE_FOR_MODE (x), x_addr, 0))
220890075Sobrien    return 0;
220990075Sobrien
221090075Sobrien  if (aliases_everything_p (x))
221190075Sobrien    return 1;
221290075Sobrien
221390075Sobrien  /* We cannot use aliases_everything_p to test MEM, since we must look
221490075Sobrien     at MEM_MODE, rather than GET_MODE (MEM).  */
221590075Sobrien  if (mem_mode == QImode || GET_CODE (mem_addr) == AND)
221690075Sobrien    return 1;
221790075Sobrien
221890075Sobrien  /* In true_dependence we also allow BLKmode to alias anything.  Why
221990075Sobrien     don't we do this in anti_dependence and output_dependence?  */
222090075Sobrien  if (mem_mode == BLKmode || GET_MODE (x) == BLKmode)
222190075Sobrien    return 1;
222290075Sobrien
222390075Sobrien  return ! fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr,
222490075Sobrien					      varies);
222590075Sobrien}
222690075Sobrien
222790075Sobrien/* Canonical true dependence: X is read after store in MEM takes place.
2228117395Skan   Variant of true_dependence which assumes MEM has already been
2229117395Skan   canonicalized (hence we no longer do that here).
2230117395Skan   The mem_addr argument has been added, since true_dependence computed
223190075Sobrien   this value prior to canonicalizing.  */
223290075Sobrien
223390075Sobrienint
2234132718Skancanon_true_dependence (rtx mem, enum machine_mode mem_mode, rtx mem_addr,
2235132718Skan		       rtx x, int (*varies) (rtx, int))
223690075Sobrien{
223790075Sobrien  rtx x_addr;
223890075Sobrien
223990075Sobrien  if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem))
224090075Sobrien    return 1;
224190075Sobrien
224296263Sobrien  /* (mem:BLK (scratch)) is a special mechanism to conflict with everything.
224396263Sobrien     This is used in epilogue deallocation functions.  */
224496263Sobrien  if (GET_MODE (x) == BLKmode && GET_CODE (XEXP (x, 0)) == SCRATCH)
224596263Sobrien    return 1;
224696263Sobrien  if (GET_MODE (mem) == BLKmode && GET_CODE (XEXP (mem, 0)) == SCRATCH)
224796263Sobrien    return 1;
224896263Sobrien
224990075Sobrien  if (DIFFERENT_ALIAS_SETS_P (x, mem))
225090075Sobrien    return 0;
225190075Sobrien
225250397Sobrien  /* If X is an unchanging read, then it can't possibly conflict with any
225350397Sobrien     non-unchanging store.  It may conflict with an unchanging write though,
225450397Sobrien     because there may be a single store to this address to initialize it.
225550397Sobrien     Just fall through to the code below to resolve the case where we have
225650397Sobrien     both an unchanging read and an unchanging write.  This won't handle all
225750397Sobrien     cases optimally, but the possible performance loss should be
225850397Sobrien     negligible.  */
225950397Sobrien  if (RTX_UNCHANGING_P (x) && ! RTX_UNCHANGING_P (mem))
226050397Sobrien    return 0;
226150397Sobrien
226290075Sobrien  if (nonoverlapping_memrefs_p (x, mem))
226390075Sobrien    return 0;
226452284Sobrien
226590075Sobrien  x_addr = get_addr (XEXP (x, 0));
226690075Sobrien
226790075Sobrien  if (! base_alias_check (x_addr, mem_addr, GET_MODE (x), mem_mode))
226850397Sobrien    return 0;
226950397Sobrien
227090075Sobrien  x_addr = canon_rtx (x_addr);
227150397Sobrien  if (! memrefs_conflict_p (GET_MODE_SIZE (mem_mode), mem_addr,
227250397Sobrien			    SIZE_FOR_MODE (x), x_addr, 0))
227350397Sobrien    return 0;
227450397Sobrien
227552284Sobrien  if (aliases_everything_p (x))
227652284Sobrien    return 1;
227750397Sobrien
227890075Sobrien  /* We cannot use aliases_everything_p to test MEM, since we must look
227952284Sobrien     at MEM_MODE, rather than GET_MODE (MEM).  */
228052284Sobrien  if (mem_mode == QImode || GET_CODE (mem_addr) == AND)
228152284Sobrien    return 1;
228250397Sobrien
228352284Sobrien  /* In true_dependence we also allow BLKmode to alias anything.  Why
228452284Sobrien     don't we do this in anti_dependence and output_dependence?  */
228552284Sobrien  if (mem_mode == BLKmode || GET_MODE (x) == BLKmode)
228650397Sobrien    return 1;
228750397Sobrien
228890075Sobrien  return ! fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr,
228990075Sobrien					      varies);
229050397Sobrien}
229150397Sobrien
2292117395Skan/* Returns nonzero if a write to X might alias a previous read from
2293132718Skan   (or, if WRITEP is nonzero, a write to) MEM.  If CONSTP is nonzero,
2294132718Skan   honor the RTX_UNCHANGING_P flags on X and MEM.  */
229550397Sobrien
229652284Sobrienstatic int
2297132718Skanwrite_dependence_p (rtx mem, rtx x, int writep, int constp)
229850397Sobrien{
229950397Sobrien  rtx x_addr, mem_addr;
230052284Sobrien  rtx fixed_scalar;
230190075Sobrien  rtx base;
230250397Sobrien
230350397Sobrien  if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem))
230450397Sobrien    return 1;
230550397Sobrien
230696263Sobrien  /* (mem:BLK (scratch)) is a special mechanism to conflict with everything.
230796263Sobrien     This is used in epilogue deallocation functions.  */
230896263Sobrien  if (GET_MODE (x) == BLKmode && GET_CODE (XEXP (x, 0)) == SCRATCH)
230996263Sobrien    return 1;
231096263Sobrien  if (GET_MODE (mem) == BLKmode && GET_CODE (XEXP (mem, 0)) == SCRATCH)
231196263Sobrien    return 1;
231296263Sobrien
231390075Sobrien  if (DIFFERENT_ALIAS_SETS_P (x, mem))
231490075Sobrien    return 0;
231590075Sobrien
2316132718Skan  if (constp)
2317132718Skan    {
2318132718Skan      /* Unchanging memory can't conflict with non-unchanging memory.  */
2319132718Skan      if (RTX_UNCHANGING_P (x) != RTX_UNCHANGING_P (mem))
2320132718Skan	return 0;
232190075Sobrien
2322132718Skan      /* If MEM is an unchanging read, then it can't possibly conflict with
2323132718Skan	 the store to X, because there is at most one store to MEM, and it
2324132718Skan	 must have occurred somewhere before MEM.  */
2325132718Skan      if (! writep && RTX_UNCHANGING_P (mem))
2326132718Skan	return 0;
2327132718Skan    }
232850397Sobrien
232990075Sobrien  if (nonoverlapping_memrefs_p (x, mem))
233050397Sobrien    return 0;
233150397Sobrien
233290075Sobrien  x_addr = get_addr (XEXP (x, 0));
233390075Sobrien  mem_addr = get_addr (XEXP (mem, 0));
233450397Sobrien
233590075Sobrien  if (! writep)
233690075Sobrien    {
233790075Sobrien      base = find_base_term (mem_addr);
233890075Sobrien      if (base && (GET_CODE (base) == LABEL_REF
233990075Sobrien		   || (GET_CODE (base) == SYMBOL_REF
234090075Sobrien		       && CONSTANT_POOL_ADDRESS_P (base))))
234190075Sobrien	return 0;
234290075Sobrien    }
234390075Sobrien
234490075Sobrien  if (! base_alias_check (x_addr, mem_addr, GET_MODE (x),
234590075Sobrien			  GET_MODE (mem)))
234650397Sobrien    return 0;
234750397Sobrien
234890075Sobrien  x_addr = canon_rtx (x_addr);
234990075Sobrien  mem_addr = canon_rtx (mem_addr);
235050397Sobrien
235152284Sobrien  if (!memrefs_conflict_p (SIZE_FOR_MODE (mem), mem_addr,
235252284Sobrien			   SIZE_FOR_MODE (x), x_addr, 0))
235352284Sobrien    return 0;
235452284Sobrien
2355117395Skan  fixed_scalar
235690075Sobrien    = fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr,
235790075Sobrien					 rtx_addr_varies_p);
235890075Sobrien
235952284Sobrien  return (!(fixed_scalar == mem && !aliases_everything_p (x))
236052284Sobrien	  && !(fixed_scalar == x && !aliases_everything_p (mem)));
236150397Sobrien}
236250397Sobrien
236352284Sobrien/* Anti dependence: X is written after read in MEM takes place.  */
236452284Sobrien
236552284Sobrienint
2366132718Skananti_dependence (rtx mem, rtx x)
236752284Sobrien{
2368132718Skan  return write_dependence_p (mem, x, /*writep=*/0, /*constp*/1);
236952284Sobrien}
237052284Sobrien
237150397Sobrien/* Output dependence: X is written after store in MEM takes place.  */
237250397Sobrien
237350397Sobrienint
2374132718Skanoutput_dependence (rtx mem, rtx x)
237550397Sobrien{
2376132718Skan  return write_dependence_p (mem, x, /*writep=*/1, /*constp*/1);
237750397Sobrien}
2378132718Skan
2379132718Skan/* Unchanging anti dependence: Like anti_dependence but ignores
2380132718Skan   the UNCHANGING_RTX_P property on const variable references.  */
2381132718Skan
2382132718Skanint
2383132718Skanunchanging_anti_dependence (rtx mem, rtx x)
2384132718Skan{
2385132718Skan  return write_dependence_p (mem, x, /*writep=*/0, /*constp*/0);
2386132718Skan}
2387117395Skan
2388117395Skan/* A subroutine of nonlocal_mentioned_p, returns 1 if *LOC mentions
2389117395Skan   something which is not local to the function and is not constant.  */
239050397Sobrien
239190075Sobrienstatic int
2392132718Skannonlocal_mentioned_p_1 (rtx *loc, void *data ATTRIBUTE_UNUSED)
239390075Sobrien{
2394117395Skan  rtx x = *loc;
239590075Sobrien  rtx base;
239690075Sobrien  int regno;
239790075Sobrien
2398117395Skan  if (! x)
2399117395Skan    return 0;
240090075Sobrien
2401117395Skan  switch (GET_CODE (x))
240290075Sobrien    {
240390075Sobrien    case SUBREG:
240490075Sobrien      if (GET_CODE (SUBREG_REG (x)) == REG)
240590075Sobrien	{
240690075Sobrien	  /* Global registers are not local.  */
240790075Sobrien	  if (REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER
240890075Sobrien	      && global_regs[subreg_regno (x)])
240990075Sobrien	    return 1;
241090075Sobrien	  return 0;
241190075Sobrien	}
241290075Sobrien      break;
241390075Sobrien
241490075Sobrien    case REG:
241590075Sobrien      regno = REGNO (x);
241690075Sobrien      /* Global registers are not local.  */
241790075Sobrien      if (regno < FIRST_PSEUDO_REGISTER && global_regs[regno])
241890075Sobrien	return 1;
241990075Sobrien      return 0;
242090075Sobrien
242190075Sobrien    case SCRATCH:
242290075Sobrien    case PC:
242390075Sobrien    case CC0:
242490075Sobrien    case CONST_INT:
242590075Sobrien    case CONST_DOUBLE:
242696263Sobrien    case CONST_VECTOR:
242790075Sobrien    case CONST:
242890075Sobrien    case LABEL_REF:
242990075Sobrien      return 0;
243090075Sobrien
243190075Sobrien    case SYMBOL_REF:
243290075Sobrien      /* Constants in the function's constants pool are constant.  */
243390075Sobrien      if (CONSTANT_POOL_ADDRESS_P (x))
243490075Sobrien	return 0;
243590075Sobrien      return 1;
243690075Sobrien
243790075Sobrien    case CALL:
243890075Sobrien      /* Non-constant calls and recursion are not local.  */
243990075Sobrien      return 1;
244090075Sobrien
244190075Sobrien    case MEM:
244290075Sobrien      /* Be overly conservative and consider any volatile memory
244390075Sobrien	 reference as not local.  */
244490075Sobrien      if (MEM_VOLATILE_P (x))
244590075Sobrien	return 1;
244690075Sobrien      base = find_base_term (XEXP (x, 0));
244790075Sobrien      if (base)
244890075Sobrien	{
244990075Sobrien	  /* A Pmode ADDRESS could be a reference via the structure value
245090075Sobrien	     address or static chain.  Such memory references are nonlocal.
245190075Sobrien
245290075Sobrien	     Thus, we have to examine the contents of the ADDRESS to find
245390075Sobrien	     out if this is a local reference or not.  */
245490075Sobrien	  if (GET_CODE (base) == ADDRESS
245590075Sobrien	      && GET_MODE (base) == Pmode
245690075Sobrien	      && (XEXP (base, 0) == stack_pointer_rtx
245790075Sobrien		  || XEXP (base, 0) == arg_pointer_rtx
245890075Sobrien#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
245990075Sobrien		  || XEXP (base, 0) == hard_frame_pointer_rtx
246090075Sobrien#endif
246190075Sobrien		  || XEXP (base, 0) == frame_pointer_rtx))
246290075Sobrien	    return 0;
246390075Sobrien	  /* Constants in the function's constant pool are constant.  */
246490075Sobrien	  if (GET_CODE (base) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (base))
246590075Sobrien	    return 0;
246690075Sobrien	}
246790075Sobrien      return 1;
246890075Sobrien
246990075Sobrien    case UNSPEC_VOLATILE:
247090075Sobrien    case ASM_INPUT:
247190075Sobrien      return 1;
247290075Sobrien
247390075Sobrien    case ASM_OPERANDS:
247490075Sobrien      if (MEM_VOLATILE_P (x))
247590075Sobrien	return 1;
247690075Sobrien
2477132718Skan    /* Fall through.  */
247890075Sobrien
247990075Sobrien    default:
248090075Sobrien      break;
248190075Sobrien    }
248290075Sobrien
2483117395Skan  return 0;
2484117395Skan}
248590075Sobrien
2486117395Skan/* Returns nonzero if X might mention something which is not
2487117395Skan   local to the function and is not constant.  */
248890075Sobrien
2489117395Skanstatic int
2490132718Skannonlocal_mentioned_p (rtx x)
2491117395Skan{
2492117395Skan  if (INSN_P (x))
2493117395Skan    {
2494117395Skan      if (GET_CODE (x) == CALL_INSN)
2495117395Skan	{
2496117395Skan	  if (! CONST_OR_PURE_CALL_P (x))
2497117395Skan	    return 1;
2498117395Skan	  x = CALL_INSN_FUNCTION_USAGE (x);
2499117395Skan	  if (x == 0)
2500117395Skan	    return 0;
2501117395Skan	}
2502117395Skan      else
2503117395Skan	x = PATTERN (x);
2504117395Skan    }
2505117395Skan
2506117395Skan  return for_each_rtx (&x, nonlocal_mentioned_p_1, NULL);
2507117395Skan}
2508117395Skan
2509117395Skan/* A subroutine of nonlocal_referenced_p, returns 1 if *LOC references
2510117395Skan   something which is not local to the function and is not constant.  */
2511117395Skan
2512117395Skanstatic int
2513132718Skannonlocal_referenced_p_1 (rtx *loc, void *data ATTRIBUTE_UNUSED)
2514117395Skan{
2515117395Skan  rtx x = *loc;
2516117395Skan
2517117395Skan  if (! x)
2518117395Skan    return 0;
2519117395Skan
2520117395Skan  switch (GET_CODE (x))
2521117395Skan    {
2522117395Skan    case MEM:
2523117395Skan    case REG:
2524117395Skan    case SYMBOL_REF:
2525117395Skan    case SUBREG:
2526117395Skan      return nonlocal_mentioned_p (x);
2527117395Skan
2528117395Skan    case CALL:
2529117395Skan      /* Non-constant calls and recursion are not local.  */
2530117395Skan      return 1;
2531117395Skan
2532117395Skan    case SET:
2533117395Skan      if (nonlocal_mentioned_p (SET_SRC (x)))
2534117395Skan	return 1;
2535117395Skan
2536117395Skan      if (GET_CODE (SET_DEST (x)) == MEM)
2537117395Skan	return nonlocal_mentioned_p (XEXP (SET_DEST (x), 0));
2538117395Skan
2539117395Skan      /* If the destination is anything other than a CC0, PC,
2540117395Skan	 MEM, REG, or a SUBREG of a REG that occupies all of
2541117395Skan	 the REG, then X references nonlocal memory if it is
2542117395Skan	 mentioned in the destination.  */
2543117395Skan      if (GET_CODE (SET_DEST (x)) != CC0
2544117395Skan	  && GET_CODE (SET_DEST (x)) != PC
2545117395Skan	  && GET_CODE (SET_DEST (x)) != REG
2546117395Skan	  && ! (GET_CODE (SET_DEST (x)) == SUBREG
2547117395Skan		&& GET_CODE (SUBREG_REG (SET_DEST (x))) == REG
2548117395Skan		&& (((GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_DEST (x))))
2549117395Skan		      + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
2550117395Skan		    == ((GET_MODE_SIZE (GET_MODE (SET_DEST (x)))
2551117395Skan			 + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD))))
2552117395Skan	return nonlocal_mentioned_p (SET_DEST (x));
2553117395Skan      return 0;
2554117395Skan
2555117395Skan    case CLOBBER:
2556117395Skan      if (GET_CODE (XEXP (x, 0)) == MEM)
2557117395Skan	return nonlocal_mentioned_p (XEXP (XEXP (x, 0), 0));
2558117395Skan      return 0;
2559117395Skan
2560117395Skan    case USE:
2561117395Skan      return nonlocal_mentioned_p (XEXP (x, 0));
2562117395Skan
2563117395Skan    case ASM_INPUT:
2564117395Skan    case UNSPEC_VOLATILE:
2565117395Skan      return 1;
2566117395Skan
2567117395Skan    case ASM_OPERANDS:
2568117395Skan      if (MEM_VOLATILE_P (x))
2569117395Skan	return 1;
2570117395Skan
2571132718Skan    /* Fall through.  */
2572117395Skan
2573117395Skan    default:
2574117395Skan      break;
2575117395Skan    }
2576117395Skan
257790075Sobrien  return 0;
257890075Sobrien}
257990075Sobrien
2580117395Skan/* Returns nonzero if X might reference something which is not
2581117395Skan   local to the function and is not constant.  */
2582117395Skan
2583117395Skanstatic int
2584132718Skannonlocal_referenced_p (rtx x)
2585117395Skan{
2586117395Skan  if (INSN_P (x))
2587117395Skan    {
2588117395Skan      if (GET_CODE (x) == CALL_INSN)
2589117395Skan	{
2590117395Skan	  if (! CONST_OR_PURE_CALL_P (x))
2591117395Skan	    return 1;
2592117395Skan	  x = CALL_INSN_FUNCTION_USAGE (x);
2593117395Skan	  if (x == 0)
2594117395Skan	    return 0;
2595117395Skan	}
2596117395Skan      else
2597117395Skan	x = PATTERN (x);
2598117395Skan    }
2599117395Skan
2600117395Skan  return for_each_rtx (&x, nonlocal_referenced_p_1, NULL);
2601117395Skan}
2602117395Skan
2603117395Skan/* A subroutine of nonlocal_set_p, returns 1 if *LOC sets
2604117395Skan   something which is not local to the function and is not constant.  */
2605117395Skan
2606117395Skanstatic int
2607132718Skannonlocal_set_p_1 (rtx *loc, void *data ATTRIBUTE_UNUSED)
2608117395Skan{
2609117395Skan  rtx x = *loc;
2610117395Skan
2611117395Skan  if (! x)
2612117395Skan    return 0;
2613117395Skan
2614117395Skan  switch (GET_CODE (x))
2615117395Skan    {
2616117395Skan    case CALL:
2617117395Skan      /* Non-constant calls and recursion are not local.  */
2618117395Skan      return 1;
2619117395Skan
2620117395Skan    case PRE_INC:
2621117395Skan    case PRE_DEC:
2622117395Skan    case POST_INC:
2623117395Skan    case POST_DEC:
2624117395Skan    case PRE_MODIFY:
2625117395Skan    case POST_MODIFY:
2626117395Skan      return nonlocal_mentioned_p (XEXP (x, 0));
2627117395Skan
2628117395Skan    case SET:
2629117395Skan      if (nonlocal_mentioned_p (SET_DEST (x)))
2630117395Skan	return 1;
2631117395Skan      return nonlocal_set_p (SET_SRC (x));
2632117395Skan
2633117395Skan    case CLOBBER:
2634117395Skan      return nonlocal_mentioned_p (XEXP (x, 0));
2635117395Skan
2636117395Skan    case USE:
2637117395Skan      return 0;
2638117395Skan
2639117395Skan    case ASM_INPUT:
2640117395Skan    case UNSPEC_VOLATILE:
2641117395Skan      return 1;
2642117395Skan
2643117395Skan    case ASM_OPERANDS:
2644117395Skan      if (MEM_VOLATILE_P (x))
2645117395Skan	return 1;
2646117395Skan
2647132718Skan    /* Fall through.  */
2648117395Skan
2649117395Skan    default:
2650117395Skan      break;
2651117395Skan    }
2652117395Skan
2653117395Skan  return 0;
2654117395Skan}
2655117395Skan
2656117395Skan/* Returns nonzero if X might set something which is not
2657117395Skan   local to the function and is not constant.  */
2658117395Skan
2659117395Skanstatic int
2660132718Skannonlocal_set_p (rtx x)
2661117395Skan{
2662117395Skan  if (INSN_P (x))
2663117395Skan    {
2664117395Skan      if (GET_CODE (x) == CALL_INSN)
2665117395Skan	{
2666117395Skan	  if (! CONST_OR_PURE_CALL_P (x))
2667117395Skan	    return 1;
2668117395Skan	  x = CALL_INSN_FUNCTION_USAGE (x);
2669117395Skan	  if (x == 0)
2670117395Skan	    return 0;
2671117395Skan	}
2672117395Skan      else
2673117395Skan	x = PATTERN (x);
2674117395Skan    }
2675117395Skan
2676117395Skan  return for_each_rtx (&x, nonlocal_set_p_1, NULL);
2677117395Skan}
2678117395Skan
2679132718Skan/* Mark the function if it is pure or constant.  */
268090075Sobrien
268190075Sobrienvoid
2682132718Skanmark_constant_function (void)
268390075Sobrien{
268490075Sobrien  rtx insn;
2685117395Skan  int nonlocal_memory_referenced;
268690075Sobrien
2687117395Skan  if (TREE_READONLY (current_function_decl)
268890075Sobrien      || DECL_IS_PURE (current_function_decl)
268990075Sobrien      || TREE_THIS_VOLATILE (current_function_decl)
2690117395Skan      || current_function_has_nonlocal_goto
2691117395Skan      || !(*targetm.binds_local_p) (current_function_decl))
269290075Sobrien    return;
269390075Sobrien
269490075Sobrien  /* A loop might not return which counts as a side effect.  */
269590075Sobrien  if (mark_dfs_back_edges ())
269690075Sobrien    return;
269790075Sobrien
2698117395Skan  nonlocal_memory_referenced = 0;
269990075Sobrien
270090075Sobrien  init_alias_analysis ();
270190075Sobrien
2702117395Skan  /* Determine if this is a constant or pure function.  */
270390075Sobrien
270490075Sobrien  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
2705117395Skan    {
2706117395Skan      if (! INSN_P (insn))
2707117395Skan	continue;
2708117395Skan
2709117395Skan      if (nonlocal_set_p (insn) || global_reg_mentioned_p (insn)
2710117395Skan	  || volatile_refs_p (PATTERN (insn)))
271190075Sobrien	break;
271290075Sobrien
2713117395Skan      if (! nonlocal_memory_referenced)
2714117395Skan	nonlocal_memory_referenced = nonlocal_referenced_p (insn);
2715117395Skan    }
2716117395Skan
271790075Sobrien  end_alias_analysis ();
271890075Sobrien
271990075Sobrien  /* Mark the function.  */
272090075Sobrien
2721117395Skan  if (insn)
2722117395Skan    ;
2723117395Skan  else if (nonlocal_memory_referenced)
2724132718Skan    {
2725132718Skan      cgraph_rtl_info (current_function_decl)->pure_function = 1;
2726132718Skan      DECL_IS_PURE (current_function_decl) = 1;
2727132718Skan    }
2728117395Skan  else
2729132718Skan    {
2730132718Skan      cgraph_rtl_info (current_function_decl)->const_function = 1;
2731132718Skan      TREE_READONLY (current_function_decl) = 1;
2732132718Skan    }
273390075Sobrien}
2734117395Skan
273590075Sobrien
273650397Sobrienvoid
2737132718Skaninit_alias_once (void)
273850397Sobrien{
273990075Sobrien  int i;
274050397Sobrien
274150397Sobrien#ifndef OUTGOING_REGNO
274250397Sobrien#define OUTGOING_REGNO(N) N
274350397Sobrien#endif
274450397Sobrien  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
274550397Sobrien    /* Check whether this register can hold an incoming pointer
274650397Sobrien       argument.  FUNCTION_ARG_REGNO_P tests outgoing register
274790075Sobrien       numbers, so translate if necessary due to register windows.  */
274850397Sobrien    if (FUNCTION_ARG_REGNO_P (OUTGOING_REGNO (i))
274950397Sobrien	&& HARD_REGNO_MODE_OK (i, Pmode))
2750117395Skan      static_reg_base_value[i]
2751117395Skan	= gen_rtx_ADDRESS (VOIDmode, gen_rtx_REG (Pmode, i));
275252284Sobrien
2753117395Skan  static_reg_base_value[STACK_POINTER_REGNUM]
2754117395Skan    = gen_rtx_ADDRESS (Pmode, stack_pointer_rtx);
2755117395Skan  static_reg_base_value[ARG_POINTER_REGNUM]
2756117395Skan    = gen_rtx_ADDRESS (Pmode, arg_pointer_rtx);
2757117395Skan  static_reg_base_value[FRAME_POINTER_REGNUM]
2758117395Skan    = gen_rtx_ADDRESS (Pmode, frame_pointer_rtx);
2759117395Skan#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
2760117395Skan  static_reg_base_value[HARD_FRAME_POINTER_REGNUM]
2761117395Skan    = gen_rtx_ADDRESS (Pmode, hard_frame_pointer_rtx);
2762117395Skan#endif
2763132718Skan}
2764117395Skan
2765132718Skan/* Set MEMORY_MODIFIED when X modifies DATA (that is assumed
2766132718Skan   to be memory reference.  */
2767132718Skanstatic bool memory_modified;
2768132718Skanstatic void
2769132718Skanmemory_modified_1 (rtx x, rtx pat ATTRIBUTE_UNUSED, void *data)
2770132718Skan{
2771132718Skan  if (GET_CODE (x) == MEM)
2772132718Skan    {
2773132718Skan      if (anti_dependence (x, (rtx)data) || output_dependence (x, (rtx)data))
2774132718Skan	memory_modified = true;
2775132718Skan    }
277650397Sobrien}
277750397Sobrien
2778132718Skan
2779132718Skan/* Return true when INSN possibly modify memory contents of MEM
2780132718Skan   (ie address can be modified).  */
2781132718Skanbool
2782132718Skanmemory_modified_in_insn_p (rtx mem, rtx insn)
2783132718Skan{
2784132718Skan  if (!INSN_P (insn))
2785132718Skan    return false;
2786132718Skan  memory_modified = false;
2787132718Skan  note_stores (PATTERN (insn), memory_modified_1, mem);
2788132718Skan  return memory_modified;
2789132718Skan}
2790132718Skan
279190075Sobrien/* Initialize the aliasing machinery.  Initialize the REG_KNOWN_VALUE
279290075Sobrien   array.  */
279390075Sobrien
279450397Sobrienvoid
2795132718Skaninit_alias_analysis (void)
279650397Sobrien{
2797132718Skan  unsigned int maxreg = max_reg_num ();
279850397Sobrien  int changed, pass;
279990075Sobrien  int i;
280090075Sobrien  unsigned int ui;
280190075Sobrien  rtx insn;
280250397Sobrien
2803132718Skan  timevar_push (TV_ALIAS_ANALYSIS);
280450397Sobrien
2805132718Skan  reg_known_value_size = maxreg - FIRST_PSEUDO_REGISTER;
2806132718Skan  reg_known_value = ggc_calloc (reg_known_value_size, sizeof (rtx));
2807132718Skan  reg_known_equiv_p = xcalloc (reg_known_value_size, sizeof (bool));
280850397Sobrien
280950397Sobrien  /* Overallocate reg_base_value to allow some growth during loop
281050397Sobrien     optimization.  Loop unrolling can create a large number of
281150397Sobrien     registers.  */
2812132718Skan  if (old_reg_base_value)
2813132718Skan    {
2814132718Skan      reg_base_value = old_reg_base_value;
2815132718Skan      /* If varray gets large zeroing cost may get important.  */
2816132718Skan      if (VARRAY_SIZE (reg_base_value) > 256
2817132718Skan          && VARRAY_SIZE (reg_base_value) > 4 * maxreg)
2818132718Skan	VARRAY_GROW (reg_base_value, maxreg);
2819132718Skan      VARRAY_CLEAR (reg_base_value);
2820132718Skan      if (VARRAY_SIZE (reg_base_value) < maxreg)
2821132718Skan	VARRAY_GROW (reg_base_value, maxreg);
2822132718Skan    }
2823132718Skan  else
2824132718Skan    {
2825132718Skan      VARRAY_RTX_INIT (reg_base_value, maxreg, "reg_base_value");
2826132718Skan    }
282790075Sobrien
2828132718Skan  new_reg_base_value = xmalloc (maxreg * sizeof (rtx));
2829132718Skan  reg_seen = xmalloc (maxreg);
2830132718Skan  if (! reload_completed && flag_old_unroll_loops)
283150397Sobrien    {
2832132718Skan      alias_invariant = ggc_calloc (maxreg, sizeof (rtx));
2833132718Skan      alias_invariant_size = maxreg;
283450397Sobrien    }
283550397Sobrien
283650397Sobrien  /* The basic idea is that each pass through this loop will use the
283750397Sobrien     "constant" information from the previous pass to propagate alias
283850397Sobrien     information through another level of assignments.
283950397Sobrien
284050397Sobrien     This could get expensive if the assignment chains are long.  Maybe
284150397Sobrien     we should throttle the number of iterations, possibly based on
284250397Sobrien     the optimization level or flag_expensive_optimizations.
284350397Sobrien
284450397Sobrien     We could propagate more information in the first pass by making use
284550397Sobrien     of REG_N_SETS to determine immediately that the alias information
284650397Sobrien     for a pseudo is "constant".
284750397Sobrien
284850397Sobrien     A program with an uninitialized variable can cause an infinite loop
284950397Sobrien     here.  Instead of doing a full dataflow analysis to detect such problems
285050397Sobrien     we just cap the number of iterations for the loop.
285150397Sobrien
285250397Sobrien     The state of the arrays for the set chain in question does not matter
285350397Sobrien     since the program has undefined behavior.  */
285450397Sobrien
285550397Sobrien  pass = 0;
285650397Sobrien  do
285750397Sobrien    {
285850397Sobrien      /* Assume nothing will change this iteration of the loop.  */
285950397Sobrien      changed = 0;
286050397Sobrien
286150397Sobrien      /* We want to assign the same IDs each iteration of this loop, so
286250397Sobrien	 start counting from zero each iteration of the loop.  */
286350397Sobrien      unique_id = 0;
286450397Sobrien
286590075Sobrien      /* We're at the start of the function each iteration through the
286650397Sobrien	 loop, so we're copying arguments.  */
2867117395Skan      copying_arguments = true;
286850397Sobrien
286950397Sobrien      /* Wipe the potential alias information clean for this pass.  */
2870132718Skan      memset (new_reg_base_value, 0, maxreg * sizeof (rtx));
287150397Sobrien
287250397Sobrien      /* Wipe the reg_seen array clean.  */
2873132718Skan      memset (reg_seen, 0, maxreg);
287450397Sobrien
287550397Sobrien      /* Mark all hard registers which may contain an address.
287650397Sobrien	 The stack, frame and argument pointers may contain an address.
287750397Sobrien	 An argument register which can hold a Pmode value may contain
287850397Sobrien	 an address even if it is not in BASE_REGS.
287950397Sobrien
288050397Sobrien	 The address expression is VOIDmode for an argument and
288150397Sobrien	 Pmode for other registers.  */
288250397Sobrien
2883117395Skan      memcpy (new_reg_base_value, static_reg_base_value,
2884117395Skan	      FIRST_PSEUDO_REGISTER * sizeof (rtx));
288550397Sobrien
288650397Sobrien      /* Walk the insns adding values to the new_reg_base_value array.  */
288750397Sobrien      for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
288850397Sobrien	{
288990075Sobrien	  if (INSN_P (insn))
289050397Sobrien	    {
289150397Sobrien	      rtx note, set;
289290075Sobrien
289390075Sobrien#if defined (HAVE_prologue) || defined (HAVE_epilogue)
289490075Sobrien	      /* The prologue/epilogue insns are not threaded onto the
289590075Sobrien		 insn chain until after reload has completed.  Thus,
289690075Sobrien		 there is no sense wasting time checking if INSN is in
289790075Sobrien		 the prologue/epilogue until after reload has completed.  */
289890075Sobrien	      if (reload_completed
289990075Sobrien		  && prologue_epilogue_contains (insn))
290090075Sobrien		continue;
290190075Sobrien#endif
290290075Sobrien
290350397Sobrien	      /* If this insn has a noalias note, process it,  Otherwise,
290450397Sobrien	         scan for sets.  A simple set will have no side effects
290590075Sobrien	         which could change the base value of any other register.  */
290650397Sobrien
290750397Sobrien	      if (GET_CODE (PATTERN (insn)) == SET
290890075Sobrien		  && REG_NOTES (insn) != 0
290990075Sobrien		  && find_reg_note (insn, REG_NOALIAS, NULL_RTX))
291090075Sobrien		record_set (SET_DEST (PATTERN (insn)), NULL_RTX, NULL);
291150397Sobrien	      else
291290075Sobrien		note_stores (PATTERN (insn), record_set, NULL);
291350397Sobrien
291450397Sobrien	      set = single_set (insn);
291550397Sobrien
291650397Sobrien	      if (set != 0
291750397Sobrien		  && GET_CODE (SET_DEST (set)) == REG
291890075Sobrien		  && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
291950397Sobrien		{
292090075Sobrien		  unsigned int regno = REGNO (SET_DEST (set));
292190075Sobrien		  rtx src = SET_SRC (set);
2922132718Skan		  rtx t;
292390075Sobrien
292490075Sobrien		  if (REG_NOTES (insn) != 0
292590075Sobrien		      && (((note = find_reg_note (insn, REG_EQUAL, 0)) != 0
292690075Sobrien			   && REG_N_SETS (regno) == 1)
292790075Sobrien			  || (note = find_reg_note (insn, REG_EQUIV, NULL_RTX)) != 0)
292890075Sobrien		      && GET_CODE (XEXP (note, 0)) != EXPR_LIST
292990075Sobrien		      && ! rtx_varies_p (XEXP (note, 0), 1)
2930132718Skan		      && ! reg_overlap_mentioned_p (SET_DEST (set),
2931132718Skan						    XEXP (note, 0)))
293290075Sobrien		    {
2933132718Skan		      set_reg_known_value (regno, XEXP (note, 0));
2934132718Skan		      set_reg_known_equiv_p (regno,
2935132718Skan			REG_NOTE_KIND (note) == REG_EQUIV);
293690075Sobrien		    }
293790075Sobrien		  else if (REG_N_SETS (regno) == 1
293890075Sobrien			   && GET_CODE (src) == PLUS
293990075Sobrien			   && GET_CODE (XEXP (src, 0)) == REG
2940132718Skan			   && (t = get_reg_known_value (REGNO (XEXP (src, 0))))
294190075Sobrien			   && GET_CODE (XEXP (src, 1)) == CONST_INT)
294290075Sobrien		    {
2943132718Skan		      t = plus_constant (t, INTVAL (XEXP (src, 1)));
2944132718Skan		      set_reg_known_value (regno, t);
2945132718Skan		      set_reg_known_equiv_p (regno, 0);
294690075Sobrien		    }
294790075Sobrien		  else if (REG_N_SETS (regno) == 1
294890075Sobrien			   && ! rtx_varies_p (src, 1))
294990075Sobrien		    {
2950132718Skan		      set_reg_known_value (regno, src);
2951132718Skan		      set_reg_known_equiv_p (regno, 0);
295290075Sobrien		    }
295350397Sobrien		}
295450397Sobrien	    }
295550397Sobrien	  else if (GET_CODE (insn) == NOTE
295650397Sobrien		   && NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_BEG)
2957117395Skan	    copying_arguments = false;
295850397Sobrien	}
295950397Sobrien
296050397Sobrien      /* Now propagate values from new_reg_base_value to reg_base_value.  */
2961132718Skan      if (maxreg != (unsigned int) max_reg_num())
2962132718Skan	abort ();
2963132718Skan      for (ui = 0; ui < maxreg; ui++)
296450397Sobrien	{
296552284Sobrien	  if (new_reg_base_value[ui]
2966132718Skan	      && new_reg_base_value[ui] != VARRAY_RTX (reg_base_value, ui)
2967132718Skan	      && ! rtx_equal_p (new_reg_base_value[ui],
2968132718Skan				VARRAY_RTX (reg_base_value, ui)))
296950397Sobrien	    {
2970132718Skan	      VARRAY_RTX (reg_base_value, ui) = new_reg_base_value[ui];
297150397Sobrien	      changed = 1;
297250397Sobrien	    }
297350397Sobrien	}
297450397Sobrien    }
297550397Sobrien  while (changed && ++pass < MAX_ALIAS_LOOP_PASSES);
297650397Sobrien
297750397Sobrien  /* Fill in the remaining entries.  */
2978132718Skan  for (i = 0; i < (int)reg_known_value_size; i++)
297950397Sobrien    if (reg_known_value[i] == 0)
2980132718Skan      reg_known_value[i] = regno_reg_rtx[i + FIRST_PSEUDO_REGISTER];
298150397Sobrien
298250397Sobrien  /* Simplify the reg_base_value array so that no register refers to
298350397Sobrien     another register, except to special registers indirectly through
298450397Sobrien     ADDRESS expressions.
298550397Sobrien
298650397Sobrien     In theory this loop can take as long as O(registers^2), but unless
298750397Sobrien     there are very long dependency chains it will run in close to linear
298850397Sobrien     time.
298950397Sobrien
299050397Sobrien     This loop may not be needed any longer now that the main loop does
299150397Sobrien     a better job at propagating alias information.  */
299250397Sobrien  pass = 0;
299350397Sobrien  do
299450397Sobrien    {
299550397Sobrien      changed = 0;
299650397Sobrien      pass++;
2997132718Skan      for (ui = 0; ui < maxreg; ui++)
299850397Sobrien	{
2999132718Skan	  rtx base = VARRAY_RTX (reg_base_value, ui);
300050397Sobrien	  if (base && GET_CODE (base) == REG)
300150397Sobrien	    {
300252284Sobrien	      unsigned int base_regno = REGNO (base);
300352284Sobrien	      if (base_regno == ui)		/* register set from itself */
3004132718Skan		VARRAY_RTX (reg_base_value, ui) = 0;
300550397Sobrien	      else
3006132718Skan		VARRAY_RTX (reg_base_value, ui)
3007132718Skan		  = VARRAY_RTX (reg_base_value, base_regno);
300850397Sobrien	      changed = 1;
300950397Sobrien	    }
301050397Sobrien	}
301150397Sobrien    }
301250397Sobrien  while (changed && pass < MAX_ALIAS_LOOP_PASSES);
301350397Sobrien
301490075Sobrien  /* Clean up.  */
301590075Sobrien  free (new_reg_base_value);
301650397Sobrien  new_reg_base_value = 0;
301790075Sobrien  free (reg_seen);
301850397Sobrien  reg_seen = 0;
3019132718Skan  timevar_pop (TV_ALIAS_ANALYSIS);
302050397Sobrien}
302150397Sobrien
302250397Sobrienvoid
3023132718Skanend_alias_analysis (void)
302450397Sobrien{
3025132718Skan  old_reg_base_value = reg_base_value;
302650397Sobrien  reg_known_value = 0;
302790075Sobrien  reg_known_value_size = 0;
3028132718Skan  free (reg_known_equiv_p);
302990075Sobrien  reg_known_equiv_p = 0;
303050397Sobrien  if (alias_invariant)
303150397Sobrien    {
303250397Sobrien      alias_invariant = 0;
3033132718Skan      alias_invariant_size = 0;
303450397Sobrien    }
303550397Sobrien}
3036117395Skan
3037117395Skan#include "gt-alias.h"
3038