/* Alias analysis for GNU C
   Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
   Free Software Foundation, Inc.
   Contributed by John Carr (jfc@mit.edu).

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING.  If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "rtl.h"
#include "tree.h"
#include "tm_p.h"
#include "function.h"
#include "expr.h"
#include "regs.h"
#include "hard-reg-set.h"
#include "basic-block.h"
#include "flags.h"
#include "output.h"
#include "toplev.h"
#include "cselib.h"
#include "splay-tree.h"
#include "ggc.h"
#include "langhooks.h"
#include "timevar.h"
#include "target.h"
#include "cgraph.h"
#include "varray.h"

/* The alias sets assigned to MEMs assist the back-end in determining
   which MEMs can alias which other MEMs.  In general, two MEMs in
   different alias sets cannot alias each other, with one important
   exception.  Consider something like:

     struct S { int i; double d; };

   a store to an `S' can alias something of either type `int' or type
   `double'.  (However, a store to an `int' cannot alias a `double'
   and vice versa.)  We indicate this via a tree structure that looks
   like:
           struct S
            /   \
	   /     \
         |/_     _\|
         int    double

   (The arrows are directed and point downwards.)
    In this situation we say the alias set for `struct S' is the
   `superset' and that those for `int' and `double' are `subsets'.

   To see whether two alias sets can point to the same memory, we must
   see if either alias set is a subset of the other. We need not trace
   past immediate descendants, however, since we propagate all
   grandchildren up one level.

   Alias set zero is implicitly a superset of all other alias sets.
   However, this is no actual entry for alias set zero.  It is an
   error to attempt to explicitly construct a subset of zero.  */

struct alias_set_entry GTY(())
{
  /* The alias set number, as stored in MEM_ALIAS_SET.  */
  HOST_WIDE_INT alias_set;

  /* The children of the alias set.  These are not just the immediate
     children, but, in fact, all descendants.  So, if we have:

       struct T { struct S s; float f; }

     continuing our example above, the children here will be all of
     `int', `double', `float', and `struct S'.  */
  splay_tree GTY((param1_is (int), param2_is (int))) children;

  /* Nonzero if would have a child of zero: this effectively makes this
     alias set the same as alias set zero.  */
  int has_zero_child;
};
typedef struct alias_set_entry *alias_set_entry;

static int rtx_equal_for_memref_p (rtx, rtx);
static rtx find_symbolic_term (rtx);
static int memrefs_conflict_p (int, rtx, int, rtx, HOST_WIDE_INT);
static void record_set (rtx, rtx, void *);
static int base_alias_check (rtx, rtx, enum machine_mode,
			     enum machine_mode);
static rtx find_base_value (rtx);
static int mems_in_disjoint_alias_sets_p (rtx, rtx);
static int insert_subset_children (splay_tree_node, void*);
static tree find_base_decl (tree);
static alias_set_entry get_alias_set_entry (HOST_WIDE_INT);
static rtx fixed_scalar_and_varying_struct_p (rtx, rtx, rtx, rtx,
					      int (*) (rtx, int));
static int aliases_everything_p (rtx);
static bool nonoverlapping_component_refs_p (tree, tree);
static tree decl_for_component_ref (tree);
static rtx adjust_offset_for_component_ref (tree, rtx);
static int nonoverlapping_memrefs_p (rtx, rtx);
static int write_dependence_p (rtx, rtx, int, int);

static int nonlocal_mentioned_p_1 (rtx *, void *);
static int nonlocal_mentioned_p (rtx);
static int nonlocal_referenced_p_1 (rtx *, void *);
static int nonlocal_referenced_p (rtx);
static int nonlocal_set_p_1 (rtx *, void *);
static int nonlocal_set_p (rtx);
static void memory_modified_1 (rtx, rtx, void *);

/* Set up all info needed to perform alias analysis on memory references.  */

/* Returns the size in bytes of the mode of X.  */
#define SIZE_FOR_MODE(X) (GET_MODE_SIZE (GET_MODE (X)))

/* Returns nonzero if MEM1 and MEM2 do not alias because they are in
   different alias sets.  We ignore alias sets in functions making use
   of variable arguments because the va_arg macros on some systems are
   not legal ANSI C.  */
#define DIFFERENT_ALIAS_SETS_P(MEM1, MEM2)			\
  mems_in_disjoint_alias_sets_p (MEM1, MEM2)

/* Cap the number of passes we make over the insns propagating alias
   information through set chains.   10 is a completely arbitrary choice.  */
#define MAX_ALIAS_LOOP_PASSES 10

/* reg_base_value[N] gives an address to which register N is related.
   If all sets after the first add or subtract to the current value
   or otherwise modify it so it does not point to a different top level
   object, reg_base_value[N] is equal to the address part of the source
   of the first set.

   A base address can be an ADDRESS, SYMBOL_REF, or LABEL_REF.  ADDRESS
   expressions represent certain special values: function arguments and
   the stack, frame, and argument pointers.

   The contents of an ADDRESS is not normally used, the mode of the
   ADDRESS determines whether the ADDRESS is a function argument or some
   other special value.  Pointer equality, not rtx_equal_p, determines whether
   two ADDRESS expressions refer to the same base address.

   The only use of the contents of an ADDRESS is for determining if the
   current function performs nonlocal memory memory references for the
   purposes of marking the function as a constant function.  */

static GTY(()) varray_type reg_base_value;
static rtx *new_reg_base_value;

/* We preserve the copy of old array around to avoid amount of garbage
   produced.  About 8% of garbage produced were attributed to this
   array.  */
static GTY((deletable (""))) varray_type old_reg_base_value;

/* Static hunks of RTL used by the aliasing code; these are initialized
   once per function to avoid unnecessary RTL allocations.  */
static GTY (()) rtx static_reg_base_value[FIRST_PSEUDO_REGISTER];

#define REG_BASE_VALUE(X) \
  (reg_base_value && REGNO (X) < VARRAY_SIZE (reg_base_value) \
   ? VARRAY_RTX (reg_base_value, REGNO (X)) : 0)

/* Vector of known invariant relationships between registers.  Set in
   loop unrolling.  Indexed by register number, if nonzero the value
   is an expression describing this register in terms of another.

   The length of this array is REG_BASE_VALUE_SIZE.

   Because this array contains only pseudo registers it has no effect
   after reload.  */
static rtx *alias_invariant;
unsigned int alias_invariant_size;

/* Vector indexed by N giving the initial (unchanging) value known for
   pseudo-register N.  This array is initialized in
   init_alias_analysis, and does not change until end_alias_analysis
   is called.  */
rtx *reg_known_value;

/* Indicates number of valid entries in reg_known_value.  */
static unsigned int reg_known_value_size;

/* Vector recording for each reg_known_value whether it is due to a
   REG_EQUIV note.  Future passes (viz., reload) may replace the
   pseudo with the equivalent expression and so we account for the
   dependences that would be introduced if that happens.

   The REG_EQUIV notes created in assign_parms may mention the arg
   pointer, and there are explicit insns in the RTL that modify the
   arg pointer.  Thus we must ensure that such insns don't get
   scheduled across each other because that would invalidate the
   REG_EQUIV notes.  One could argue that the REG_EQUIV notes are
   wrong, but solving the problem in the scheduler will likely give
   better code, so we do it here.  */
char *reg_known_equiv_p;

/* True when scanning insns from the start of the rtl to the
   NOTE_INSN_FUNCTION_BEG note.  */
static bool copying_arguments;

/* The splay-tree used to store the various alias set entries.  */
static GTY ((param_is (struct alias_set_entry))) varray_type alias_sets;

/* Returns a pointer to the alias set entry for ALIAS_SET, if there is
   such an entry, or NULL otherwise.  */

static inline alias_set_entry
get_alias_set_entry (HOST_WIDE_INT alias_set)
{
  return (alias_set_entry)VARRAY_GENERIC_PTR (alias_sets, alias_set);
}

/* Returns nonzero if the alias sets for MEM1 and MEM2 are such that
   the two MEMs cannot alias each other.  */

static inline int
mems_in_disjoint_alias_sets_p (rtx mem1, rtx mem2)
{
#ifdef ENABLE_CHECKING
/* Perform a basic sanity check.  Namely, that there are no alias sets
   if we're not using strict aliasing.  This helps to catch bugs
   whereby someone uses PUT_CODE, but doesn't clear MEM_ALIAS_SET, or
   where a MEM is allocated in some way other than by the use of
   gen_rtx_MEM, and the MEM_ALIAS_SET is not cleared.  If we begin to
   use alias sets to indicate that spilled registers cannot alias each
   other, we might need to remove this check.  */
  if (! flag_strict_aliasing
      && (MEM_ALIAS_SET (mem1) != 0 || MEM_ALIAS_SET (mem2) != 0))
    abort ();
#endif

  return ! alias_sets_conflict_p (MEM_ALIAS_SET (mem1), MEM_ALIAS_SET (mem2));
}

/* Insert the NODE into the splay tree given by DATA.  Used by
   record_alias_subset via splay_tree_foreach.  */

static int
insert_subset_children (splay_tree_node node, void *data)
{
  splay_tree_insert ((splay_tree) data, node->key, node->value);

  return 0;
}

/* Return 1 if the two specified alias sets may conflict.  */

int
alias_sets_conflict_p (HOST_WIDE_INT set1, HOST_WIDE_INT set2)
{
  alias_set_entry ase;

  /* If have no alias set information for one of the operands, we have
     to assume it can alias anything.  */
  if (set1 == 0 || set2 == 0
      /* If the two alias sets are the same, they may alias.  */
      || set1 == set2)
    return 1;

  /* See if the first alias set is a subset of the second.  */
  ase = get_alias_set_entry (set1);
  if (ase != 0
      && (ase->has_zero_child
	  || splay_tree_lookup (ase->children,
				(splay_tree_key) set2)))
    return 1;

  /* Now do the same, but with the alias sets reversed.  */
  ase = get_alias_set_entry (set2);
  if (ase != 0
      && (ase->has_zero_child
	  || splay_tree_lookup (ase->children,
				(splay_tree_key) set1)))
    return 1;

  /* The two alias sets are distinct and neither one is the
     child of the other.  Therefore, they cannot alias.  */
  return 0;
}

/* Return 1 if TYPE is a RECORD_TYPE, UNION_TYPE, or QUAL_UNION_TYPE and has
   has any readonly fields.  If any of the fields have types that
   contain readonly fields, return true as well.  */

int
readonly_fields_p (tree type)
{
  tree field;

  if (TREE_CODE (type) != RECORD_TYPE && TREE_CODE (type) != UNION_TYPE
      && TREE_CODE (type) != QUAL_UNION_TYPE)
    return 0;

  for (field = TYPE_FIELDS (type); field != 0; field = TREE_CHAIN (field))
    if (TREE_CODE (field) == FIELD_DECL
	&& (TREE_READONLY (field)
	    || readonly_fields_p (TREE_TYPE (field))))
      return 1;

  return 0;
}

/* Return 1 if any MEM object of type T1 will always conflict (using the
   dependency routines in this file) with any MEM object of type T2.
   This is used when allocating temporary storage.  If T1 and/or T2 are
   NULL_TREE, it means we know nothing about the storage.  */

int
objects_must_conflict_p (tree t1, tree t2)
{
  HOST_WIDE_INT set1, set2;

  /* If neither has a type specified, we don't know if they'll conflict
     because we may be using them to store objects of various types, for
     example the argument and local variables areas of inlined functions.  */
  if (t1 == 0 && t2 == 0)
    return 0;

  /* If one or the other has readonly fields or is readonly,
     then they may not conflict.  */
  if ((t1 != 0 && readonly_fields_p (t1))
      || (t2 != 0 && readonly_fields_p (t2))
      || (t1 != 0 && lang_hooks.honor_readonly && TYPE_READONLY (t1))
      || (t2 != 0 && lang_hooks.honor_readonly && TYPE_READONLY (t2)))
    return 0;

  /* If they are the same type, they must conflict.  */
  if (t1 == t2
      /* Likewise if both are volatile.  */
      || (t1 != 0 && TYPE_VOLATILE (t1) && t2 != 0 && TYPE_VOLATILE (t2)))
    return 1;

  set1 = t1 ? get_alias_set (t1) : 0;
  set2 = t2 ? get_alias_set (t2) : 0;

  /* Otherwise they conflict if they have no alias set or the same. We
     can't simply use alias_sets_conflict_p here, because we must make
     sure that every subtype of t1 will conflict with every subtype of
     t2 for which a pair of subobjects of these respective subtypes
     overlaps on the stack.  */
  return set1 == 0 || set2 == 0 || set1 == set2;
}

/* T is an expression with pointer type.  Find the DECL on which this
   expression is based.  (For example, in `a[i]' this would be `a'.)
   If there is no such DECL, or a unique decl cannot be determined,
   NULL_TREE is returned.  */

static tree
find_base_decl (tree t)
{
  tree d0, d1, d2;

  if (t == 0 || t == error_mark_node || ! POINTER_TYPE_P (TREE_TYPE (t)))
    return 0;

  /* If this is a declaration, return it.  */
  if (TREE_CODE_CLASS (TREE_CODE (t)) == 'd')
    return t;

  /* Handle general expressions.  It would be nice to deal with
     COMPONENT_REFs here.  If we could tell that `a' and `b' were the
     same, then `a->f' and `b->f' are also the same.  */
  switch (TREE_CODE_CLASS (TREE_CODE (t)))
    {
    case '1':
      return find_base_decl (TREE_OPERAND (t, 0));

    case '2':
      /* Return 0 if found in neither or both are the same.  */
      d0 = find_base_decl (TREE_OPERAND (t, 0));
      d1 = find_base_decl (TREE_OPERAND (t, 1));
      if (d0 == d1)
	return d0;
      else if (d0 == 0)
	return d1;
      else if (d1 == 0)
	return d0;
      else
	return 0;

    case '3':
      d0 = find_base_decl (TREE_OPERAND (t, 0));
      d1 = find_base_decl (TREE_OPERAND (t, 1));
      d2 = find_base_decl (TREE_OPERAND (t, 2));

      /* Set any nonzero values from the last, then from the first.  */
      if (d1 == 0) d1 = d2;
      if (d0 == 0) d0 = d1;
      if (d1 == 0) d1 = d0;
      if (d2 == 0) d2 = d1;

      /* At this point all are nonzero or all are zero.  If all three are the
	 same, return it.  Otherwise, return zero.  */
      return (d0 == d1 && d1 == d2) ? d0 : 0;

    default:
      return 0;
    }
}

/* Return 1 if all the nested component references handled by
   get_inner_reference in T are such that we can address the object in T.  */

int
can_address_p (tree t)
{
  /* If we're at the end, it is vacuously addressable.  */
  if (! handled_component_p (t))
    return 1;

  /* Bitfields are never addressable.  */
  else if (TREE_CODE (t) == BIT_FIELD_REF)
    return 0;

  /* Fields are addressable unless they are marked as nonaddressable or
     the containing type has alias set 0.  */
  else if (TREE_CODE (t) == COMPONENT_REF
	   && ! DECL_NONADDRESSABLE_P (TREE_OPERAND (t, 1))
	   && get_alias_set (TREE_TYPE (TREE_OPERAND (t, 0))) != 0
	   && can_address_p (TREE_OPERAND (t, 0)))
    return 1;

  /* Likewise for arrays.  */
  else if ((TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
	   && ! TYPE_NONALIASED_COMPONENT (TREE_TYPE (TREE_OPERAND (t, 0)))
	   && get_alias_set (TREE_TYPE (TREE_OPERAND (t, 0))) != 0
	   && can_address_p (TREE_OPERAND (t, 0)))
    return 1;

  return 0;
}

/* Return the alias set for T, which may be either a type or an
   expression.  Call language-specific routine for help, if needed.  */

HOST_WIDE_INT
get_alias_set (tree t)
{
  HOST_WIDE_INT set;

  /* If we're not doing any alias analysis, just assume everything
     aliases everything else.  Also return 0 if this or its type is
     an error.  */
  if (! flag_strict_aliasing || t == error_mark_node
      || (! TYPE_P (t)
	  && (TREE_TYPE (t) == 0 || TREE_TYPE (t) == error_mark_node)))
    return 0;

  /* We can be passed either an expression or a type.  This and the
     language-specific routine may make mutually-recursive calls to each other
     to figure out what to do.  At each juncture, we see if this is a tree
     that the language may need to handle specially.  First handle things that
     aren't types.  */
  if (! TYPE_P (t))
    {
      tree inner = t;
      tree placeholder_ptr = 0;

      /* Remove any nops, then give the language a chance to do
	 something with this tree before we look at it.  */
      STRIP_NOPS (t);
      set = (*lang_hooks.get_alias_set) (t);
      if (set != -1)
	return set;

      /* First see if the actual object referenced is an INDIRECT_REF from a
	 restrict-qualified pointer or a "void *".  Replace
	 PLACEHOLDER_EXPRs.  */
      while (TREE_CODE (inner) == PLACEHOLDER_EXPR
	     || handled_component_p (inner))
	{
	  if (TREE_CODE (inner) == PLACEHOLDER_EXPR)
	    inner = find_placeholder (inner, &placeholder_ptr);
	  else
	    inner = TREE_OPERAND (inner, 0);

	  STRIP_NOPS (inner);
	}

      /* Check for accesses through restrict-qualified pointers.  */
      if (TREE_CODE (inner) == INDIRECT_REF)
	{
	  tree decl = find_base_decl (TREE_OPERAND (inner, 0));

	  if (decl && DECL_POINTER_ALIAS_SET_KNOWN_P (decl))
	    {
	      /* If we haven't computed the actual alias set, do it now.  */
	      if (DECL_POINTER_ALIAS_SET (decl) == -2)
		{
		  /* No two restricted pointers can point at the same thing.
		     However, a restricted pointer can point at the same thing
		     as an unrestricted pointer, if that unrestricted pointer
		     is based on the restricted pointer.  So, we make the
		     alias set for the restricted pointer a subset of the
		     alias set for the type pointed to by the type of the
		     decl.  */
		  HOST_WIDE_INT pointed_to_alias_set
		    = get_alias_set (TREE_TYPE (TREE_TYPE (decl)));

		  if (pointed_to_alias_set == 0)
		    /* It's not legal to make a subset of alias set zero.  */
		    DECL_POINTER_ALIAS_SET (decl) = 0;
		  else
		    {
		      DECL_POINTER_ALIAS_SET (decl) = new_alias_set ();
		      record_alias_subset (pointed_to_alias_set,
					   DECL_POINTER_ALIAS_SET (decl));
		    }
		}

	      /* We use the alias set indicated in the declaration.  */
	      return DECL_POINTER_ALIAS_SET (decl);
	    }

	  /* If we have an INDIRECT_REF via a void pointer, we don't
	     know anything about what that might alias.  */
	  else if (TREE_CODE (TREE_TYPE (inner)) == VOID_TYPE)
	    return 0;
	}

      /* Otherwise, pick up the outermost object that we could have a pointer
	 to, processing conversion and PLACEHOLDER_EXPR as above.  */
      placeholder_ptr = 0;
      while (TREE_CODE (t) == PLACEHOLDER_EXPR
	     || (handled_component_p (t) && ! can_address_p (t)))
	{
	  if (TREE_CODE (t) == PLACEHOLDER_EXPR)
	    t = find_placeholder (t, &placeholder_ptr);
	  else
	    t = TREE_OPERAND (t, 0);

	  STRIP_NOPS (t);
	}

      /* If we've already determined the alias set for a decl, just return
	 it.  This is necessary for C++ anonymous unions, whose component
	 variables don't look like union members (boo!).  */
      if (TREE_CODE (t) == VAR_DECL
	  && DECL_RTL_SET_P (t) && GET_CODE (DECL_RTL (t)) == MEM)
	return MEM_ALIAS_SET (DECL_RTL (t));

      /* Now all we care about is the type.  */
      t = TREE_TYPE (t);
    }

  /* Variant qualifiers don't affect the alias set, so get the main
     variant. If this is a type with a known alias set, return it.  */
  t = TYPE_MAIN_VARIANT (t);
  if (TYPE_ALIAS_SET_KNOWN_P (t))
    return TYPE_ALIAS_SET (t);

  /* See if the language has special handling for this type.  */
  set = (*lang_hooks.get_alias_set) (t);
  if (set != -1)
    return set;

  /* There are no objects of FUNCTION_TYPE, so there's no point in
     using up an alias set for them.  (There are, of course, pointers
     and references to functions, but that's different.)  */
  else if (TREE_CODE (t) == FUNCTION_TYPE)
    set = 0;

  /* Unless the language specifies otherwise, let vector types alias
     their components.  This avoids some nasty type punning issues in
     normal usage.  And indeed lets vectors be treated more like an
     array slice.  */
  else if (TREE_CODE (t) == VECTOR_TYPE)
    set = get_alias_set (TREE_TYPE (t));

  else
    /* Otherwise make a new alias set for this type.  */
    set = new_alias_set ();

  TYPE_ALIAS_SET (t) = set;

  /* If this is an aggregate type, we must record any component aliasing
     information.  */
  if (AGGREGATE_TYPE_P (t) || TREE_CODE (t) == COMPLEX_TYPE)
    record_component_aliases (t);

  return set;
}

/* Return a brand-new alias set.  */

static GTY(()) HOST_WIDE_INT last_alias_set;

HOST_WIDE_INT
new_alias_set (void)
{
  if (flag_strict_aliasing)
    {
      if (!alias_sets)
	VARRAY_GENERIC_PTR_INIT (alias_sets, 10, "alias sets");
      else
	VARRAY_GROW (alias_sets, last_alias_set + 2);
      return ++last_alias_set;
    }
  else
    return 0;
}

/* Indicate that things in SUBSET can alias things in SUPERSET, but that
   not everything that aliases SUPERSET also aliases SUBSET.  For example,
   in C, a store to an `int' can alias a load of a structure containing an
   `int', and vice versa.  But it can't alias a load of a 'double' member
   of the same structure.  Here, the structure would be the SUPERSET and
   `int' the SUBSET.  This relationship is also described in the comment at
   the beginning of this file.

   This function should be called only once per SUPERSET/SUBSET pair.

   It is illegal for SUPERSET to be zero; everything is implicitly a
   subset of alias set zero.  */

void
record_alias_subset (HOST_WIDE_INT superset, HOST_WIDE_INT subset)
{
  alias_set_entry superset_entry;
  alias_set_entry subset_entry;

  /* It is possible in complex type situations for both sets to be the same,
     in which case we can ignore this operation.  */
  if (superset == subset)
    return;

  if (superset == 0)
    abort ();

  superset_entry = get_alias_set_entry (superset);
  if (superset_entry == 0)
    {
      /* Create an entry for the SUPERSET, so that we have a place to
	 attach the SUBSET.  */
      superset_entry = ggc_alloc (sizeof (struct alias_set_entry));
      superset_entry->alias_set = superset;
      superset_entry->children
	= splay_tree_new_ggc (splay_tree_compare_ints);
      superset_entry->has_zero_child = 0;
      VARRAY_GENERIC_PTR (alias_sets, superset) = superset_entry;
    }

  if (subset == 0)
    superset_entry->has_zero_child = 1;
  else
    {
      subset_entry = get_alias_set_entry (subset);
      /* If there is an entry for the subset, enter all of its children
	 (if they are not already present) as children of the SUPERSET.  */
      if (subset_entry)
	{
	  if (subset_entry->has_zero_child)
	    superset_entry->has_zero_child = 1;

	  splay_tree_foreach (subset_entry->children, insert_subset_children,
			      superset_entry->children);
	}

      /* Enter the SUBSET itself as a child of the SUPERSET.  */
      splay_tree_insert (superset_entry->children,
			 (splay_tree_key) subset, 0);
    }
}

/* Record that component types of TYPE, if any, are part of that type for
   aliasing purposes.  For record types, we only record component types
   for fields that are marked addressable.  For array types, we always
   record the component types, so the front end should not call this
   function if the individual component aren't addressable.  */

void
record_component_aliases (tree type)
{
  HOST_WIDE_INT superset = get_alias_set (type);
  tree field;

  if (superset == 0)
    return;

  switch (TREE_CODE (type))
    {
    case ARRAY_TYPE:
      if (! TYPE_NONALIASED_COMPONENT (type))
	record_alias_subset (superset, get_alias_set (TREE_TYPE (type)));
      break;

    case RECORD_TYPE:
    case UNION_TYPE:
    case QUAL_UNION_TYPE:
      /* Recursively record aliases for the base classes, if there are any.  */
      if (TYPE_BINFO (type) != NULL && TYPE_BINFO_BASETYPES (type) != NULL)
	{
	  int i;
	  for (i = 0; i < TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (type)); i++)
	    {
	      tree binfo = TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), i);
	      record_alias_subset (superset,
				   get_alias_set (BINFO_TYPE (binfo)));
	    }
	}
      for (field = TYPE_FIELDS (type); field != 0; field = TREE_CHAIN (field))
	if (TREE_CODE (field) == FIELD_DECL && ! DECL_NONADDRESSABLE_P (field))
	  record_alias_subset (superset, get_alias_set (TREE_TYPE (field)));
      break;

    case COMPLEX_TYPE:
      record_alias_subset (superset, get_alias_set (TREE_TYPE (type)));
      break;

    default:
      break;
    }
}

/* Allocate an alias set for use in storing and reading from the varargs
   spill area.  */

static GTY(()) HOST_WIDE_INT varargs_set = -1;

HOST_WIDE_INT
get_varargs_alias_set (void)
{
  if (varargs_set == -1)
    varargs_set = new_alias_set ();

  return varargs_set;
}

/* Likewise, but used for the fixed portions of the frame, e.g., register
   save areas.  */

static GTY(()) HOST_WIDE_INT frame_set = -1;

HOST_WIDE_INT
get_frame_alias_set (void)
{
  if (frame_set == -1)
    frame_set = new_alias_set ();

  return frame_set;
}

/* Inside SRC, the source of a SET, find a base address.  */

static rtx
find_base_value (rtx src)
{
  unsigned int regno;

  switch (GET_CODE (src))
    {
    case SYMBOL_REF:
    case LABEL_REF:
      return src;

    case REG:
      regno = REGNO (src);
      /* At the start of a function, argument registers have known base
	 values which may be lost later.  Returning an ADDRESS
	 expression here allows optimization based on argument values
	 even when the argument registers are used for other purposes.  */
      if (regno < FIRST_PSEUDO_REGISTER && copying_arguments)
	return new_reg_base_value[regno];

      /* If a pseudo has a known base value, return it.  Do not do this
	 for non-fixed hard regs since it can result in a circular
	 dependency chain for registers which have values at function entry.

	 The test above is not sufficient because the scheduler may move
	 a copy out of an arg reg past the NOTE_INSN_FUNCTION_BEGIN.  */
      if ((regno >= FIRST_PSEUDO_REGISTER || fixed_regs[regno])
	  && regno < VARRAY_SIZE (reg_base_value))
	{
	  /* If we're inside init_alias_analysis, use new_reg_base_value
	     to reduce the number of relaxation iterations.  */
	  if (new_reg_base_value && new_reg_base_value[regno]
	      && REG_N_SETS (regno) == 1)
	    return new_reg_base_value[regno];

	  if (VARRAY_RTX (reg_base_value, regno))
	    return VARRAY_RTX (reg_base_value, regno);
	}

      return 0;

    case MEM:
      /* Check for an argument passed in memory.  Only record in the
	 copying-arguments block; it is too hard to track changes
	 otherwise.  */
      if (copying_arguments
	  && (XEXP (src, 0) == arg_pointer_rtx
	      || (GET_CODE (XEXP (src, 0)) == PLUS
		  && XEXP (XEXP (src, 0), 0) == arg_pointer_rtx)))
	return gen_rtx_ADDRESS (VOIDmode, src);
      return 0;

    case CONST:
      src = XEXP (src, 0);
      if (GET_CODE (src) != PLUS && GET_CODE (src) != MINUS)
	break;

      /* ... fall through ...  */

    case PLUS:
    case MINUS:
      {
	rtx temp, src_0 = XEXP (src, 0), src_1 = XEXP (src, 1);

	/* If either operand is a REG that is a known pointer, then it
	   is the base.  */
	if (REG_P (src_0) && REG_POINTER (src_0))
	  return find_base_value (src_0);
	if (REG_P (src_1) && REG_POINTER (src_1))
	  return find_base_value (src_1);

	/* If either operand is a REG, then see if we already have
	   a known value for it.  */
	if (REG_P (src_0))
	  {
	    temp = find_base_value (src_0);
	    if (temp != 0)
	      src_0 = temp;
	  }

	if (REG_P (src_1))
	  {
	    temp = find_base_value (src_1);
	    if (temp!= 0)
	      src_1 = temp;
	  }

	/* If either base is named object or a special address
	   (like an argument or stack reference), then use it for the
	   base term.  */
	if (src_0 != 0
	    && (GET_CODE (src_0) == SYMBOL_REF
		|| GET_CODE (src_0) == LABEL_REF
		|| (GET_CODE (src_0) == ADDRESS
		    && GET_MODE (src_0) != VOIDmode)))
	  return src_0;

	if (src_1 != 0
	    && (GET_CODE (src_1) == SYMBOL_REF
		|| GET_CODE (src_1) == LABEL_REF
		|| (GET_CODE (src_1) == ADDRESS
		    && GET_MODE (src_1) != VOIDmode)))
	  return src_1;

	/* Guess which operand is the base address:
	   If either operand is a symbol, then it is the base.  If
	   either operand is a CONST_INT, then the other is the base.  */
	if (GET_CODE (src_1) == CONST_INT || CONSTANT_P (src_0))
	  return find_base_value (src_0);
	else if (GET_CODE (src_0) == CONST_INT || CONSTANT_P (src_1))
	  return find_base_value (src_1);

	return 0;
      }

    case LO_SUM:
      /* The standard form is (lo_sum reg sym) so look only at the
	 second operand.  */
      return find_base_value (XEXP (src, 1));

    case AND:
      /* If the second operand is constant set the base
	 address to the first operand.  */
      if (GET_CODE (XEXP (src, 1)) == CONST_INT && INTVAL (XEXP (src, 1)) != 0)
	return find_base_value (XEXP (src, 0));
      return 0;

    case TRUNCATE:
      if (GET_MODE_SIZE (GET_MODE (src)) < GET_MODE_SIZE (Pmode))
	break;
      /* Fall through.  */
    case HIGH:
    case PRE_INC:
    case PRE_DEC:
    case POST_INC:
    case POST_DEC:
    case PRE_MODIFY:
    case POST_MODIFY:
      return find_base_value (XEXP (src, 0));

    case ZERO_EXTEND:
    case SIGN_EXTEND:	/* used for NT/Alpha pointers */
      {
	rtx temp = find_base_value (XEXP (src, 0));

	if (temp != 0 && CONSTANT_P (temp))
	  temp = convert_memory_address (Pmode, temp);

	return temp;
      }

    default:
      break;
    }

  return 0;
}

/* Called from init_alias_analysis indirectly through note_stores.  */

/* While scanning insns to find base values, reg_seen[N] is nonzero if
   register N has been set in this function.  */
static char *reg_seen;

/* Addresses which are known not to alias anything else are identified
   by a unique integer.  */
static int unique_id;

static void
record_set (rtx dest, rtx set, void *data ATTRIBUTE_UNUSED)
{
  unsigned regno;
  rtx src;
  int n;

  if (GET_CODE (dest) != REG)
    return;

  regno = REGNO (dest);

  if (regno >= VARRAY_SIZE (reg_base_value))
    abort ();

  /* If this spans multiple hard registers, then we must indicate that every
     register has an unusable value.  */
  if (regno < FIRST_PSEUDO_REGISTER)
    n = HARD_REGNO_NREGS (regno, GET_MODE (dest));
  else
    n = 1;
  if (n != 1)
    {
      while (--n >= 0)
	{
	  reg_seen[regno + n] = 1;
	  new_reg_base_value[regno + n] = 0;
	}
      return;
    }

  if (set)
    {
      /* A CLOBBER wipes out any old value but does not prevent a previously
	 unset register from acquiring a base address (i.e. reg_seen is not
	 set).  */
      if (GET_CODE (set) == CLOBBER)
	{
	  new_reg_base_value[regno] = 0;
	  return;
	}
      src = SET_SRC (set);
    }
  else
    {
      if (reg_seen[regno])
	{
	  new_reg_base_value[regno] = 0;
	  return;
	}
      reg_seen[regno] = 1;
      new_reg_base_value[regno] = gen_rtx_ADDRESS (Pmode,
						   GEN_INT (unique_id++));
      return;
    }

  /* This is not the first set.  If the new value is not related to the
     old value, forget the base value. Note that the following code is
     not detected:
     extern int x, y;  int *p = &x; p += (&y-&x);
     ANSI C does not allow computing the difference of addresses
     of distinct top level objects.  */
  if (new_reg_base_value[regno])
    switch (GET_CODE (src))
      {
      case LO_SUM:
      case MINUS:
	if (XEXP (src, 0) != dest && XEXP (src, 1) != dest)
	  new_reg_base_value[regno] = 0;
	break;
      case PLUS:
	/* If the value we add in the PLUS is also a valid base value,
	   this might be the actual base value, and the original value
	   an index.  */
	{
	  rtx other = NULL_RTX;

	  if (XEXP (src, 0) == dest)
	    other = XEXP (src, 1);
	  else if (XEXP (src, 1) == dest)
	    other = XEXP (src, 0);

	  if (! other || find_base_value (other))
	    new_reg_base_value[regno] = 0;
	  break;
	}
      case AND:
	if (XEXP (src, 0) != dest || GET_CODE (XEXP (src, 1)) != CONST_INT)
	  new_reg_base_value[regno] = 0;
	break;
      default:
	new_reg_base_value[regno] = 0;
	break;
      }
  /* If this is the first set of a register, record the value.  */
  else if ((regno >= FIRST_PSEUDO_REGISTER || ! fixed_regs[regno])
	   && ! reg_seen[regno] && new_reg_base_value[regno] == 0)
    new_reg_base_value[regno] = find_base_value (src);

  reg_seen[regno] = 1;
}

/* Called from loop optimization when a new pseudo-register is
   created.  It indicates that REGNO is being set to VAL.  f INVARIANT
   is true then this value also describes an invariant relationship
   which can be used to deduce that two registers with unknown values
   are different.  */

void
record_base_value (unsigned int regno, rtx val, int invariant)
{
  if (invariant && alias_invariant && regno < alias_invariant_size)
    alias_invariant[regno] = val;

  if (regno >= VARRAY_SIZE (reg_base_value))
    VARRAY_GROW (reg_base_value, max_reg_num ());

  if (GET_CODE (val) == REG)
    {
      VARRAY_RTX (reg_base_value, regno)
	 = REG_BASE_VALUE (val);
      return;
    }
  VARRAY_RTX (reg_base_value, regno)
     = find_base_value (val);
}

/* Clear alias info for a register.  This is used if an RTL transformation
   changes the value of a register.  This is used in flow by AUTO_INC_DEC
   optimizations.  We don't need to clear reg_base_value, since flow only
   changes the offset.  */

void
clear_reg_alias_info (rtx reg)
{
  unsigned int regno = REGNO (reg);

  if (regno < reg_known_value_size && regno >= FIRST_PSEUDO_REGISTER)
    reg_known_value[regno] = reg;
}

/* Returns a canonical version of X, from the point of view alias
   analysis.  (For example, if X is a MEM whose address is a register,
   and the register has a known value (say a SYMBOL_REF), then a MEM
   whose address is the SYMBOL_REF is returned.)  */

rtx
canon_rtx (rtx x)
{
  /* Recursively look for equivalences.  */
  if (GET_CODE (x) == REG && REGNO (x) >= FIRST_PSEUDO_REGISTER
      && REGNO (x) < reg_known_value_size)
    return reg_known_value[REGNO (x)] == x
      ? x : canon_rtx (reg_known_value[REGNO (x)]);
  else if (GET_CODE (x) == PLUS)
    {
      rtx x0 = canon_rtx (XEXP (x, 0));
      rtx x1 = canon_rtx (XEXP (x, 1));

      if (x0 != XEXP (x, 0) || x1 != XEXP (x, 1))
	{
	  if (GET_CODE (x0) == CONST_INT)
	    return plus_constant (x1, INTVAL (x0));
	  else if (GET_CODE (x1) == CONST_INT)
	    return plus_constant (x0, INTVAL (x1));
	  return gen_rtx_PLUS (GET_MODE (x), x0, x1);
	}
    }

  /* This gives us much better alias analysis when called from
     the loop optimizer.   Note we want to leave the original
     MEM alone, but need to return the canonicalized MEM with
     all the flags with their original values.  */
  else if (GET_CODE (x) == MEM)
    x = replace_equiv_address_nv (x, canon_rtx (XEXP (x, 0)));

  return x;
}

/* Return 1 if X and Y are identical-looking rtx's.
   Expect that X and Y has been already canonicalized.

   We use the data in reg_known_value above to see if two registers with
   different numbers are, in fact, equivalent.  */

static int
rtx_equal_for_memref_p (rtx x, rtx y)
{
  int i;
  int j;
  enum rtx_code code;
  const char *fmt;

  if (x == 0 && y == 0)
    return 1;
  if (x == 0 || y == 0)
    return 0;

  if (x == y)
    return 1;

  code = GET_CODE (x);
  /* Rtx's of different codes cannot be equal.  */
  if (code != GET_CODE (y))
    return 0;

  /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent.
     (REG:SI x) and (REG:HI x) are NOT equivalent.  */

  if (GET_MODE (x) != GET_MODE (y))
    return 0;

  /* Some RTL can be compared without a recursive examination.  */
  switch (code)
    {
    case REG:
      return REGNO (x) == REGNO (y);

    case LABEL_REF:
      return XEXP (x, 0) == XEXP (y, 0);

    case SYMBOL_REF:
      return XSTR (x, 0) == XSTR (y, 0);

    case VALUE:
    case CONST_INT:
    case CONST_DOUBLE:
      /* There's no need to compare the contents of CONST_DOUBLEs or
	 CONST_INTs because pointer equality is a good enough
	 comparison for these nodes.  */
      return 0;

    case ADDRESSOF:
      return (XINT (x, 1) == XINT (y, 1)
	      && rtx_equal_for_memref_p (XEXP (x, 0),
					 XEXP (y, 0)));

    default:
      break;
    }

  /* canon_rtx knows how to handle plus.  No need to canonicalize.  */
  if (code == PLUS)
    return ((rtx_equal_for_memref_p (XEXP (x, 0), XEXP (y, 0))
	     && rtx_equal_for_memref_p (XEXP (x, 1), XEXP (y, 1)))
	    || (rtx_equal_for_memref_p (XEXP (x, 0), XEXP (y, 1))
		&& rtx_equal_for_memref_p (XEXP (x, 1), XEXP (y, 0))));
  /* For commutative operations, the RTX match if the operand match in any
     order.  Also handle the simple binary and unary cases without a loop.  */
  if (code == EQ || code == NE || GET_RTX_CLASS (code) == 'c')
    {
      rtx xop0 = canon_rtx (XEXP (x, 0));
      rtx yop0 = canon_rtx (XEXP (y, 0));
      rtx yop1 = canon_rtx (XEXP (y, 1));

      return ((rtx_equal_for_memref_p (xop0, yop0)
	       && rtx_equal_for_memref_p (canon_rtx (XEXP (x, 1)), yop1))
	      || (rtx_equal_for_memref_p (xop0, yop1)
		  && rtx_equal_for_memref_p (canon_rtx (XEXP (x, 1)), yop0)));
    }
  else if (GET_RTX_CLASS (code) == '<' || GET_RTX_CLASS (code) == '2')
    {
      return (rtx_equal_for_memref_p (canon_rtx (XEXP (x, 0)),
				      canon_rtx (XEXP (y, 0)))
	      && rtx_equal_for_memref_p (canon_rtx (XEXP (x, 1)),
					 canon_rtx (XEXP (y, 1))));
    }
  else if (GET_RTX_CLASS (code) == '1')
    return rtx_equal_for_memref_p (canon_rtx (XEXP (x, 0)),
				   canon_rtx (XEXP (y, 0)));

  /* Compare the elements.  If any pair of corresponding elements
     fail to match, return 0 for the whole things.

     Limit cases to types which actually appear in addresses.  */

  fmt = GET_RTX_FORMAT (code);
  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    {
      switch (fmt[i])
	{
	case 'i':
	  if (XINT (x, i) != XINT (y, i))
	    return 0;
	  break;

	case 'E':
	  /* Two vectors must have the same length.  */
	  if (XVECLEN (x, i) != XVECLEN (y, i))
	    return 0;

	  /* And the corresponding elements must match.  */
	  for (j = 0; j < XVECLEN (x, i); j++)
	    if (rtx_equal_for_memref_p (canon_rtx (XVECEXP (x, i, j)),
					canon_rtx (XVECEXP (y, i, j))) == 0)
	      return 0;
	  break;

	case 'e':
	  if (rtx_equal_for_memref_p (canon_rtx (XEXP (x, i)),
				      canon_rtx (XEXP (y, i))) == 0)
	    return 0;
	  break;

	  /* This can happen for asm operands.  */
	case 's':
	  if (strcmp (XSTR (x, i), XSTR (y, i)))
	    return 0;
	  break;

	/* This can happen for an asm which clobbers memory.  */
	case '0':
	  break;

	  /* It is believed that rtx's at this level will never
	     contain anything but integers and other rtx's,
	     except for within LABEL_REFs and SYMBOL_REFs.  */
	default:
	  abort ();
	}
    }
  return 1;
}

/* Given an rtx X, find a SYMBOL_REF or LABEL_REF within
   X and return it, or return 0 if none found.  */

static rtx
find_symbolic_term (rtx x)
{
  int i;
  enum rtx_code code;
  const char *fmt;

  code = GET_CODE (x);
  if (code == SYMBOL_REF || code == LABEL_REF)
    return x;
  if (GET_RTX_CLASS (code) == 'o')
    return 0;

  fmt = GET_RTX_FORMAT (code);
  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    {
      rtx t;

      if (fmt[i] == 'e')
	{
	  t = find_symbolic_term (XEXP (x, i));
	  if (t != 0)
	    return t;
	}
      else if (fmt[i] == 'E')
	break;
    }
  return 0;
}

rtx
find_base_term (rtx x)
{
  cselib_val *val;
  struct elt_loc_list *l;

#if defined (FIND_BASE_TERM)
  /* Try machine-dependent ways to find the base term.  */
  x = FIND_BASE_TERM (x);
#endif

  switch (GET_CODE (x))
    {
    case REG:
      return REG_BASE_VALUE (x);

    case TRUNCATE:
      if (GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (Pmode))
	return 0;
      /* Fall through.  */
    case HIGH:
    case PRE_INC:
    case PRE_DEC:
    case POST_INC:
    case POST_DEC:
    case PRE_MODIFY:
    case POST_MODIFY:
      return find_base_term (XEXP (x, 0));

    case ZERO_EXTEND:
    case SIGN_EXTEND:	/* Used for Alpha/NT pointers */
      {
	rtx temp = find_base_term (XEXP (x, 0));

	if (temp != 0 && CONSTANT_P (temp))
	  temp = convert_memory_address (Pmode, temp);

	return temp;
      }

    case VALUE:
      val = CSELIB_VAL_PTR (x);
      if (!val)
	return 0;
      for (l = val->locs; l; l = l->next)
	if ((x = find_base_term (l->loc)) != 0)
	  return x;
      return 0;

    case CONST:
      x = XEXP (x, 0);
      if (GET_CODE (x) != PLUS && GET_CODE (x) != MINUS)
	return 0;
      /* Fall through.  */
    case LO_SUM:
    case PLUS:
    case MINUS:
      {
	rtx tmp1 = XEXP (x, 0);
	rtx tmp2 = XEXP (x, 1);

	/* This is a little bit tricky since we have to determine which of
	   the two operands represents the real base address.  Otherwise this
	   routine may return the index register instead of the base register.

	   That may cause us to believe no aliasing was possible, when in
	   fact aliasing is possible.

	   We use a few simple tests to guess the base register.  Additional
	   tests can certainly be added.  For example, if one of the operands
	   is a shift or multiply, then it must be the index register and the
	   other operand is the base register.  */

	if (tmp1 == pic_offset_table_rtx && CONSTANT_P (tmp2))
	  return find_base_term (tmp2);

	/* If either operand is known to be a pointer, then use it
	   to determine the base term.  */
	if (REG_P (tmp1) && REG_POINTER (tmp1))
	  return find_base_term (tmp1);

	if (REG_P (tmp2) && REG_POINTER (tmp2))
	  return find_base_term (tmp2);

	/* Neither operand was known to be a pointer.  Go ahead and find the
	   base term for both operands.  */
	tmp1 = find_base_term (tmp1);
	tmp2 = find_base_term (tmp2);

	/* If either base term is named object or a special address
	   (like an argument or stack reference), then use it for the
	   base term.  */
	if (tmp1 != 0
	    && (GET_CODE (tmp1) == SYMBOL_REF
		|| GET_CODE (tmp1) == LABEL_REF
		|| (GET_CODE (tmp1) == ADDRESS
		    && GET_MODE (tmp1) != VOIDmode)))
	  return tmp1;

	if (tmp2 != 0
	    && (GET_CODE (tmp2) == SYMBOL_REF
		|| GET_CODE (tmp2) == LABEL_REF
		|| (GET_CODE (tmp2) == ADDRESS
		    && GET_MODE (tmp2) != VOIDmode)))
	  return tmp2;

	/* We could not determine which of the two operands was the
	   base register and which was the index.  So we can determine
	   nothing from the base alias check.  */
	return 0;
      }

    case AND:
      if (GET_CODE (XEXP (x, 1)) == CONST_INT && INTVAL (XEXP (x, 1)) != 0)
	return find_base_term (XEXP (x, 0));
      return 0;

    case SYMBOL_REF:
    case LABEL_REF:
      return x;

    case ADDRESSOF:
      return REG_BASE_VALUE (frame_pointer_rtx);

    default:
      return 0;
    }
}

/* Return 0 if the addresses X and Y are known to point to different
   objects, 1 if they might be pointers to the same object.  */

static int
base_alias_check (rtx x, rtx y, enum machine_mode x_mode,
		  enum machine_mode y_mode)
{
  rtx x_base = find_base_term (x);
  rtx y_base = find_base_term (y);

  /* If the address itself has no known base see if a known equivalent
     value has one.  If either address still has no known base, nothing
     is known about aliasing.  */
  if (x_base == 0)
    {
      rtx x_c;

      if (! flag_expensive_optimizations || (x_c = canon_rtx (x)) == x)
	return 1;

      x_base = find_base_term (x_c);
      if (x_base == 0)
	return 1;
    }

  if (y_base == 0)
    {
      rtx y_c;
      if (! flag_expensive_optimizations || (y_c = canon_rtx (y)) == y)
	return 1;

      y_base = find_base_term (y_c);
      if (y_base == 0)
	return 1;
    }

  /* If the base addresses are equal nothing is known about aliasing.  */
  if (rtx_equal_p (x_base, y_base))
    return 1;

  /* The base addresses of the read and write are different expressions.
     If they are both symbols and they are not accessed via AND, there is
     no conflict.  We can bring knowledge of object alignment into play
     here.  For example, on alpha, "char a, b;" can alias one another,
     though "char a; long b;" cannot.  */
  if (GET_CODE (x_base) != ADDRESS && GET_CODE (y_base) != ADDRESS)
    {
      if (GET_CODE (x) == AND && GET_CODE (y) == AND)
	return 1;
      if (GET_CODE (x) == AND
	  && (GET_CODE (XEXP (x, 1)) != CONST_INT
	      || (int) GET_MODE_UNIT_SIZE (y_mode) < -INTVAL (XEXP (x, 1))))
	return 1;
      if (GET_CODE (y) == AND
	  && (GET_CODE (XEXP (y, 1)) != CONST_INT
	      || (int) GET_MODE_UNIT_SIZE (x_mode) < -INTVAL (XEXP (y, 1))))
	return 1;
      /* Differing symbols never alias.  */
      return 0;
    }

  /* If one address is a stack reference there can be no alias:
     stack references using different base registers do not alias,
     a stack reference can not alias a parameter, and a stack reference
     can not alias a global.  */
  if ((GET_CODE (x_base) == ADDRESS && GET_MODE (x_base) == Pmode)
      || (GET_CODE (y_base) == ADDRESS && GET_MODE (y_base) == Pmode))
    return 0;

  if (! flag_argument_noalias)
    return 1;

  if (flag_argument_noalias > 1)
    return 0;

  /* Weak noalias assertion (arguments are distinct, but may match globals).  */
  return ! (GET_MODE (x_base) == VOIDmode && GET_MODE (y_base) == VOIDmode);
}

/* Convert the address X into something we can use.  This is done by returning
   it unchanged unless it is a value; in the latter case we call cselib to get
   a more useful rtx.  */

rtx
get_addr (rtx x)
{
  cselib_val *v;
  struct elt_loc_list *l;

  if (GET_CODE (x) != VALUE)
    return x;
  v = CSELIB_VAL_PTR (x);
  if (v)
    {
      for (l = v->locs; l; l = l->next)
	if (CONSTANT_P (l->loc))
	  return l->loc;
      for (l = v->locs; l; l = l->next)
	if (GET_CODE (l->loc) != REG && GET_CODE (l->loc) != MEM)
	  return l->loc;
      if (v->locs)
	return v->locs->loc;
    }
  return x;
}

/*  Return the address of the (N_REFS + 1)th memory reference to ADDR
    where SIZE is the size in bytes of the memory reference.  If ADDR
    is not modified by the memory reference then ADDR is returned.  */

rtx
addr_side_effect_eval (rtx addr, int size, int n_refs)
{
  int offset = 0;

  switch (GET_CODE (addr))
    {
    case PRE_INC:
      offset = (n_refs + 1) * size;
      break;
    case PRE_DEC:
      offset = -(n_refs + 1) * size;
      break;
    case POST_INC:
      offset = n_refs * size;
      break;
    case POST_DEC:
      offset = -n_refs * size;
      break;

    default:
      return addr;
    }

  if (offset)
    addr = gen_rtx_PLUS (GET_MODE (addr), XEXP (addr, 0),
		         GEN_INT (offset));
  else
    addr = XEXP (addr, 0);
  addr = canon_rtx (addr);

  return addr;
}

/* Return nonzero if X and Y (memory addresses) could reference the
   same location in memory.  C is an offset accumulator.  When
   C is nonzero, we are testing aliases between X and Y + C.
   XSIZE is the size in bytes of the X reference,
   similarly YSIZE is the size in bytes for Y.
   Expect that canon_rtx has been already called for X and Y.

   If XSIZE or YSIZE is zero, we do not know the amount of memory being
   referenced (the reference was BLKmode), so make the most pessimistic
   assumptions.

   If XSIZE or YSIZE is negative, we may access memory outside the object
   being referenced as a side effect.  This can happen when using AND to
   align memory references, as is done on the Alpha.

   Nice to notice that varying addresses cannot conflict with fp if no
   local variables had their addresses taken, but that's too hard now.  */

static int
memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c)
{
  if (GET_CODE (x) == VALUE)
    x = get_addr (x);
  if (GET_CODE (y) == VALUE)
    y = get_addr (y);
  if (GET_CODE (x) == HIGH)
    x = XEXP (x, 0);
  else if (GET_CODE (x) == LO_SUM)
    x = XEXP (x, 1);
  else
    x = addr_side_effect_eval (x, xsize, 0);
  if (GET_CODE (y) == HIGH)
    y = XEXP (y, 0);
  else if (GET_CODE (y) == LO_SUM)
    y = XEXP (y, 1);
  else
    y = addr_side_effect_eval (y, ysize, 0);

  if (rtx_equal_for_memref_p (x, y))
    {
      if (xsize <= 0 || ysize <= 0)
	return 1;
      if (c >= 0 && xsize > c)
	return 1;
      if (c < 0 && ysize+c > 0)
	return 1;
      return 0;
    }

  /* This code used to check for conflicts involving stack references and
     globals but the base address alias code now handles these cases.  */

  if (GET_CODE (x) == PLUS)
    {
      /* The fact that X is canonicalized means that this
	 PLUS rtx is canonicalized.  */
      rtx x0 = XEXP (x, 0);
      rtx x1 = XEXP (x, 1);

      if (GET_CODE (y) == PLUS)
	{
	  /* The fact that Y is canonicalized means that this
	     PLUS rtx is canonicalized.  */
	  rtx y0 = XEXP (y, 0);
	  rtx y1 = XEXP (y, 1);

	  if (rtx_equal_for_memref_p (x1, y1))
	    return memrefs_conflict_p (xsize, x0, ysize, y0, c);
	  if (rtx_equal_for_memref_p (x0, y0))
	    return memrefs_conflict_p (xsize, x1, ysize, y1, c);
	  if (GET_CODE (x1) == CONST_INT)
	    {
	      if (GET_CODE (y1) == CONST_INT)
		return memrefs_conflict_p (xsize, x0, ysize, y0,
					   c - INTVAL (x1) + INTVAL (y1));
	      else
		return memrefs_conflict_p (xsize, x0, ysize, y,
					   c - INTVAL (x1));
	    }
	  else if (GET_CODE (y1) == CONST_INT)
	    return memrefs_conflict_p (xsize, x, ysize, y0, c + INTVAL (y1));

	  return 1;
	}
      else if (GET_CODE (x1) == CONST_INT)
	return memrefs_conflict_p (xsize, x0, ysize, y, c - INTVAL (x1));
    }
  else if (GET_CODE (y) == PLUS)
    {
      /* The fact that Y is canonicalized means that this
	 PLUS rtx is canonicalized.  */
      rtx y0 = XEXP (y, 0);
      rtx y1 = XEXP (y, 1);

      if (GET_CODE (y1) == CONST_INT)
	return memrefs_conflict_p (xsize, x, ysize, y0, c + INTVAL (y1));
      else
	return 1;
    }

  if (GET_CODE (x) == GET_CODE (y))
    switch (GET_CODE (x))
      {
      case MULT:
	{
	  /* Handle cases where we expect the second operands to be the
	     same, and check only whether the first operand would conflict
	     or not.  */
	  rtx x0, y0;
	  rtx x1 = canon_rtx (XEXP (x, 1));
	  rtx y1 = canon_rtx (XEXP (y, 1));
	  if (! rtx_equal_for_memref_p (x1, y1))
	    return 1;
	  x0 = canon_rtx (XEXP (x, 0));
	  y0 = canon_rtx (XEXP (y, 0));
	  if (rtx_equal_for_memref_p (x0, y0))
	    return (xsize == 0 || ysize == 0
		    || (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0));

	  /* Can't properly adjust our sizes.  */
	  if (GET_CODE (x1) != CONST_INT)
	    return 1;
	  xsize /= INTVAL (x1);
	  ysize /= INTVAL (x1);
	  c /= INTVAL (x1);
	  return memrefs_conflict_p (xsize, x0, ysize, y0, c);
	}

      case REG:
	/* Are these registers known not to be equal?  */
	if (alias_invariant)
	  {
	    unsigned int r_x = REGNO (x), r_y = REGNO (y);
	    rtx i_x, i_y;	/* invariant relationships of X and Y */

	    i_x = r_x >= alias_invariant_size ? 0 : alias_invariant[r_x];
	    i_y = r_y >= alias_invariant_size ? 0 : alias_invariant[r_y];

	    if (i_x == 0 && i_y == 0)
	      break;

	    if (! memrefs_conflict_p (xsize, i_x ? i_x : x,
				      ysize, i_y ? i_y : y, c))
	      return 0;
	  }
	break;

      default:
	break;
      }

  /* Treat an access through an AND (e.g. a subword access on an Alpha)
     as an access with indeterminate size.  Assume that references
     besides AND are aligned, so if the size of the other reference is
     at least as large as the alignment, assume no other overlap.  */
  if (GET_CODE (x) == AND && GET_CODE (XEXP (x, 1)) == CONST_INT)
    {
      if (GET_CODE (y) == AND || ysize < -INTVAL (XEXP (x, 1)))
	xsize = -1;
      return memrefs_conflict_p (xsize, canon_rtx (XEXP (x, 0)), ysize, y, c);
    }
  if (GET_CODE (y) == AND && GET_CODE (XEXP (y, 1)) == CONST_INT)
    {
      /* ??? If we are indexing far enough into the array/structure, we
	 may yet be able to determine that we can not overlap.  But we
	 also need to that we are far enough from the end not to overlap
	 a following reference, so we do nothing with that for now.  */
      if (GET_CODE (x) == AND || xsize < -INTVAL (XEXP (y, 1)))
	ysize = -1;
      return memrefs_conflict_p (xsize, x, ysize, canon_rtx (XEXP (y, 0)), c);
    }

  if (GET_CODE (x) == ADDRESSOF)
    {
      if (y == frame_pointer_rtx
	  || GET_CODE (y) == ADDRESSOF)
	return xsize <= 0 || ysize <= 0;
    }
  if (GET_CODE (y) == ADDRESSOF)
    {
      if (x == frame_pointer_rtx)
	return xsize <= 0 || ysize <= 0;
    }

  if (CONSTANT_P (x))
    {
      if (GET_CODE (x) == CONST_INT && GET_CODE (y) == CONST_INT)
	{
	  c += (INTVAL (y) - INTVAL (x));
	  return (xsize <= 0 || ysize <= 0
		  || (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0));
	}

      if (GET_CODE (x) == CONST)
	{
	  if (GET_CODE (y) == CONST)
	    return memrefs_conflict_p (xsize, canon_rtx (XEXP (x, 0)),
				       ysize, canon_rtx (XEXP (y, 0)), c);
	  else
	    return memrefs_conflict_p (xsize, canon_rtx (XEXP (x, 0)),
				       ysize, y, c);
	}
      if (GET_CODE (y) == CONST)
	return memrefs_conflict_p (xsize, x, ysize,
				   canon_rtx (XEXP (y, 0)), c);

      if (CONSTANT_P (y))
	return (xsize <= 0 || ysize <= 0
		|| (rtx_equal_for_memref_p (x, y)
		    && ((c >= 0 && xsize > c) || (c < 0 && ysize+c > 0))));

      return 1;
    }
  return 1;
}

/* Functions to compute memory dependencies.

   Since we process the insns in execution order, we can build tables
   to keep track of what registers are fixed (and not aliased), what registers
   are varying in known ways, and what registers are varying in unknown
   ways.

   If both memory references are volatile, then there must always be a
   dependence between the two references, since their order can not be
   changed.  A volatile and non-volatile reference can be interchanged
   though.

   A MEM_IN_STRUCT reference at a non-AND varying address can never
   conflict with a non-MEM_IN_STRUCT reference at a fixed address.  We
   also must allow AND addresses, because they may generate accesses
   outside the object being referenced.  This is used to generate
   aligned addresses from unaligned addresses, for instance, the alpha
   storeqi_unaligned pattern.  */

/* Read dependence: X is read after read in MEM takes place.  There can
   only be a dependence here if both reads are volatile.  */

int
read_dependence (rtx mem, rtx x)
{
  return MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem);
}

/* Returns MEM1 if and only if MEM1 is a scalar at a fixed address and
   MEM2 is a reference to a structure at a varying address, or returns
   MEM2 if vice versa.  Otherwise, returns NULL_RTX.  If a non-NULL
   value is returned MEM1 and MEM2 can never alias.  VARIES_P is used
   to decide whether or not an address may vary; it should return
   nonzero whenever variation is possible.
   MEM1_ADDR and MEM2_ADDR are the addresses of MEM1 and MEM2.  */

static rtx
fixed_scalar_and_varying_struct_p (rtx mem1, rtx mem2, rtx mem1_addr,
				   rtx mem2_addr,
				   int (*varies_p) (rtx, int))
{
  if (! flag_strict_aliasing)
    return NULL_RTX;

  if (MEM_SCALAR_P (mem1) && MEM_IN_STRUCT_P (mem2)
      && !varies_p (mem1_addr, 1) && varies_p (mem2_addr, 1))
    /* MEM1 is a scalar at a fixed address; MEM2 is a struct at a
       varying address.  */
    return mem1;

  if (MEM_IN_STRUCT_P (mem1) && MEM_SCALAR_P (mem2)
      && varies_p (mem1_addr, 1) && !varies_p (mem2_addr, 1))
    /* MEM2 is a scalar at a fixed address; MEM1 is a struct at a
       varying address.  */
    return mem2;

  return NULL_RTX;
}

/* Returns nonzero if something about the mode or address format MEM1
   indicates that it might well alias *anything*.  */

static int
aliases_everything_p (rtx mem)
{
  if (GET_CODE (XEXP (mem, 0)) == AND)
    /* If the address is an AND, its very hard to know at what it is
       actually pointing.  */
    return 1;

  return 0;
}

/* Return true if we can determine that the fields referenced cannot
   overlap for any pair of objects.  */

static bool
nonoverlapping_component_refs_p (tree x, tree y)
{
  tree fieldx, fieldy, typex, typey, orig_y;

  do
    {
      /* The comparison has to be done at a common type, since we don't
	 know how the inheritance hierarchy works.  */
      orig_y = y;
      do
	{
	  fieldx = TREE_OPERAND (x, 1);
	  typex = DECL_FIELD_CONTEXT (fieldx);

	  y = orig_y;
	  do
	    {
	      fieldy = TREE_OPERAND (y, 1);
	      typey = DECL_FIELD_CONTEXT (fieldy);

	      if (typex == typey)
		goto found;

	      y = TREE_OPERAND (y, 0);
	    }
	  while (y && TREE_CODE (y) == COMPONENT_REF);

	  x = TREE_OPERAND (x, 0);
	}
      while (x && TREE_CODE (x) == COMPONENT_REF);

      /* Never found a common type.  */
      return false;

    found:
      /* If we're left with accessing different fields of a structure,
	 then no overlap.  */
      if (TREE_CODE (typex) == RECORD_TYPE
	  && fieldx != fieldy)
	return true;

      /* The comparison on the current field failed.  If we're accessing
	 a very nested structure, look at the next outer level.  */
      x = TREE_OPERAND (x, 0);
      y = TREE_OPERAND (y, 0);
    }
  while (x && y
	 && TREE_CODE (x) == COMPONENT_REF
	 && TREE_CODE (y) == COMPONENT_REF);

  return false;
}

/* Look at the bottom of the COMPONENT_REF list for a DECL, and return it.  */

static tree
decl_for_component_ref (tree x)
{
  do
    {
      x = TREE_OPERAND (x, 0);
    }
  while (x && TREE_CODE (x) == COMPONENT_REF);

  return x && DECL_P (x) ? x : NULL_TREE;
}

/* Walk up the COMPONENT_REF list and adjust OFFSET to compensate for the
   offset of the field reference.  */

static rtx
adjust_offset_for_component_ref (tree x, rtx offset)
{
  HOST_WIDE_INT ioffset;

  if (! offset)
    return NULL_RTX;

  ioffset = INTVAL (offset);
  do
    {
      tree field = TREE_OPERAND (x, 1);

      if (! host_integerp (DECL_FIELD_OFFSET (field), 1))
	return NULL_RTX;
      ioffset += (tree_low_cst (DECL_FIELD_OFFSET (field), 1)
		  + (tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
		     / BITS_PER_UNIT));

      x = TREE_OPERAND (x, 0);
    }
  while (x && TREE_CODE (x) == COMPONENT_REF);

  return GEN_INT (ioffset);
}

/* Return nonzero if we can determine the exprs corresponding to memrefs
   X and Y and they do not overlap.  */

static int
nonoverlapping_memrefs_p (rtx x, rtx y)
{
  tree exprx = MEM_EXPR (x), expry = MEM_EXPR (y);
  rtx rtlx, rtly;
  rtx basex, basey;
  rtx moffsetx, moffsety;
  HOST_WIDE_INT offsetx = 0, offsety = 0, sizex, sizey, tem;

  /* Unless both have exprs, we can't tell anything.  */
  if (exprx == 0 || expry == 0)
    return 0;

  /* If both are field references, we may be able to determine something.  */
  if (TREE_CODE (exprx) == COMPONENT_REF
      && TREE_CODE (expry) == COMPONENT_REF
      && nonoverlapping_component_refs_p (exprx, expry))
    return 1;

  /* If the field reference test failed, look at the DECLs involved.  */
  moffsetx = MEM_OFFSET (x);
  if (TREE_CODE (exprx) == COMPONENT_REF)
    {
      tree t = decl_for_component_ref (exprx);
      if (! t)
	return 0;
      moffsetx = adjust_offset_for_component_ref (exprx, moffsetx);
      exprx = t;
    }
  else if (TREE_CODE (exprx) == INDIRECT_REF)
    {
      exprx = TREE_OPERAND (exprx, 0);
      if (flag_argument_noalias < 2
	  || TREE_CODE (exprx) != PARM_DECL)
	return 0;
    }

  moffsety = MEM_OFFSET (y);
  if (TREE_CODE (expry) == COMPONENT_REF)
    {
      tree t = decl_for_component_ref (expry);
      if (! t)
	return 0;
      moffsety = adjust_offset_for_component_ref (expry, moffsety);
      expry = t;
    }
  else if (TREE_CODE (expry) == INDIRECT_REF)
    {
      expry = TREE_OPERAND (expry, 0);
      if (flag_argument_noalias < 2
	  || TREE_CODE (expry) != PARM_DECL)
	return 0;
    }

  if (! DECL_P (exprx) || ! DECL_P (expry))
    return 0;

  rtlx = DECL_RTL (exprx);
  rtly = DECL_RTL (expry);

  /* If either RTL is not a MEM, it must be a REG or CONCAT, meaning they
     can't overlap unless they are the same because we never reuse that part
     of the stack frame used for locals for spilled pseudos.  */
  if ((GET_CODE (rtlx) != MEM || GET_CODE (rtly) != MEM)
      && ! rtx_equal_p (rtlx, rtly))
    return 1;

  /* Get the base and offsets of both decls.  If either is a register, we
     know both are and are the same, so use that as the base.  The only
     we can avoid overlap is if we can deduce that they are nonoverlapping
     pieces of that decl, which is very rare.  */
  basex = GET_CODE (rtlx) == MEM ? XEXP (rtlx, 0) : rtlx;
  if (GET_CODE (basex) == PLUS && GET_CODE (XEXP (basex, 1)) == CONST_INT)
    offsetx = INTVAL (XEXP (basex, 1)), basex = XEXP (basex, 0);

  basey = GET_CODE (rtly) == MEM ? XEXP (rtly, 0) : rtly;
  if (GET_CODE (basey) == PLUS && GET_CODE (XEXP (basey, 1)) == CONST_INT)
    offsety = INTVAL (XEXP (basey, 1)), basey = XEXP (basey, 0);

  /* If the bases are different, we know they do not overlap if both
     are constants or if one is a constant and the other a pointer into the
     stack frame.  Otherwise a different base means we can't tell if they
     overlap or not.  */
  if (! rtx_equal_p (basex, basey))
    return ((CONSTANT_P (basex) && CONSTANT_P (basey))
	    || (CONSTANT_P (basex) && REG_P (basey)
		&& REGNO_PTR_FRAME_P (REGNO (basey)))
	    || (CONSTANT_P (basey) && REG_P (basex)
		&& REGNO_PTR_FRAME_P (REGNO (basex))));

  sizex = (GET_CODE (rtlx) != MEM ? (int) GET_MODE_SIZE (GET_MODE (rtlx))
	   : MEM_SIZE (rtlx) ? INTVAL (MEM_SIZE (rtlx))
	   : -1);
  sizey = (GET_CODE (rtly) != MEM ? (int) GET_MODE_SIZE (GET_MODE (rtly))
	   : MEM_SIZE (rtly) ? INTVAL (MEM_SIZE (rtly)) :
	   -1);

  /* If we have an offset for either memref, it can update the values computed
     above.  */
  if (moffsetx)
    offsetx += INTVAL (moffsetx), sizex -= INTVAL (moffsetx);
  if (moffsety)
    offsety += INTVAL (moffsety), sizey -= INTVAL (moffsety);

  /* If a memref has both a size and an offset, we can use the smaller size.
     We can't do this if the offset isn't known because we must view this
     memref as being anywhere inside the DECL's MEM.  */
  if (MEM_SIZE (x) && moffsetx)
    sizex = INTVAL (MEM_SIZE (x));
  if (MEM_SIZE (y) && moffsety)
    sizey = INTVAL (MEM_SIZE (y));

  /* Put the values of the memref with the lower offset in X's values.  */
  if (offsetx > offsety)
    {
      tem = offsetx, offsetx = offsety, offsety = tem;
      tem = sizex, sizex = sizey, sizey = tem;
    }

  /* If we don't know the size of the lower-offset value, we can't tell
     if they conflict.  Otherwise, we do the test.  */
  return sizex >= 0 && offsety >= offsetx + sizex;
}

/* True dependence: X is read after store in MEM takes place.  */

int
true_dependence (rtx mem, enum machine_mode mem_mode, rtx x,
		 int (*varies) (rtx, int))
{
  rtx x_addr, mem_addr;
  rtx base;

  if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem))
    return 1;

  /* (mem:BLK (scratch)) is a special mechanism to conflict with everything.
     This is used in epilogue deallocation functions.  */
  if (GET_MODE (x) == BLKmode && GET_CODE (XEXP (x, 0)) == SCRATCH)
    return 1;
  if (GET_MODE (mem) == BLKmode && GET_CODE (XEXP (mem, 0)) == SCRATCH)
    return 1;

  if (DIFFERENT_ALIAS_SETS_P (x, mem))
    return 0;

  /* Unchanging memory can't conflict with non-unchanging memory.
     A non-unchanging read can conflict with a non-unchanging write.
     An unchanging read can conflict with an unchanging write since
     there may be a single store to this address to initialize it.
     Note that an unchanging store can conflict with a non-unchanging read
     since we have to make conservative assumptions when we have a
     record with readonly fields and we are copying the whole thing.
     Just fall through to the code below to resolve potential conflicts.
     This won't handle all cases optimally, but the possible performance
     loss should be negligible.  */
  if (RTX_UNCHANGING_P (x) && ! RTX_UNCHANGING_P (mem))
    return 0;

  if (nonoverlapping_memrefs_p (mem, x))
    return 0;

  if (mem_mode == VOIDmode)
    mem_mode = GET_MODE (mem);

  x_addr = get_addr (XEXP (x, 0));
  mem_addr = get_addr (XEXP (mem, 0));

  base = find_base_term (x_addr);
  if (base && (GET_CODE (base) == LABEL_REF
	       || (GET_CODE (base) == SYMBOL_REF
		   && CONSTANT_POOL_ADDRESS_P (base))))
    return 0;

  if (! base_alias_check (x_addr, mem_addr, GET_MODE (x), mem_mode))
    return 0;

  x_addr = canon_rtx (x_addr);
  mem_addr = canon_rtx (mem_addr);

  if (! memrefs_conflict_p (GET_MODE_SIZE (mem_mode), mem_addr,
			    SIZE_FOR_MODE (x), x_addr, 0))
    return 0;

  if (aliases_everything_p (x))
    return 1;

  /* We cannot use aliases_everything_p to test MEM, since we must look
     at MEM_MODE, rather than GET_MODE (MEM).  */
  if (mem_mode == QImode || GET_CODE (mem_addr) == AND)
    return 1;

  /* In true_dependence we also allow BLKmode to alias anything.  Why
     don't we do this in anti_dependence and output_dependence?  */
  if (mem_mode == BLKmode || GET_MODE (x) == BLKmode)
    return 1;

  return ! fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr,
					      varies);
}

/* Canonical true dependence: X is read after store in MEM takes place.
   Variant of true_dependence which assumes MEM has already been
   canonicalized (hence we no longer do that here).
   The mem_addr argument has been added, since true_dependence computed
   this value prior to canonicalizing.  */

int
canon_true_dependence (rtx mem, enum machine_mode mem_mode, rtx mem_addr,
		       rtx x, int (*varies) (rtx, int))
{
  rtx x_addr;

  if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem))
    return 1;

  /* (mem:BLK (scratch)) is a special mechanism to conflict with everything.
     This is used in epilogue deallocation functions.  */
  if (GET_MODE (x) == BLKmode && GET_CODE (XEXP (x, 0)) == SCRATCH)
    return 1;
  if (GET_MODE (mem) == BLKmode && GET_CODE (XEXP (mem, 0)) == SCRATCH)
    return 1;

  if (DIFFERENT_ALIAS_SETS_P (x, mem))
    return 0;

  /* If X is an unchanging read, then it can't possibly conflict with any
     non-unchanging store.  It may conflict with an unchanging write though,
     because there may be a single store to this address to initialize it.
     Just fall through to the code below to resolve the case where we have
     both an unchanging read and an unchanging write.  This won't handle all
     cases optimally, but the possible performance loss should be
     negligible.  */
  if (RTX_UNCHANGING_P (x) && ! RTX_UNCHANGING_P (mem))
    return 0;

  if (nonoverlapping_memrefs_p (x, mem))
    return 0;

  x_addr = get_addr (XEXP (x, 0));

  if (! base_alias_check (x_addr, mem_addr, GET_MODE (x), mem_mode))
    return 0;

  x_addr = canon_rtx (x_addr);
  if (! memrefs_conflict_p (GET_MODE_SIZE (mem_mode), mem_addr,
			    SIZE_FOR_MODE (x), x_addr, 0))
    return 0;

  if (aliases_everything_p (x))
    return 1;

  /* We cannot use aliases_everything_p to test MEM, since we must look
     at MEM_MODE, rather than GET_MODE (MEM).  */
  if (mem_mode == QImode || GET_CODE (mem_addr) == AND)
    return 1;

  /* In true_dependence we also allow BLKmode to alias anything.  Why
     don't we do this in anti_dependence and output_dependence?  */
  if (mem_mode == BLKmode || GET_MODE (x) == BLKmode)
    return 1;

  return ! fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr,
					      varies);
}

/* Returns nonzero if a write to X might alias a previous read from
   (or, if WRITEP is nonzero, a write to) MEM.  If CONSTP is nonzero,
   honor the RTX_UNCHANGING_P flags on X and MEM.  */

static int
write_dependence_p (rtx mem, rtx x, int writep, int constp)
{
  rtx x_addr, mem_addr;
  rtx fixed_scalar;
  rtx base;

  if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem))
    return 1;

  /* (mem:BLK (scratch)) is a special mechanism to conflict with everything.
     This is used in epilogue deallocation functions.  */
  if (GET_MODE (x) == BLKmode && GET_CODE (XEXP (x, 0)) == SCRATCH)
    return 1;
  if (GET_MODE (mem) == BLKmode && GET_CODE (XEXP (mem, 0)) == SCRATCH)
    return 1;

  if (DIFFERENT_ALIAS_SETS_P (x, mem))
    return 0;

  if (constp)
    {
      /* Unchanging memory can't conflict with non-unchanging memory.  */
      if (RTX_UNCHANGING_P (x) != RTX_UNCHANGING_P (mem))
	return 0;

      /* If MEM is an unchanging read, then it can't possibly conflict with
	 the store to X, because there is at most one store to MEM, and it
	 must have occurred somewhere before MEM.  */
      if (! writep && RTX_UNCHANGING_P (mem))
	return 0;
    }

  if (nonoverlapping_memrefs_p (x, mem))
    return 0;

  x_addr = get_addr (XEXP (x, 0));
  mem_addr = get_addr (XEXP (mem, 0));

  if (! writep)
    {
      base = find_base_term (mem_addr);
      if (base && (GET_CODE (base) == LABEL_REF
		   || (GET_CODE (base) == SYMBOL_REF
		       && CONSTANT_POOL_ADDRESS_P (base))))
	return 0;
    }

  if (! base_alias_check (x_addr, mem_addr, GET_MODE (x),
			  GET_MODE (mem)))
    return 0;

  x_addr = canon_rtx (x_addr);
  mem_addr = canon_rtx (mem_addr);

  if (!memrefs_conflict_p (SIZE_FOR_MODE (mem), mem_addr,
			   SIZE_FOR_MODE (x), x_addr, 0))
    return 0;

  fixed_scalar
    = fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr,
					 rtx_addr_varies_p);

  return (!(fixed_scalar == mem && !aliases_everything_p (x))
	  && !(fixed_scalar == x && !aliases_everything_p (mem)));
}

/* Anti dependence: X is written after read in MEM takes place.  */

int
anti_dependence (rtx mem, rtx x)
{
  return write_dependence_p (mem, x, /*writep=*/0, /*constp*/1);
}

/* Output dependence: X is written after store in MEM takes place.  */

int
output_dependence (rtx mem, rtx x)
{
  return write_dependence_p (mem, x, /*writep=*/1, /*constp*/1);
}

/* Unchanging anti dependence: Like anti_dependence but ignores
   the UNCHANGING_RTX_P property on const variable references.  */

int
unchanging_anti_dependence (rtx mem, rtx x)
{
  return write_dependence_p (mem, x, /*writep=*/0, /*constp*/0);
}

/* A subroutine of nonlocal_mentioned_p, returns 1 if *LOC mentions
   something which is not local to the function and is not constant.  */

static int
nonlocal_mentioned_p_1 (rtx *loc, void *data ATTRIBUTE_UNUSED)
{
  rtx x = *loc;
  rtx base;
  int regno;

  if (! x)
    return 0;

  switch (GET_CODE (x))
    {
    case SUBREG:
      if (GET_CODE (SUBREG_REG (x)) == REG)
	{
	  /* Global registers are not local.  */
	  if (REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER
	      && global_regs[subreg_regno (x)])
	    return 1;
	  return 0;
	}
      break;

    case REG:
      regno = REGNO (x);
      /* Global registers are not local.  */
      if (regno < FIRST_PSEUDO_REGISTER && global_regs[regno])
	return 1;
      return 0;

    case SCRATCH:
    case PC:
    case CC0:
    case CONST_INT:
    case CONST_DOUBLE:
    case CONST_VECTOR:
    case CONST:
    case LABEL_REF:
      return 0;

    case SYMBOL_REF:
      /* Constants in the function's constants pool are constant.  */
      if (CONSTANT_POOL_ADDRESS_P (x))
	return 0;
      return 1;

    case CALL:
      /* Non-constant calls and recursion are not local.  */
      return 1;

    case MEM:
      /* Be overly conservative and consider any volatile memory
	 reference as not local.  */
      if (MEM_VOLATILE_P (x))
	return 1;
      base = find_base_term (XEXP (x, 0));
      if (base)
	{
	  /* A Pmode ADDRESS could be a reference via the structure value
	     address or static chain.  Such memory references are nonlocal.

	     Thus, we have to examine the contents of the ADDRESS to find
	     out if this is a local reference or not.  */
	  if (GET_CODE (base) == ADDRESS
	      && GET_MODE (base) == Pmode
	      && (XEXP (base, 0) == stack_pointer_rtx
		  || XEXP (base, 0) == arg_pointer_rtx
#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
		  || XEXP (base, 0) == hard_frame_pointer_rtx
#endif
		  || XEXP (base, 0) == frame_pointer_rtx))
	    return 0;
	  /* Constants in the function's constant pool are constant.  */
	  if (GET_CODE (base) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (base))
	    return 0;
	}
      return 1;

    case UNSPEC_VOLATILE:
    case ASM_INPUT:
      return 1;

    case ASM_OPERANDS:
      if (MEM_VOLATILE_P (x))
	return 1;

    /* Fall through.  */

    default:
      break;
    }

  return 0;
}

/* Returns nonzero if X might mention something which is not
   local to the function and is not constant.  */

static int
nonlocal_mentioned_p (rtx x)
{
  if (INSN_P (x))
    {
      if (GET_CODE (x) == CALL_INSN)
	{
	  if (! CONST_OR_PURE_CALL_P (x))
	    return 1;
	  x = CALL_INSN_FUNCTION_USAGE (x);
	  if (x == 0)
	    return 0;
	}
      else
	x = PATTERN (x);
    }

  return for_each_rtx (&x, nonlocal_mentioned_p_1, NULL);
}

/* A subroutine of nonlocal_referenced_p, returns 1 if *LOC references
   something which is not local to the function and is not constant.  */

static int
nonlocal_referenced_p_1 (rtx *loc, void *data ATTRIBUTE_UNUSED)
{
  rtx x = *loc;

  if (! x)
    return 0;

  switch (GET_CODE (x))
    {
    case MEM:
    case REG:
    case SYMBOL_REF:
    case SUBREG:
      return nonlocal_mentioned_p (x);

    case CALL:
      /* Non-constant calls and recursion are not local.  */
      return 1;

    case SET:
      if (nonlocal_mentioned_p (SET_SRC (x)))
	return 1;

      if (GET_CODE (SET_DEST (x)) == MEM)
	return nonlocal_mentioned_p (XEXP (SET_DEST (x), 0));

      /* If the destination is anything other than a CC0, PC,
	 MEM, REG, or a SUBREG of a REG that occupies all of
	 the REG, then X references nonlocal memory if it is
	 mentioned in the destination.  */
      if (GET_CODE (SET_DEST (x)) != CC0
	  && GET_CODE (SET_DEST (x)) != PC
	  && GET_CODE (SET_DEST (x)) != REG
	  && ! (GET_CODE (SET_DEST (x)) == SUBREG
		&& GET_CODE (SUBREG_REG (SET_DEST (x))) == REG
		&& (((GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_DEST (x))))
		      + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
		    == ((GET_MODE_SIZE (GET_MODE (SET_DEST (x)))
			 + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD))))
	return nonlocal_mentioned_p (SET_DEST (x));
      return 0;

    case CLOBBER:
      if (GET_CODE (XEXP (x, 0)) == MEM)
	return nonlocal_mentioned_p (XEXP (XEXP (x, 0), 0));
      return 0;

    case USE:
      return nonlocal_mentioned_p (XEXP (x, 0));

    case ASM_INPUT:
    case UNSPEC_VOLATILE:
      return 1;

    case ASM_OPERANDS:
      if (MEM_VOLATILE_P (x))
	return 1;

    /* Fall through.  */

    default:
      break;
    }

  return 0;
}

/* Returns nonzero if X might reference something which is not
   local to the function and is not constant.  */

static int
nonlocal_referenced_p (rtx x)
{
  if (INSN_P (x))
    {
      if (GET_CODE (x) == CALL_INSN)
	{
	  if (! CONST_OR_PURE_CALL_P (x))
	    return 1;
	  x = CALL_INSN_FUNCTION_USAGE (x);
	  if (x == 0)
	    return 0;
	}
      else
	x = PATTERN (x);
    }

  return for_each_rtx (&x, nonlocal_referenced_p_1, NULL);
}

/* A subroutine of nonlocal_set_p, returns 1 if *LOC sets
   something which is not local to the function and is not constant.  */

static int
nonlocal_set_p_1 (rtx *loc, void *data ATTRIBUTE_UNUSED)
{
  rtx x = *loc;

  if (! x)
    return 0;

  switch (GET_CODE (x))
    {
    case CALL:
      /* Non-constant calls and recursion are not local.  */
      return 1;

    case PRE_INC:
    case PRE_DEC:
    case POST_INC:
    case POST_DEC:
    case PRE_MODIFY:
    case POST_MODIFY:
      return nonlocal_mentioned_p (XEXP (x, 0));

    case SET:
      if (nonlocal_mentioned_p (SET_DEST (x)))
	return 1;
      return nonlocal_set_p (SET_SRC (x));

    case CLOBBER:
      return nonlocal_mentioned_p (XEXP (x, 0));

    case USE:
      return 0;

    case ASM_INPUT:
    case UNSPEC_VOLATILE:
      return 1;

    case ASM_OPERANDS:
      if (MEM_VOLATILE_P (x))
	return 1;

    /* Fall through.  */

    default:
      break;
    }

  return 0;
}

/* Returns nonzero if X might set something which is not
   local to the function and is not constant.  */

static int
nonlocal_set_p (rtx x)
{
  if (INSN_P (x))
    {
      if (GET_CODE (x) == CALL_INSN)
	{
	  if (! CONST_OR_PURE_CALL_P (x))
	    return 1;
	  x = CALL_INSN_FUNCTION_USAGE (x);
	  if (x == 0)
	    return 0;
	}
      else
	x = PATTERN (x);
    }

  return for_each_rtx (&x, nonlocal_set_p_1, NULL);
}

/* Mark the function if it is pure or constant.  */

void
mark_constant_function (void)
{
  rtx insn;
  int nonlocal_memory_referenced;

  if (TREE_READONLY (current_function_decl)
      || DECL_IS_PURE (current_function_decl)
      || TREE_THIS_VOLATILE (current_function_decl)
      || current_function_has_nonlocal_goto
      || !(*targetm.binds_local_p) (current_function_decl))
    return;

  /* A loop might not return which counts as a side effect.  */
  if (mark_dfs_back_edges ())
    return;

  nonlocal_memory_referenced = 0;

  init_alias_analysis ();

  /* Determine if this is a constant or pure function.  */

  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
    {
      if (! INSN_P (insn))
	continue;

      if (nonlocal_set_p (insn) || global_reg_mentioned_p (insn)
	  || volatile_refs_p (PATTERN (insn)))
	break;

      if (! nonlocal_memory_referenced)
	nonlocal_memory_referenced = nonlocal_referenced_p (insn);
    }

  end_alias_analysis ();

  /* Mark the function.  */

  if (insn)
    ;
  else if (nonlocal_memory_referenced)
    {
      cgraph_rtl_info (current_function_decl)->pure_function = 1;
      DECL_IS_PURE (current_function_decl) = 1;
    }
  else
    {
      cgraph_rtl_info (current_function_decl)->const_function = 1;
      TREE_READONLY (current_function_decl) = 1;
    }
}


void
init_alias_once (void)
{
  int i;

#ifndef OUTGOING_REGNO
#define OUTGOING_REGNO(N) N
#endif
  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    /* Check whether this register can hold an incoming pointer
       argument.  FUNCTION_ARG_REGNO_P tests outgoing register
       numbers, so translate if necessary due to register windows.  */
    if (FUNCTION_ARG_REGNO_P (OUTGOING_REGNO (i))
	&& HARD_REGNO_MODE_OK (i, Pmode))
      static_reg_base_value[i]
	= gen_rtx_ADDRESS (VOIDmode, gen_rtx_REG (Pmode, i));

  static_reg_base_value[STACK_POINTER_REGNUM]
    = gen_rtx_ADDRESS (Pmode, stack_pointer_rtx);
  static_reg_base_value[ARG_POINTER_REGNUM]
    = gen_rtx_ADDRESS (Pmode, arg_pointer_rtx);
  static_reg_base_value[FRAME_POINTER_REGNUM]
    = gen_rtx_ADDRESS (Pmode, frame_pointer_rtx);
#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
  static_reg_base_value[HARD_FRAME_POINTER_REGNUM]
    = gen_rtx_ADDRESS (Pmode, hard_frame_pointer_rtx);
#endif
}

/* Set MEMORY_MODIFIED when X modifies DATA (that is assumed
   to be memory reference.  */
static bool memory_modified;
static void
memory_modified_1 (rtx x, rtx pat ATTRIBUTE_UNUSED, void *data)
{
  if (GET_CODE (x) == MEM)
    {
      if (anti_dependence (x, (rtx)data) || output_dependence (x, (rtx)data))
	memory_modified = true;
    }
}


/* Return true when INSN possibly modify memory contents of MEM
   (ie address can be modified).  */
bool
memory_modified_in_insn_p (rtx mem, rtx insn)
{
  if (!INSN_P (insn))
    return false;
  memory_modified = false;
  note_stores (PATTERN (insn), memory_modified_1, mem);
  return memory_modified;
}

/* Initialize the aliasing machinery.  Initialize the REG_KNOWN_VALUE
   array.  */

void
init_alias_analysis (void)
{
  unsigned int maxreg = max_reg_num ();
  int changed, pass;
  int i;
  unsigned int ui;
  rtx insn;

  timevar_push (TV_ALIAS_ANALYSIS);

  reg_known_value_size = maxreg;

  reg_known_value
    = (rtx *) xcalloc ((maxreg - FIRST_PSEUDO_REGISTER), sizeof (rtx))
    - FIRST_PSEUDO_REGISTER;
  reg_known_equiv_p
    = (char*) xcalloc ((maxreg - FIRST_PSEUDO_REGISTER), sizeof (char))
    - FIRST_PSEUDO_REGISTER;

  /* Overallocate reg_base_value to allow some growth during loop
     optimization.  Loop unrolling can create a large number of
     registers.  */
  if (old_reg_base_value)
    {
      reg_base_value = old_reg_base_value;
      /* If varray gets large zeroing cost may get important.  */
      if (VARRAY_SIZE (reg_base_value) > 256
          && VARRAY_SIZE (reg_base_value) > 4 * maxreg)
	VARRAY_GROW (reg_base_value, maxreg);
      VARRAY_CLEAR (reg_base_value);
      if (VARRAY_SIZE (reg_base_value) < maxreg)
	VARRAY_GROW (reg_base_value, maxreg);
    }
  else
    {
      VARRAY_RTX_INIT (reg_base_value, maxreg, "reg_base_value");
    }

  new_reg_base_value = xmalloc (maxreg * sizeof (rtx));
  reg_seen = xmalloc (maxreg);
  if (! reload_completed && flag_old_unroll_loops)
    {
      /* ??? Why are we realloc'ing if we're just going to zero it?  */
      alias_invariant = xrealloc (alias_invariant,
				  maxreg * sizeof (rtx));
      memset (alias_invariant, 0, maxreg * sizeof (rtx));
      alias_invariant_size = maxreg;
    }

  /* The basic idea is that each pass through this loop will use the
     "constant" information from the previous pass to propagate alias
     information through another level of assignments.

     This could get expensive if the assignment chains are long.  Maybe
     we should throttle the number of iterations, possibly based on
     the optimization level or flag_expensive_optimizations.

     We could propagate more information in the first pass by making use
     of REG_N_SETS to determine immediately that the alias information
     for a pseudo is "constant".

     A program with an uninitialized variable can cause an infinite loop
     here.  Instead of doing a full dataflow analysis to detect such problems
     we just cap the number of iterations for the loop.

     The state of the arrays for the set chain in question does not matter
     since the program has undefined behavior.  */

  pass = 0;
  do
    {
      /* Assume nothing will change this iteration of the loop.  */
      changed = 0;

      /* We want to assign the same IDs each iteration of this loop, so
	 start counting from zero each iteration of the loop.  */
      unique_id = 0;

      /* We're at the start of the function each iteration through the
	 loop, so we're copying arguments.  */
      copying_arguments = true;

      /* Wipe the potential alias information clean for this pass.  */
      memset (new_reg_base_value, 0, maxreg * sizeof (rtx));

      /* Wipe the reg_seen array clean.  */
      memset (reg_seen, 0, maxreg);

      /* Mark all hard registers which may contain an address.
	 The stack, frame and argument pointers may contain an address.
	 An argument register which can hold a Pmode value may contain
	 an address even if it is not in BASE_REGS.

	 The address expression is VOIDmode for an argument and
	 Pmode for other registers.  */

      memcpy (new_reg_base_value, static_reg_base_value,
	      FIRST_PSEUDO_REGISTER * sizeof (rtx));

      /* Walk the insns adding values to the new_reg_base_value array.  */
      for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
	{
	  if (INSN_P (insn))
	    {
	      rtx note, set;

#if defined (HAVE_prologue) || defined (HAVE_epilogue)
	      /* The prologue/epilogue insns are not threaded onto the
		 insn chain until after reload has completed.  Thus,
		 there is no sense wasting time checking if INSN is in
		 the prologue/epilogue until after reload has completed.  */
	      if (reload_completed
		  && prologue_epilogue_contains (insn))
		continue;
#endif

	      /* If this insn has a noalias note, process it,  Otherwise,
	         scan for sets.  A simple set will have no side effects
	         which could change the base value of any other register.  */

	      if (GET_CODE (PATTERN (insn)) == SET
		  && REG_NOTES (insn) != 0
		  && find_reg_note (insn, REG_NOALIAS, NULL_RTX))
		record_set (SET_DEST (PATTERN (insn)), NULL_RTX, NULL);
	      else
		note_stores (PATTERN (insn), record_set, NULL);

	      set = single_set (insn);

	      if (set != 0
		  && GET_CODE (SET_DEST (set)) == REG
		  && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
		{
		  unsigned int regno = REGNO (SET_DEST (set));
		  rtx src = SET_SRC (set);

		  if (REG_NOTES (insn) != 0
		      && (((note = find_reg_note (insn, REG_EQUAL, 0)) != 0
			   && REG_N_SETS (regno) == 1)
			  || (note = find_reg_note (insn, REG_EQUIV, NULL_RTX)) != 0)
		      && GET_CODE (XEXP (note, 0)) != EXPR_LIST
		      && ! rtx_varies_p (XEXP (note, 0), 1)
		      && ! reg_overlap_mentioned_p (SET_DEST (set), XEXP (note, 0)))
		    {
		      reg_known_value[regno] = XEXP (note, 0);
		      reg_known_equiv_p[regno] = REG_NOTE_KIND (note) == REG_EQUIV;
		    }
		  else if (REG_N_SETS (regno) == 1
			   && GET_CODE (src) == PLUS
			   && GET_CODE (XEXP (src, 0)) == REG
			   && REGNO (XEXP (src, 0)) >= FIRST_PSEUDO_REGISTER
			   && (reg_known_value[REGNO (XEXP (src, 0))])
			   && GET_CODE (XEXP (src, 1)) == CONST_INT)
		    {
		      rtx op0 = XEXP (src, 0);
		      op0 = reg_known_value[REGNO (op0)];
		      reg_known_value[regno]
			= plus_constant (op0, INTVAL (XEXP (src, 1)));
		      reg_known_equiv_p[regno] = 0;
		    }
		  else if (REG_N_SETS (regno) == 1
			   && ! rtx_varies_p (src, 1))
		    {
		      reg_known_value[regno] = src;
		      reg_known_equiv_p[regno] = 0;
		    }
		}
	    }
	  else if (GET_CODE (insn) == NOTE
		   && NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_BEG)
	    copying_arguments = false;
	}

      /* Now propagate values from new_reg_base_value to reg_base_value.  */
      if (maxreg != (unsigned int) max_reg_num())
	abort ();
      for (ui = 0; ui < maxreg; ui++)
	{
	  if (new_reg_base_value[ui]
	      && new_reg_base_value[ui] != VARRAY_RTX (reg_base_value, ui)
	      && ! rtx_equal_p (new_reg_base_value[ui],
				VARRAY_RTX (reg_base_value, ui)))
	    {
	      VARRAY_RTX (reg_base_value, ui) = new_reg_base_value[ui];
	      changed = 1;
	    }
	}
    }
  while (changed && ++pass < MAX_ALIAS_LOOP_PASSES);

  /* Fill in the remaining entries.  */
  for (i = FIRST_PSEUDO_REGISTER; i < (int)maxreg; i++)
    if (reg_known_value[i] == 0)
      reg_known_value[i] = regno_reg_rtx[i];

  /* Simplify the reg_base_value array so that no register refers to
     another register, except to special registers indirectly through
     ADDRESS expressions.

     In theory this loop can take as long as O(registers^2), but unless
     there are very long dependency chains it will run in close to linear
     time.

     This loop may not be needed any longer now that the main loop does
     a better job at propagating alias information.  */
  pass = 0;
  do
    {
      changed = 0;
      pass++;
      for (ui = 0; ui < maxreg; ui++)
	{
	  rtx base = VARRAY_RTX (reg_base_value, ui);
	  if (base && GET_CODE (base) == REG)
	    {
	      unsigned int base_regno = REGNO (base);
	      if (base_regno == ui)		/* register set from itself */
		VARRAY_RTX (reg_base_value, ui) = 0;
	      else
		VARRAY_RTX (reg_base_value, ui)
		  = VARRAY_RTX (reg_base_value, base_regno);
	      changed = 1;
	    }
	}
    }
  while (changed && pass < MAX_ALIAS_LOOP_PASSES);

  /* Clean up.  */
  free (new_reg_base_value);
  new_reg_base_value = 0;
  free (reg_seen);
  reg_seen = 0;
  timevar_pop (TV_ALIAS_ANALYSIS);
}

void
end_alias_analysis (void)
{
  old_reg_base_value = reg_base_value;
  free (reg_known_value + FIRST_PSEUDO_REGISTER);
  reg_known_value = 0;
  reg_known_value_size = 0;
  free (reg_known_equiv_p + FIRST_PSEUDO_REGISTER);
  reg_known_equiv_p = 0;
  if (alias_invariant)
    {
      free (alias_invariant);
      alias_invariant = 0;
      alias_invariant_size = 0;
    }
}

#include "gt-alias.h"
