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