annotate gcc/alias.c @ 132:d34655255c78

update gcc-8.2
author mir3636
date Thu, 25 Oct 2018 10:21:07 +0900
parents 84e7813d76e9
children 1830386684a0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1 /* Alias analysis for GNU C
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2 Copyright (C) 1997-2018 Free Software Foundation, Inc.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3 Contributed by John Carr (jfc@mit.edu).
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
4
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
5 This file is part of GCC.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
6
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
7 GCC is free software; you can redistribute it and/or modify it under
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
8 the terms of the GNU General Public License as published by the Free
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
9 Software Foundation; either version 3, or (at your option) any later
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
10 version.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
11
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
15 for more details.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
16
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
17 You should have received a copy of the GNU General Public License
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
18 along with GCC; see the file COPYING3. If not see
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
19 <http://www.gnu.org/licenses/>. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
20
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
21 #include "config.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
22 #include "system.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
23 #include "coretypes.h"
111
kono
parents: 67
diff changeset
24 #include "backend.h"
kono
parents: 67
diff changeset
25 #include "target.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
26 #include "rtl.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
27 #include "tree.h"
111
kono
parents: 67
diff changeset
28 #include "gimple.h"
kono
parents: 67
diff changeset
29 #include "df.h"
kono
parents: 67
diff changeset
30 #include "memmodel.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
31 #include "tm_p.h"
111
kono
parents: 67
diff changeset
32 #include "gimple-ssa.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
33 #include "emit-rtl.h"
111
kono
parents: 67
diff changeset
34 #include "alias.h"
kono
parents: 67
diff changeset
35 #include "fold-const.h"
kono
parents: 67
diff changeset
36 #include "varasm.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
37 #include "cselib.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
38 #include "langhooks.h"
111
kono
parents: 67
diff changeset
39 #include "cfganal.h"
kono
parents: 67
diff changeset
40 #include "rtl-iter.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
41 #include "cgraph.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
42
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
43 /* The aliasing API provided here solves related but different problems:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
44
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
45 Say there exists (in c)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
46
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
47 struct X {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
48 struct Y y1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
49 struct Z z2;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
50 } x1, *px1, *px2;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
51
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
52 struct Y y2, *py;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
53 struct Z z2, *pz;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
54
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
55
111
kono
parents: 67
diff changeset
56 py = &x1.y1;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
57 px2 = &x1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
58
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
59 Consider the four questions:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
60
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
61 Can a store to x1 interfere with px2->y1?
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
62 Can a store to x1 interfere with px2->z2?
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
63 Can a store to x1 change the value pointed to by with py?
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
64 Can a store to x1 change the value pointed to by with pz?
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
65
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
66 The answer to these questions can be yes, yes, yes, and maybe.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
67
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
68 The first two questions can be answered with a simple examination
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
69 of the type system. If structure X contains a field of type Y then
111
kono
parents: 67
diff changeset
70 a store through a pointer to an X can overwrite any field that is
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
71 contained (recursively) in an X (unless we know that px1 != px2).
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
72
111
kono
parents: 67
diff changeset
73 The last two questions can be solved in the same way as the first
kono
parents: 67
diff changeset
74 two questions but this is too conservative. The observation is
kono
parents: 67
diff changeset
75 that in some cases we can know which (if any) fields are addressed
kono
parents: 67
diff changeset
76 and if those addresses are used in bad ways. This analysis may be
kono
parents: 67
diff changeset
77 language specific. In C, arbitrary operations may be applied to
kono
parents: 67
diff changeset
78 pointers. However, there is some indication that this may be too
kono
parents: 67
diff changeset
79 conservative for some C++ types.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
80
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
81 The pass ipa-type-escape does this analysis for the types whose
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
82 instances do not escape across the compilation boundary.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
83
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
84 Historically in GCC, these two problems were combined and a single
111
kono
parents: 67
diff changeset
85 data structure that was used to represent the solution to these
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
86 problems. We now have two similar but different data structures,
111
kono
parents: 67
diff changeset
87 The data structure to solve the last two questions is similar to
kono
parents: 67
diff changeset
88 the first, but does not contain the fields whose address are never
kono
parents: 67
diff changeset
89 taken. For types that do escape the compilation unit, the data
kono
parents: 67
diff changeset
90 structures will have identical information.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
91 */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
92
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
93 /* The alias sets assigned to MEMs assist the back-end in determining
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
94 which MEMs can alias which other MEMs. In general, two MEMs in
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
95 different alias sets cannot alias each other, with one important
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
96 exception. Consider something like:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
97
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
98 struct S { int i; double d; };
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
99
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
100 a store to an `S' can alias something of either type `int' or type
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
101 `double'. (However, a store to an `int' cannot alias a `double'
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
102 and vice versa.) We indicate this via a tree structure that looks
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
103 like:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
104 struct S
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
105 / \
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
106 / \
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
107 |/_ _\|
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
108 int double
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
109
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
110 (The arrows are directed and point downwards.)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
111 In this situation we say the alias set for `struct S' is the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
112 `superset' and that those for `int' and `double' are `subsets'.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
113
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
114 To see whether two alias sets can point to the same memory, we must
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
115 see if either alias set is a subset of the other. We need not trace
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
116 past immediate descendants, however, since we propagate all
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
117 grandchildren up one level.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
118
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
119 Alias set zero is implicitly a superset of all other alias sets.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
120 However, this is no actual entry for alias set zero. It is an
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
121 error to attempt to explicitly construct a subset of zero. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
122
111
kono
parents: 67
diff changeset
123 struct alias_set_hash : int_hash <int, INT_MIN, INT_MIN + 1> {};
kono
parents: 67
diff changeset
124
kono
parents: 67
diff changeset
125 struct GTY(()) alias_set_entry {
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
126 /* The alias set number, as stored in MEM_ALIAS_SET. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
127 alias_set_type alias_set;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
128
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
129 /* Nonzero if would have a child of zero: this effectively makes this
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
130 alias set the same as alias set zero. */
111
kono
parents: 67
diff changeset
131 bool has_zero_child;
kono
parents: 67
diff changeset
132 /* Nonzero if alias set corresponds to pointer type itself (i.e. not to
kono
parents: 67
diff changeset
133 aggregate contaiing pointer.
kono
parents: 67
diff changeset
134 This is used for a special case where we need an universal pointer type
kono
parents: 67
diff changeset
135 compatible with all other pointer types. */
kono
parents: 67
diff changeset
136 bool is_pointer;
kono
parents: 67
diff changeset
137 /* Nonzero if is_pointer or if one of childs have has_pointer set. */
kono
parents: 67
diff changeset
138 bool has_pointer;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
139
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
140 /* The children of the alias set. These are not just the immediate
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
141 children, but, in fact, all descendants. So, if we have:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
142
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
143 struct T { struct S s; float f; }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
144
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
145 continuing our example above, the children here will be all of
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
146 `int', `double', `float', and `struct S'. */
111
kono
parents: 67
diff changeset
147 hash_map<alias_set_hash, int> *children;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
148 };
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
149
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
150 static int rtx_equal_for_memref_p (const_rtx, const_rtx);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
151 static void record_set (rtx, const_rtx, void *);
111
kono
parents: 67
diff changeset
152 static int base_alias_check (rtx, rtx, rtx, rtx, machine_mode,
kono
parents: 67
diff changeset
153 machine_mode);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
154 static rtx find_base_value (rtx);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
155 static int mems_in_disjoint_alias_sets_p (const_rtx, const_rtx);
111
kono
parents: 67
diff changeset
156 static alias_set_entry *get_alias_set_entry (alias_set_type);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
157 static tree decl_for_component_ref (tree);
111
kono
parents: 67
diff changeset
158 static int write_dependence_p (const_rtx,
kono
parents: 67
diff changeset
159 const_rtx, machine_mode, rtx,
kono
parents: 67
diff changeset
160 bool, bool, bool);
kono
parents: 67
diff changeset
161 static int compare_base_symbol_refs (const_rtx, const_rtx);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
162
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
163 static void memory_modified_1 (rtx, const_rtx, void *);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
164
111
kono
parents: 67
diff changeset
165 /* Query statistics for the different low-level disambiguators.
kono
parents: 67
diff changeset
166 A high-level query may trigger multiple of them. */
kono
parents: 67
diff changeset
167
kono
parents: 67
diff changeset
168 static struct {
kono
parents: 67
diff changeset
169 unsigned long long num_alias_zero;
kono
parents: 67
diff changeset
170 unsigned long long num_same_alias_set;
kono
parents: 67
diff changeset
171 unsigned long long num_same_objects;
kono
parents: 67
diff changeset
172 unsigned long long num_volatile;
kono
parents: 67
diff changeset
173 unsigned long long num_dag;
kono
parents: 67
diff changeset
174 unsigned long long num_universal;
kono
parents: 67
diff changeset
175 unsigned long long num_disambiguated;
kono
parents: 67
diff changeset
176 } alias_stats;
kono
parents: 67
diff changeset
177
kono
parents: 67
diff changeset
178
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
179 /* Set up all info needed to perform alias analysis on memory references. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
180
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
181 /* Returns the size in bytes of the mode of X. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
182 #define SIZE_FOR_MODE(X) (GET_MODE_SIZE (GET_MODE (X)))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
183
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
184 /* Cap the number of passes we make over the insns propagating alias
111
kono
parents: 67
diff changeset
185 information through set chains.
kono
parents: 67
diff changeset
186 ??? 10 is a completely arbitrary choice. This should be based on the
kono
parents: 67
diff changeset
187 maximum loop depth in the CFG, but we do not have this information
kono
parents: 67
diff changeset
188 available (even if current_loops _is_ available). */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
189 #define MAX_ALIAS_LOOP_PASSES 10
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
190
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
191 /* reg_base_value[N] gives an address to which register N is related.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
192 If all sets after the first add or subtract to the current value
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
193 or otherwise modify it so it does not point to a different top level
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
194 object, reg_base_value[N] is equal to the address part of the source
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
195 of the first set.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
196
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
197 A base address can be an ADDRESS, SYMBOL_REF, or LABEL_REF. ADDRESS
111
kono
parents: 67
diff changeset
198 expressions represent three types of base:
kono
parents: 67
diff changeset
199
kono
parents: 67
diff changeset
200 1. incoming arguments. There is just one ADDRESS to represent all
kono
parents: 67
diff changeset
201 arguments, since we do not know at this level whether accesses
kono
parents: 67
diff changeset
202 based on different arguments can alias. The ADDRESS has id 0.
kono
parents: 67
diff changeset
203
kono
parents: 67
diff changeset
204 2. stack_pointer_rtx, frame_pointer_rtx, hard_frame_pointer_rtx
kono
parents: 67
diff changeset
205 (if distinct from frame_pointer_rtx) and arg_pointer_rtx.
kono
parents: 67
diff changeset
206 Each of these rtxes has a separate ADDRESS associated with it,
kono
parents: 67
diff changeset
207 each with a negative id.
kono
parents: 67
diff changeset
208
kono
parents: 67
diff changeset
209 GCC is (and is required to be) precise in which register it
kono
parents: 67
diff changeset
210 chooses to access a particular region of stack. We can therefore
kono
parents: 67
diff changeset
211 assume that accesses based on one of these rtxes do not alias
kono
parents: 67
diff changeset
212 accesses based on another of these rtxes.
kono
parents: 67
diff changeset
213
kono
parents: 67
diff changeset
214 3. bases that are derived from malloc()ed memory (REG_NOALIAS).
kono
parents: 67
diff changeset
215 Each such piece of memory has a separate ADDRESS associated
kono
parents: 67
diff changeset
216 with it, each with an id greater than 0.
kono
parents: 67
diff changeset
217
kono
parents: 67
diff changeset
218 Accesses based on one ADDRESS do not alias accesses based on other
kono
parents: 67
diff changeset
219 ADDRESSes. Accesses based on ADDRESSes in groups (2) and (3) do not
kono
parents: 67
diff changeset
220 alias globals either; the ADDRESSes have Pmode to indicate this.
kono
parents: 67
diff changeset
221 The ADDRESS in group (1) _may_ alias globals; it has VOIDmode to
kono
parents: 67
diff changeset
222 indicate this. */
kono
parents: 67
diff changeset
223
kono
parents: 67
diff changeset
224 static GTY(()) vec<rtx, va_gc> *reg_base_value;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
225 static rtx *new_reg_base_value;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
226
111
kono
parents: 67
diff changeset
227 /* The single VOIDmode ADDRESS that represents all argument bases.
kono
parents: 67
diff changeset
228 It has id 0. */
kono
parents: 67
diff changeset
229 static GTY(()) rtx arg_base_value;
kono
parents: 67
diff changeset
230
kono
parents: 67
diff changeset
231 /* Used to allocate unique ids to each REG_NOALIAS ADDRESS. */
kono
parents: 67
diff changeset
232 static int unique_id;
kono
parents: 67
diff changeset
233
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
234 /* We preserve the copy of old array around to avoid amount of garbage
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
235 produced. About 8% of garbage produced were attributed to this
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
236 array. */
111
kono
parents: 67
diff changeset
237 static GTY((deletable)) vec<rtx, va_gc> *old_reg_base_value;
kono
parents: 67
diff changeset
238
kono
parents: 67
diff changeset
239 /* Values of XINT (address, 0) of Pmode ADDRESS rtxes for special
kono
parents: 67
diff changeset
240 registers. */
kono
parents: 67
diff changeset
241 #define UNIQUE_BASE_VALUE_SP -1
kono
parents: 67
diff changeset
242 #define UNIQUE_BASE_VALUE_ARGP -2
kono
parents: 67
diff changeset
243 #define UNIQUE_BASE_VALUE_FP -3
kono
parents: 67
diff changeset
244 #define UNIQUE_BASE_VALUE_HFP -4
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
245
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
246 #define static_reg_base_value \
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
247 (this_target_rtl->x_static_reg_base_value)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
248
111
kono
parents: 67
diff changeset
249 #define REG_BASE_VALUE(X) \
kono
parents: 67
diff changeset
250 (REGNO (X) < vec_safe_length (reg_base_value) \
kono
parents: 67
diff changeset
251 ? (*reg_base_value)[REGNO (X)] : 0)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
252
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
253 /* Vector indexed by N giving the initial (unchanging) value known for
111
kono
parents: 67
diff changeset
254 pseudo-register N. This vector is initialized in init_alias_analysis,
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
255 and does not change until end_alias_analysis is called. */
111
kono
parents: 67
diff changeset
256 static GTY(()) vec<rtx, va_gc> *reg_known_value;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
257
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
258 /* Vector recording for each reg_known_value whether it is due to a
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
259 REG_EQUIV note. Future passes (viz., reload) may replace the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
260 pseudo with the equivalent expression and so we account for the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
261 dependences that would be introduced if that happens.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
262
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
263 The REG_EQUIV notes created in assign_parms may mention the arg
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
264 pointer, and there are explicit insns in the RTL that modify the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
265 arg pointer. Thus we must ensure that such insns don't get
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
266 scheduled across each other because that would invalidate the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
267 REG_EQUIV notes. One could argue that the REG_EQUIV notes are
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
268 wrong, but solving the problem in the scheduler will likely give
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
269 better code, so we do it here. */
111
kono
parents: 67
diff changeset
270 static sbitmap reg_known_equiv_p;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
271
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
272 /* True when scanning insns from the start of the rtl to the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
273 NOTE_INSN_FUNCTION_BEG note. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
274 static bool copying_arguments;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
275
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
276
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
277 /* The splay-tree used to store the various alias set entries. */
111
kono
parents: 67
diff changeset
278 static GTY (()) vec<alias_set_entry *, va_gc> *alias_sets;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
279
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
280 /* Build a decomposed reference object for querying the alias-oracle
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
281 from the MEM rtx and store it in *REF.
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
282 Returns false if MEM is not suitable for the alias-oracle. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
283
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
284 static bool
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
285 ao_ref_from_mem (ao_ref *ref, const_rtx mem)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
286 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
287 tree expr = MEM_EXPR (mem);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
288 tree base;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
289
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
290 if (!expr)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
291 return false;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
292
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
293 ao_ref_init (ref, expr);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
294
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
295 /* Get the base of the reference and see if we have to reject or
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
296 adjust it. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
297 base = ao_ref_base (ref);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
298 if (base == NULL_TREE)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
299 return false;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
300
111
kono
parents: 67
diff changeset
301 /* The tree oracle doesn't like bases that are neither decls
kono
parents: 67
diff changeset
302 nor indirect references of SSA names. */
kono
parents: 67
diff changeset
303 if (!(DECL_P (base)
kono
parents: 67
diff changeset
304 || (TREE_CODE (base) == MEM_REF
kono
parents: 67
diff changeset
305 && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
kono
parents: 67
diff changeset
306 || (TREE_CODE (base) == TARGET_MEM_REF
kono
parents: 67
diff changeset
307 && TREE_CODE (TMR_BASE (base)) == SSA_NAME)))
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
308 return false;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
309
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
310 /* If this is a reference based on a partitioned decl replace the
111
kono
parents: 67
diff changeset
311 base with a MEM_REF of the pointer representative we
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
312 created during stack slot partitioning. */
111
kono
parents: 67
diff changeset
313 if (VAR_P (base)
kono
parents: 67
diff changeset
314 && ! is_global_var (base)
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
315 && cfun->gimple_df->decls_to_pointers != NULL)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
316 {
111
kono
parents: 67
diff changeset
317 tree *namep = cfun->gimple_df->decls_to_pointers->get (base);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
318 if (namep)
111
kono
parents: 67
diff changeset
319 ref->base = build_simple_mem_ref (*namep);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
320 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
321
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
322 ref->ref_alias_set = MEM_ALIAS_SET (mem);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
323
111
kono
parents: 67
diff changeset
324 /* If MEM_OFFSET or MEM_SIZE are unknown what we got from MEM_EXPR
kono
parents: 67
diff changeset
325 is conservative, so trust it. */
kono
parents: 67
diff changeset
326 if (!MEM_OFFSET_KNOWN_P (mem)
kono
parents: 67
diff changeset
327 || !MEM_SIZE_KNOWN_P (mem))
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
328 return true;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
329
111
kono
parents: 67
diff changeset
330 /* If MEM_OFFSET/MEM_SIZE get us outside of ref->offset/ref->max_size
kono
parents: 67
diff changeset
331 drop ref->ref. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
332 if (maybe_lt (MEM_OFFSET (mem), 0)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
333 || (ref->max_size_known_p ()
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
334 && maybe_gt ((MEM_OFFSET (mem) + MEM_SIZE (mem)) * BITS_PER_UNIT,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
335 ref->max_size)))
111
kono
parents: 67
diff changeset
336 ref->ref = NULL_TREE;
kono
parents: 67
diff changeset
337
kono
parents: 67
diff changeset
338 /* Refine size and offset we got from analyzing MEM_EXPR by using
kono
parents: 67
diff changeset
339 MEM_SIZE and MEM_OFFSET. */
kono
parents: 67
diff changeset
340
kono
parents: 67
diff changeset
341 ref->offset += MEM_OFFSET (mem) * BITS_PER_UNIT;
kono
parents: 67
diff changeset
342 ref->size = MEM_SIZE (mem) * BITS_PER_UNIT;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
343
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
344 /* The MEM may extend into adjacent fields, so adjust max_size if
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
345 necessary. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
346 if (ref->max_size_known_p ())
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
347 ref->max_size = upper_bound (ref->max_size, ref->size);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
348
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
349 /* If MEM_OFFSET and MEM_SIZE might get us outside of the base object of
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
350 the MEM_EXPR punt. This happens for STRICT_ALIGNMENT targets a lot. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
351 if (MEM_EXPR (mem) != get_spill_slot_decl (false)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
352 && (maybe_lt (ref->offset, 0)
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
353 || (DECL_P (ref->base)
111
kono
parents: 67
diff changeset
354 && (DECL_SIZE (ref->base) == NULL_TREE
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
355 || !poly_int_tree_p (DECL_SIZE (ref->base))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
356 || maybe_lt (wi::to_poly_offset (DECL_SIZE (ref->base)),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
357 ref->offset + ref->size)))))
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
358 return false;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
359
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
360 return true;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
361 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
362
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
363 /* Query the alias-oracle on whether the two memory rtx X and MEM may
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
364 alias. If TBAA_P is set also apply TBAA. Returns true if the
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
365 two rtxen may alias, false otherwise. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
366
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
367 static bool
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
368 rtx_refs_may_alias_p (const_rtx x, const_rtx mem, bool tbaa_p)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
369 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
370 ao_ref ref1, ref2;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
371
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
372 if (!ao_ref_from_mem (&ref1, x)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
373 || !ao_ref_from_mem (&ref2, mem))
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
374 return true;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
375
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
376 return refs_may_alias_p_1 (&ref1, &ref2,
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
377 tbaa_p
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
378 && MEM_ALIAS_SET (x) != 0
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
379 && MEM_ALIAS_SET (mem) != 0);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
380 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
381
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
382 /* Returns a pointer to the alias set entry for ALIAS_SET, if there is
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
383 such an entry, or NULL otherwise. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
384
111
kono
parents: 67
diff changeset
385 static inline alias_set_entry *
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
386 get_alias_set_entry (alias_set_type alias_set)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
387 {
111
kono
parents: 67
diff changeset
388 return (*alias_sets)[alias_set];
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
389 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
390
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
391 /* Returns nonzero if the alias sets for MEM1 and MEM2 are such that
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
392 the two MEMs cannot alias each other. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
393
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
394 static inline int
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
395 mems_in_disjoint_alias_sets_p (const_rtx mem1, const_rtx mem2)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
396 {
111
kono
parents: 67
diff changeset
397 return (flag_strict_aliasing
kono
parents: 67
diff changeset
398 && ! alias_sets_conflict_p (MEM_ALIAS_SET (mem1),
kono
parents: 67
diff changeset
399 MEM_ALIAS_SET (mem2)));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
400 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
401
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
402 /* Return true if the first alias set is a subset of the second. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
403
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
404 bool
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
405 alias_set_subset_of (alias_set_type set1, alias_set_type set2)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
406 {
111
kono
parents: 67
diff changeset
407 alias_set_entry *ase2;
kono
parents: 67
diff changeset
408
kono
parents: 67
diff changeset
409 /* Disable TBAA oracle with !flag_strict_aliasing. */
kono
parents: 67
diff changeset
410 if (!flag_strict_aliasing)
kono
parents: 67
diff changeset
411 return true;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
412
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
413 /* Everything is a subset of the "aliases everything" set. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
414 if (set2 == 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
415 return true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
416
111
kono
parents: 67
diff changeset
417 /* Check if set1 is a subset of set2. */
kono
parents: 67
diff changeset
418 ase2 = get_alias_set_entry (set2);
kono
parents: 67
diff changeset
419 if (ase2 != 0
kono
parents: 67
diff changeset
420 && (ase2->has_zero_child
kono
parents: 67
diff changeset
421 || (ase2->children && ase2->children->get (set1))))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
422 return true;
111
kono
parents: 67
diff changeset
423
kono
parents: 67
diff changeset
424 /* As a special case we consider alias set of "void *" to be both subset
kono
parents: 67
diff changeset
425 and superset of every alias set of a pointer. This extra symmetry does
kono
parents: 67
diff changeset
426 not matter for alias_sets_conflict_p but it makes aliasing_component_refs_p
kono
parents: 67
diff changeset
427 to return true on the following testcase:
kono
parents: 67
diff changeset
428
kono
parents: 67
diff changeset
429 void *ptr;
kono
parents: 67
diff changeset
430 char **ptr2=(char **)&ptr;
kono
parents: 67
diff changeset
431 *ptr2 = ...
kono
parents: 67
diff changeset
432
kono
parents: 67
diff changeset
433 Additionally if a set contains universal pointer, we consider every pointer
kono
parents: 67
diff changeset
434 to be a subset of it, but we do not represent this explicitely - doing so
kono
parents: 67
diff changeset
435 would require us to update transitive closure each time we introduce new
kono
parents: 67
diff changeset
436 pointer type. This makes aliasing_component_refs_p to return true
kono
parents: 67
diff changeset
437 on the following testcase:
kono
parents: 67
diff changeset
438
kono
parents: 67
diff changeset
439 struct a {void *ptr;}
kono
parents: 67
diff changeset
440 char **ptr = (char **)&a.ptr;
kono
parents: 67
diff changeset
441 ptr = ...
kono
parents: 67
diff changeset
442
kono
parents: 67
diff changeset
443 This makes void * truly universal pointer type. See pointer handling in
kono
parents: 67
diff changeset
444 get_alias_set for more details. */
kono
parents: 67
diff changeset
445 if (ase2 && ase2->has_pointer)
kono
parents: 67
diff changeset
446 {
kono
parents: 67
diff changeset
447 alias_set_entry *ase1 = get_alias_set_entry (set1);
kono
parents: 67
diff changeset
448
kono
parents: 67
diff changeset
449 if (ase1 && ase1->is_pointer)
kono
parents: 67
diff changeset
450 {
kono
parents: 67
diff changeset
451 alias_set_type voidptr_set = TYPE_ALIAS_SET (ptr_type_node);
kono
parents: 67
diff changeset
452 /* If one is ptr_type_node and other is pointer, then we consider
kono
parents: 67
diff changeset
453 them subset of each other. */
kono
parents: 67
diff changeset
454 if (set1 == voidptr_set || set2 == voidptr_set)
kono
parents: 67
diff changeset
455 return true;
kono
parents: 67
diff changeset
456 /* If SET2 contains universal pointer's alias set, then we consdier
kono
parents: 67
diff changeset
457 every (non-universal) pointer. */
kono
parents: 67
diff changeset
458 if (ase2->children && set1 != voidptr_set
kono
parents: 67
diff changeset
459 && ase2->children->get (voidptr_set))
kono
parents: 67
diff changeset
460 return true;
kono
parents: 67
diff changeset
461 }
kono
parents: 67
diff changeset
462 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
463 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
464 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
465
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
466 /* Return 1 if the two specified alias sets may conflict. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
467
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
468 int
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
469 alias_sets_conflict_p (alias_set_type set1, alias_set_type set2)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
470 {
111
kono
parents: 67
diff changeset
471 alias_set_entry *ase1;
kono
parents: 67
diff changeset
472 alias_set_entry *ase2;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
473
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
474 /* The easy case. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
475 if (alias_sets_must_conflict_p (set1, set2))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
476 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
477
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
478 /* See if the first alias set is a subset of the second. */
111
kono
parents: 67
diff changeset
479 ase1 = get_alias_set_entry (set1);
kono
parents: 67
diff changeset
480 if (ase1 != 0
kono
parents: 67
diff changeset
481 && ase1->children && ase1->children->get (set2))
kono
parents: 67
diff changeset
482 {
kono
parents: 67
diff changeset
483 ++alias_stats.num_dag;
kono
parents: 67
diff changeset
484 return 1;
kono
parents: 67
diff changeset
485 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
486
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
487 /* Now do the same, but with the alias sets reversed. */
111
kono
parents: 67
diff changeset
488 ase2 = get_alias_set_entry (set2);
kono
parents: 67
diff changeset
489 if (ase2 != 0
kono
parents: 67
diff changeset
490 && ase2->children && ase2->children->get (set1))
kono
parents: 67
diff changeset
491 {
kono
parents: 67
diff changeset
492 ++alias_stats.num_dag;
kono
parents: 67
diff changeset
493 return 1;
kono
parents: 67
diff changeset
494 }
kono
parents: 67
diff changeset
495
kono
parents: 67
diff changeset
496 /* We want void * to be compatible with any other pointer without
kono
parents: 67
diff changeset
497 really dropping it to alias set 0. Doing so would make it
kono
parents: 67
diff changeset
498 compatible with all non-pointer types too.
kono
parents: 67
diff changeset
499
kono
parents: 67
diff changeset
500 This is not strictly necessary by the C/C++ language
kono
parents: 67
diff changeset
501 standards, but avoids common type punning mistakes. In
kono
parents: 67
diff changeset
502 addition to that, we need the existence of such universal
kono
parents: 67
diff changeset
503 pointer to implement Fortran's C_PTR type (which is defined as
kono
parents: 67
diff changeset
504 type compatible with all C pointers). */
kono
parents: 67
diff changeset
505 if (ase1 && ase2 && ase1->has_pointer && ase2->has_pointer)
kono
parents: 67
diff changeset
506 {
kono
parents: 67
diff changeset
507 alias_set_type voidptr_set = TYPE_ALIAS_SET (ptr_type_node);
kono
parents: 67
diff changeset
508
kono
parents: 67
diff changeset
509 /* If one of the sets corresponds to universal pointer,
kono
parents: 67
diff changeset
510 we consider it to conflict with anything that is
kono
parents: 67
diff changeset
511 or contains pointer. */
kono
parents: 67
diff changeset
512 if (set1 == voidptr_set || set2 == voidptr_set)
kono
parents: 67
diff changeset
513 {
kono
parents: 67
diff changeset
514 ++alias_stats.num_universal;
kono
parents: 67
diff changeset
515 return true;
kono
parents: 67
diff changeset
516 }
kono
parents: 67
diff changeset
517 /* If one of sets is (non-universal) pointer and the other
kono
parents: 67
diff changeset
518 contains universal pointer, we also get conflict. */
kono
parents: 67
diff changeset
519 if (ase1->is_pointer && set2 != voidptr_set
kono
parents: 67
diff changeset
520 && ase2->children && ase2->children->get (voidptr_set))
kono
parents: 67
diff changeset
521 {
kono
parents: 67
diff changeset
522 ++alias_stats.num_universal;
kono
parents: 67
diff changeset
523 return true;
kono
parents: 67
diff changeset
524 }
kono
parents: 67
diff changeset
525 if (ase2->is_pointer && set1 != voidptr_set
kono
parents: 67
diff changeset
526 && ase1->children && ase1->children->get (voidptr_set))
kono
parents: 67
diff changeset
527 {
kono
parents: 67
diff changeset
528 ++alias_stats.num_universal;
kono
parents: 67
diff changeset
529 return true;
kono
parents: 67
diff changeset
530 }
kono
parents: 67
diff changeset
531 }
kono
parents: 67
diff changeset
532
kono
parents: 67
diff changeset
533 ++alias_stats.num_disambiguated;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
534
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
535 /* The two alias sets are distinct and neither one is the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
536 child of the other. Therefore, they cannot conflict. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
537 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
538 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
539
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
540 /* Return 1 if the two specified alias sets will always conflict. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
541
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
542 int
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
543 alias_sets_must_conflict_p (alias_set_type set1, alias_set_type set2)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
544 {
111
kono
parents: 67
diff changeset
545 /* Disable TBAA oracle with !flag_strict_aliasing. */
kono
parents: 67
diff changeset
546 if (!flag_strict_aliasing)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
547 return 1;
111
kono
parents: 67
diff changeset
548 if (set1 == 0 || set2 == 0)
kono
parents: 67
diff changeset
549 {
kono
parents: 67
diff changeset
550 ++alias_stats.num_alias_zero;
kono
parents: 67
diff changeset
551 return 1;
kono
parents: 67
diff changeset
552 }
kono
parents: 67
diff changeset
553 if (set1 == set2)
kono
parents: 67
diff changeset
554 {
kono
parents: 67
diff changeset
555 ++alias_stats.num_same_alias_set;
kono
parents: 67
diff changeset
556 return 1;
kono
parents: 67
diff changeset
557 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
558
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
559 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
560 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
561
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
562 /* Return 1 if any MEM object of type T1 will always conflict (using the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
563 dependency routines in this file) with any MEM object of type T2.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
564 This is used when allocating temporary storage. If T1 and/or T2 are
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
565 NULL_TREE, it means we know nothing about the storage. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
566
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
567 int
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
568 objects_must_conflict_p (tree t1, tree t2)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
569 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
570 alias_set_type set1, set2;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
571
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
572 /* If neither has a type specified, we don't know if they'll conflict
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
573 because we may be using them to store objects of various types, for
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
574 example the argument and local variables areas of inlined functions. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
575 if (t1 == 0 && t2 == 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
576 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
577
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
578 /* If they are the same type, they must conflict. */
111
kono
parents: 67
diff changeset
579 if (t1 == t2)
kono
parents: 67
diff changeset
580 {
kono
parents: 67
diff changeset
581 ++alias_stats.num_same_objects;
kono
parents: 67
diff changeset
582 return 1;
kono
parents: 67
diff changeset
583 }
kono
parents: 67
diff changeset
584 /* Likewise if both are volatile. */
kono
parents: 67
diff changeset
585 if (t1 != 0 && TYPE_VOLATILE (t1) && t2 != 0 && TYPE_VOLATILE (t2))
kono
parents: 67
diff changeset
586 {
kono
parents: 67
diff changeset
587 ++alias_stats.num_volatile;
kono
parents: 67
diff changeset
588 return 1;
kono
parents: 67
diff changeset
589 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
590
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
591 set1 = t1 ? get_alias_set (t1) : 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
592 set2 = t2 ? get_alias_set (t2) : 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
593
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
594 /* We can't use alias_sets_conflict_p because we must make sure
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
595 that every subtype of t1 will conflict with every subtype of
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
596 t2 for which a pair of subobjects of these respective subtypes
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
597 overlaps on the stack. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
598 return alias_sets_must_conflict_p (set1, set2);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
599 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
600
111
kono
parents: 67
diff changeset
601 /* Return the outermost parent of component present in the chain of
kono
parents: 67
diff changeset
602 component references handled by get_inner_reference in T with the
kono
parents: 67
diff changeset
603 following property:
kono
parents: 67
diff changeset
604 - the component is non-addressable, or
kono
parents: 67
diff changeset
605 - the parent has alias set zero,
kono
parents: 67
diff changeset
606 or NULL_TREE if no such parent exists. In the former cases, the alias
kono
parents: 67
diff changeset
607 set of this parent is the alias set that must be used for T itself. */
kono
parents: 67
diff changeset
608
kono
parents: 67
diff changeset
609 tree
kono
parents: 67
diff changeset
610 component_uses_parent_alias_set_from (const_tree t)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
611 {
111
kono
parents: 67
diff changeset
612 const_tree found = NULL_TREE;
kono
parents: 67
diff changeset
613
kono
parents: 67
diff changeset
614 if (AGGREGATE_TYPE_P (TREE_TYPE (t))
kono
parents: 67
diff changeset
615 && TYPE_TYPELESS_STORAGE (TREE_TYPE (t)))
kono
parents: 67
diff changeset
616 return const_cast <tree> (t);
kono
parents: 67
diff changeset
617
kono
parents: 67
diff changeset
618 while (handled_component_p (t))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
619 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
620 switch (TREE_CODE (t))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
621 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
622 case COMPONENT_REF:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
623 if (DECL_NONADDRESSABLE_P (TREE_OPERAND (t, 1)))
111
kono
parents: 67
diff changeset
624 found = t;
kono
parents: 67
diff changeset
625 /* Permit type-punning when accessing a union, provided the access
kono
parents: 67
diff changeset
626 is directly through the union. For example, this code does not
kono
parents: 67
diff changeset
627 permit taking the address of a union member and then storing
kono
parents: 67
diff changeset
628 through it. Even the type-punning allowed here is a GCC
kono
parents: 67
diff changeset
629 extension, albeit a common and useful one; the C standard says
kono
parents: 67
diff changeset
630 that such accesses have implementation-defined behavior. */
kono
parents: 67
diff changeset
631 else if (TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == UNION_TYPE)
kono
parents: 67
diff changeset
632 found = t;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
633 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
634
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
635 case ARRAY_REF:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
636 case ARRAY_RANGE_REF:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
637 if (TYPE_NONALIASED_COMPONENT (TREE_TYPE (TREE_OPERAND (t, 0))))
111
kono
parents: 67
diff changeset
638 found = t;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
639 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
640
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
641 case REALPART_EXPR:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
642 case IMAGPART_EXPR:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
643 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
644
111
kono
parents: 67
diff changeset
645 case BIT_FIELD_REF:
kono
parents: 67
diff changeset
646 case VIEW_CONVERT_EXPR:
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
647 /* Bitfields and casts are never addressable. */
111
kono
parents: 67
diff changeset
648 found = t;
kono
parents: 67
diff changeset
649 break;
kono
parents: 67
diff changeset
650
kono
parents: 67
diff changeset
651 default:
kono
parents: 67
diff changeset
652 gcc_unreachable ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
653 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
654
111
kono
parents: 67
diff changeset
655 if (get_alias_set (TREE_TYPE (TREE_OPERAND (t, 0))) == 0)
kono
parents: 67
diff changeset
656 found = t;
kono
parents: 67
diff changeset
657
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
658 t = TREE_OPERAND (t, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
659 }
111
kono
parents: 67
diff changeset
660
kono
parents: 67
diff changeset
661 if (found)
kono
parents: 67
diff changeset
662 return TREE_OPERAND (found, 0);
kono
parents: 67
diff changeset
663
kono
parents: 67
diff changeset
664 return NULL_TREE;
kono
parents: 67
diff changeset
665 }
kono
parents: 67
diff changeset
666
kono
parents: 67
diff changeset
667
kono
parents: 67
diff changeset
668 /* Return whether the pointer-type T effective for aliasing may
kono
parents: 67
diff changeset
669 access everything and thus the reference has to be assigned
kono
parents: 67
diff changeset
670 alias-set zero. */
kono
parents: 67
diff changeset
671
kono
parents: 67
diff changeset
672 static bool
kono
parents: 67
diff changeset
673 ref_all_alias_ptr_type_p (const_tree t)
kono
parents: 67
diff changeset
674 {
kono
parents: 67
diff changeset
675 return (TREE_CODE (TREE_TYPE (t)) == VOID_TYPE
kono
parents: 67
diff changeset
676 || TYPE_REF_CAN_ALIAS_ALL (t));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
677 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
678
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
679 /* Return the alias set for the memory pointed to by T, which may be
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
680 either a type or an expression. Return -1 if there is nothing
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
681 special about dereferencing T. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
682
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
683 static alias_set_type
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
684 get_deref_alias_set_1 (tree t)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
685 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
686 /* All we care about is the type. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
687 if (! TYPE_P (t))
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
688 t = TREE_TYPE (t);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
689
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
690 /* If we have an INDIRECT_REF via a void pointer, we don't
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
691 know anything about what that might alias. Likewise if the
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
692 pointer is marked that way. */
111
kono
parents: 67
diff changeset
693 if (ref_all_alias_ptr_type_p (t))
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
694 return 0;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
695
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
696 return -1;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
697 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
698
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
699 /* Return the alias set for the memory pointed to by T, which may be
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
700 either a type or an expression. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
701
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
702 alias_set_type
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
703 get_deref_alias_set (tree t)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
704 {
111
kono
parents: 67
diff changeset
705 /* If we're not doing any alias analysis, just assume everything
kono
parents: 67
diff changeset
706 aliases everything else. */
kono
parents: 67
diff changeset
707 if (!flag_strict_aliasing)
kono
parents: 67
diff changeset
708 return 0;
kono
parents: 67
diff changeset
709
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
710 alias_set_type set = get_deref_alias_set_1 (t);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
711
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
712 /* Fall back to the alias-set of the pointed-to type. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
713 if (set == -1)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
714 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
715 if (! TYPE_P (t))
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
716 t = TREE_TYPE (t);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
717 set = get_alias_set (TREE_TYPE (t));
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
718 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
719
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
720 return set;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
721 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
722
111
kono
parents: 67
diff changeset
723 /* Return the pointer-type relevant for TBAA purposes from the
kono
parents: 67
diff changeset
724 memory reference tree *T or NULL_TREE in which case *T is
kono
parents: 67
diff changeset
725 adjusted to point to the outermost component reference that
kono
parents: 67
diff changeset
726 can be used for assigning an alias set. */
kono
parents: 67
diff changeset
727
kono
parents: 67
diff changeset
728 static tree
kono
parents: 67
diff changeset
729 reference_alias_ptr_type_1 (tree *t)
kono
parents: 67
diff changeset
730 {
kono
parents: 67
diff changeset
731 tree inner;
kono
parents: 67
diff changeset
732
kono
parents: 67
diff changeset
733 /* Get the base object of the reference. */
kono
parents: 67
diff changeset
734 inner = *t;
kono
parents: 67
diff changeset
735 while (handled_component_p (inner))
kono
parents: 67
diff changeset
736 {
kono
parents: 67
diff changeset
737 /* If there is a VIEW_CONVERT_EXPR in the chain we cannot use
kono
parents: 67
diff changeset
738 the type of any component references that wrap it to
kono
parents: 67
diff changeset
739 determine the alias-set. */
kono
parents: 67
diff changeset
740 if (TREE_CODE (inner) == VIEW_CONVERT_EXPR)
kono
parents: 67
diff changeset
741 *t = TREE_OPERAND (inner, 0);
kono
parents: 67
diff changeset
742 inner = TREE_OPERAND (inner, 0);
kono
parents: 67
diff changeset
743 }
kono
parents: 67
diff changeset
744
kono
parents: 67
diff changeset
745 /* Handle pointer dereferences here, they can override the
kono
parents: 67
diff changeset
746 alias-set. */
kono
parents: 67
diff changeset
747 if (INDIRECT_REF_P (inner)
kono
parents: 67
diff changeset
748 && ref_all_alias_ptr_type_p (TREE_TYPE (TREE_OPERAND (inner, 0))))
kono
parents: 67
diff changeset
749 return TREE_TYPE (TREE_OPERAND (inner, 0));
kono
parents: 67
diff changeset
750 else if (TREE_CODE (inner) == TARGET_MEM_REF)
kono
parents: 67
diff changeset
751 return TREE_TYPE (TMR_OFFSET (inner));
kono
parents: 67
diff changeset
752 else if (TREE_CODE (inner) == MEM_REF
kono
parents: 67
diff changeset
753 && ref_all_alias_ptr_type_p (TREE_TYPE (TREE_OPERAND (inner, 1))))
kono
parents: 67
diff changeset
754 return TREE_TYPE (TREE_OPERAND (inner, 1));
kono
parents: 67
diff changeset
755
kono
parents: 67
diff changeset
756 /* If the innermost reference is a MEM_REF that has a
kono
parents: 67
diff changeset
757 conversion embedded treat it like a VIEW_CONVERT_EXPR above,
kono
parents: 67
diff changeset
758 using the memory access type for determining the alias-set. */
kono
parents: 67
diff changeset
759 if (TREE_CODE (inner) == MEM_REF
kono
parents: 67
diff changeset
760 && (TYPE_MAIN_VARIANT (TREE_TYPE (inner))
kono
parents: 67
diff changeset
761 != TYPE_MAIN_VARIANT
kono
parents: 67
diff changeset
762 (TREE_TYPE (TREE_TYPE (TREE_OPERAND (inner, 1))))))
kono
parents: 67
diff changeset
763 return TREE_TYPE (TREE_OPERAND (inner, 1));
kono
parents: 67
diff changeset
764
kono
parents: 67
diff changeset
765 /* Otherwise, pick up the outermost object that we could have
kono
parents: 67
diff changeset
766 a pointer to. */
kono
parents: 67
diff changeset
767 tree tem = component_uses_parent_alias_set_from (*t);
kono
parents: 67
diff changeset
768 if (tem)
kono
parents: 67
diff changeset
769 *t = tem;
kono
parents: 67
diff changeset
770
kono
parents: 67
diff changeset
771 return NULL_TREE;
kono
parents: 67
diff changeset
772 }
kono
parents: 67
diff changeset
773
kono
parents: 67
diff changeset
774 /* Return the pointer-type relevant for TBAA purposes from the
kono
parents: 67
diff changeset
775 gimple memory reference tree T. This is the type to be used for
kono
parents: 67
diff changeset
776 the offset operand of MEM_REF or TARGET_MEM_REF replacements of T
kono
parents: 67
diff changeset
777 and guarantees that get_alias_set will return the same alias
kono
parents: 67
diff changeset
778 set for T and the replacement. */
kono
parents: 67
diff changeset
779
kono
parents: 67
diff changeset
780 tree
kono
parents: 67
diff changeset
781 reference_alias_ptr_type (tree t)
kono
parents: 67
diff changeset
782 {
kono
parents: 67
diff changeset
783 /* If the frontend assigns this alias-set zero, preserve that. */
kono
parents: 67
diff changeset
784 if (lang_hooks.get_alias_set (t) == 0)
kono
parents: 67
diff changeset
785 return ptr_type_node;
kono
parents: 67
diff changeset
786
kono
parents: 67
diff changeset
787 tree ptype = reference_alias_ptr_type_1 (&t);
kono
parents: 67
diff changeset
788 /* If there is a given pointer type for aliasing purposes, return it. */
kono
parents: 67
diff changeset
789 if (ptype != NULL_TREE)
kono
parents: 67
diff changeset
790 return ptype;
kono
parents: 67
diff changeset
791
kono
parents: 67
diff changeset
792 /* Otherwise build one from the outermost component reference we
kono
parents: 67
diff changeset
793 may use. */
kono
parents: 67
diff changeset
794 if (TREE_CODE (t) == MEM_REF
kono
parents: 67
diff changeset
795 || TREE_CODE (t) == TARGET_MEM_REF)
kono
parents: 67
diff changeset
796 return TREE_TYPE (TREE_OPERAND (t, 1));
kono
parents: 67
diff changeset
797 else
kono
parents: 67
diff changeset
798 return build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (t)));
kono
parents: 67
diff changeset
799 }
kono
parents: 67
diff changeset
800
kono
parents: 67
diff changeset
801 /* Return whether the pointer-types T1 and T2 used to determine
kono
parents: 67
diff changeset
802 two alias sets of two references will yield the same answer
kono
parents: 67
diff changeset
803 from get_deref_alias_set. */
kono
parents: 67
diff changeset
804
kono
parents: 67
diff changeset
805 bool
kono
parents: 67
diff changeset
806 alias_ptr_types_compatible_p (tree t1, tree t2)
kono
parents: 67
diff changeset
807 {
kono
parents: 67
diff changeset
808 if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
kono
parents: 67
diff changeset
809 return true;
kono
parents: 67
diff changeset
810
kono
parents: 67
diff changeset
811 if (ref_all_alias_ptr_type_p (t1)
kono
parents: 67
diff changeset
812 || ref_all_alias_ptr_type_p (t2))
kono
parents: 67
diff changeset
813 return false;
kono
parents: 67
diff changeset
814
kono
parents: 67
diff changeset
815 return (TYPE_MAIN_VARIANT (TREE_TYPE (t1))
kono
parents: 67
diff changeset
816 == TYPE_MAIN_VARIANT (TREE_TYPE (t2)));
kono
parents: 67
diff changeset
817 }
kono
parents: 67
diff changeset
818
kono
parents: 67
diff changeset
819 /* Create emptry alias set entry. */
kono
parents: 67
diff changeset
820
kono
parents: 67
diff changeset
821 alias_set_entry *
kono
parents: 67
diff changeset
822 init_alias_set_entry (alias_set_type set)
kono
parents: 67
diff changeset
823 {
kono
parents: 67
diff changeset
824 alias_set_entry *ase = ggc_alloc<alias_set_entry> ();
kono
parents: 67
diff changeset
825 ase->alias_set = set;
kono
parents: 67
diff changeset
826 ase->children = NULL;
kono
parents: 67
diff changeset
827 ase->has_zero_child = false;
kono
parents: 67
diff changeset
828 ase->is_pointer = false;
kono
parents: 67
diff changeset
829 ase->has_pointer = false;
kono
parents: 67
diff changeset
830 gcc_checking_assert (!get_alias_set_entry (set));
kono
parents: 67
diff changeset
831 (*alias_sets)[set] = ase;
kono
parents: 67
diff changeset
832 return ase;
kono
parents: 67
diff changeset
833 }
kono
parents: 67
diff changeset
834
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
835 /* Return the alias set for T, which may be either a type or an
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
836 expression. Call language-specific routine for help, if needed. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
837
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
838 alias_set_type
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
839 get_alias_set (tree t)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
840 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
841 alias_set_type set;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
842
111
kono
parents: 67
diff changeset
843 /* We can not give up with -fno-strict-aliasing because we need to build
kono
parents: 67
diff changeset
844 proper type representation for possible functions which are build with
kono
parents: 67
diff changeset
845 -fstrict-aliasing. */
kono
parents: 67
diff changeset
846
kono
parents: 67
diff changeset
847 /* return 0 if this or its type is an error. */
kono
parents: 67
diff changeset
848 if (t == error_mark_node
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
849 || (! TYPE_P (t)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
850 && (TREE_TYPE (t) == 0 || TREE_TYPE (t) == error_mark_node)))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
851 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
852
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
853 /* We can be passed either an expression or a type. This and the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
854 language-specific routine may make mutually-recursive calls to each other
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
855 to figure out what to do. At each juncture, we see if this is a tree
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
856 that the language may need to handle specially. First handle things that
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
857 aren't types. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
858 if (! TYPE_P (t))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
859 {
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
860 /* Give the language a chance to do something with this tree
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
861 before we look at it. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
862 STRIP_NOPS (t);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
863 set = lang_hooks.get_alias_set (t);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
864 if (set != -1)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
865 return set;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
866
111
kono
parents: 67
diff changeset
867 /* Get the alias pointer-type to use or the outermost object
kono
parents: 67
diff changeset
868 that we could have a pointer to. */
kono
parents: 67
diff changeset
869 tree ptype = reference_alias_ptr_type_1 (&t);
kono
parents: 67
diff changeset
870 if (ptype != NULL)
kono
parents: 67
diff changeset
871 return get_deref_alias_set (ptype);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
872
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
873 /* If we've already determined the alias set for a decl, just return
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
874 it. This is necessary for C++ anonymous unions, whose component
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
875 variables don't look like union members (boo!). */
111
kono
parents: 67
diff changeset
876 if (VAR_P (t)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
877 && DECL_RTL_SET_P (t) && MEM_P (DECL_RTL (t)))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
878 return MEM_ALIAS_SET (DECL_RTL (t));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
879
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
880 /* Now all we care about is the type. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
881 t = TREE_TYPE (t);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
882 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
883
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
884 /* Variant qualifiers don't affect the alias set, so get the main
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
885 variant. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
886 t = TYPE_MAIN_VARIANT (t);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
887
111
kono
parents: 67
diff changeset
888 if (AGGREGATE_TYPE_P (t)
kono
parents: 67
diff changeset
889 && TYPE_TYPELESS_STORAGE (t))
kono
parents: 67
diff changeset
890 return 0;
kono
parents: 67
diff changeset
891
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
892 /* Always use the canonical type as well. If this is a type that
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
893 requires structural comparisons to identify compatible types
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
894 use alias set zero. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
895 if (TYPE_STRUCTURAL_EQUALITY_P (t))
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
896 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
897 /* Allow the language to specify another alias set for this
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
898 type. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
899 set = lang_hooks.get_alias_set (t);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
900 if (set != -1)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
901 return set;
111
kono
parents: 67
diff changeset
902 /* Handle structure type equality for pointer types, arrays and vectors.
kono
parents: 67
diff changeset
903 This is easy to do, because the code bellow ignore canonical types on
kono
parents: 67
diff changeset
904 these anyway. This is important for LTO, where TYPE_CANONICAL for
kono
parents: 67
diff changeset
905 pointers can not be meaningfuly computed by the frotnend. */
kono
parents: 67
diff changeset
906 if (canonical_type_used_p (t))
kono
parents: 67
diff changeset
907 {
kono
parents: 67
diff changeset
908 /* In LTO we set canonical types for all types where it makes
kono
parents: 67
diff changeset
909 sense to do so. Double check we did not miss some type. */
kono
parents: 67
diff changeset
910 gcc_checking_assert (!in_lto_p || !type_with_alias_set_p (t));
kono
parents: 67
diff changeset
911 return 0;
kono
parents: 67
diff changeset
912 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
913 }
111
kono
parents: 67
diff changeset
914 else
kono
parents: 67
diff changeset
915 {
kono
parents: 67
diff changeset
916 t = TYPE_CANONICAL (t);
kono
parents: 67
diff changeset
917 gcc_checking_assert (!TYPE_STRUCTURAL_EQUALITY_P (t));
kono
parents: 67
diff changeset
918 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
919
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
920 /* If this is a type with a known alias set, return it. */
111
kono
parents: 67
diff changeset
921 gcc_checking_assert (t == TYPE_MAIN_VARIANT (t));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
922 if (TYPE_ALIAS_SET_KNOWN_P (t))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
923 return TYPE_ALIAS_SET (t);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
924
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
925 /* We don't want to set TYPE_ALIAS_SET for incomplete types. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
926 if (!COMPLETE_TYPE_P (t))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
927 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
928 /* For arrays with unknown size the conservative answer is the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
929 alias set of the element type. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
930 if (TREE_CODE (t) == ARRAY_TYPE)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
931 return get_alias_set (TREE_TYPE (t));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
932
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
933 /* But return zero as a conservative answer for incomplete types. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
934 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
935 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
936
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
937 /* See if the language has special handling for this type. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
938 set = lang_hooks.get_alias_set (t);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
939 if (set != -1)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
940 return set;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
941
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
942 /* There are no objects of FUNCTION_TYPE, so there's no point in
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
943 using up an alias set for them. (There are, of course, pointers
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
944 and references to functions, but that's different.) */
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
945 else if (TREE_CODE (t) == FUNCTION_TYPE || TREE_CODE (t) == METHOD_TYPE)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
946 set = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
947
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
948 /* Unless the language specifies otherwise, let vector types alias
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
949 their components. This avoids some nasty type punning issues in
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
950 normal usage. And indeed lets vectors be treated more like an
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
951 array slice. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
952 else if (TREE_CODE (t) == VECTOR_TYPE)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
953 set = get_alias_set (TREE_TYPE (t));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
954
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
955 /* Unless the language specifies otherwise, treat array types the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
956 same as their components. This avoids the asymmetry we get
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
957 through recording the components. Consider accessing a
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
958 character(kind=1) through a reference to a character(kind=1)[1:1].
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
959 Or consider if we want to assign integer(kind=4)[0:D.1387] and
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
960 integer(kind=4)[4] the same alias set or not.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
961 Just be pragmatic here and make sure the array and its element
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
962 type get the same alias set assigned. */
111
kono
parents: 67
diff changeset
963 else if (TREE_CODE (t) == ARRAY_TYPE
kono
parents: 67
diff changeset
964 && (!TYPE_NONALIASED_COMPONENT (t)
kono
parents: 67
diff changeset
965 || TYPE_STRUCTURAL_EQUALITY_P (t)))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
966 set = get_alias_set (TREE_TYPE (t));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
967
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
968 /* From the former common C and C++ langhook implementation:
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
969
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
970 Unfortunately, there is no canonical form of a pointer type.
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
971 In particular, if we have `typedef int I', then `int *', and
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
972 `I *' are different types. So, we have to pick a canonical
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
973 representative. We do this below.
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
974
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
975 Technically, this approach is actually more conservative that
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
976 it needs to be. In particular, `const int *' and `int *'
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
977 should be in different alias sets, according to the C and C++
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
978 standard, since their types are not the same, and so,
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
979 technically, an `int **' and `const int **' cannot point at
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
980 the same thing.
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
981
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
982 But, the standard is wrong. In particular, this code is
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
983 legal C++:
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
984
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
985 int *ip;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
986 int **ipp = &ip;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
987 const int* const* cipp = ipp;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
988 And, it doesn't make sense for that to be legal unless you
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
989 can dereference IPP and CIPP. So, we ignore cv-qualifiers on
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
990 the pointed-to types. This issue has been reported to the
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
991 C++ committee.
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
992
111
kono
parents: 67
diff changeset
993 For this reason go to canonical type of the unqalified pointer type.
kono
parents: 67
diff changeset
994 Until GCC 6 this code set all pointers sets to have alias set of
kono
parents: 67
diff changeset
995 ptr_type_node but that is a bad idea, because it prevents disabiguations
kono
parents: 67
diff changeset
996 in between pointers. For Firefox this accounts about 20% of all
kono
parents: 67
diff changeset
997 disambiguations in the program. */
kono
parents: 67
diff changeset
998 else if (POINTER_TYPE_P (t) && t != ptr_type_node)
kono
parents: 67
diff changeset
999 {
kono
parents: 67
diff changeset
1000 tree p;
kono
parents: 67
diff changeset
1001 auto_vec <bool, 8> reference;
kono
parents: 67
diff changeset
1002
kono
parents: 67
diff changeset
1003 /* Unnest all pointers and references.
kono
parents: 67
diff changeset
1004 We also want to make pointer to array/vector equivalent to pointer to
kono
parents: 67
diff changeset
1005 its element (see the reasoning above). Skip all those types, too. */
kono
parents: 67
diff changeset
1006 for (p = t; POINTER_TYPE_P (p)
kono
parents: 67
diff changeset
1007 || (TREE_CODE (p) == ARRAY_TYPE
kono
parents: 67
diff changeset
1008 && (!TYPE_NONALIASED_COMPONENT (p)
kono
parents: 67
diff changeset
1009 || !COMPLETE_TYPE_P (p)
kono
parents: 67
diff changeset
1010 || TYPE_STRUCTURAL_EQUALITY_P (p)))
kono
parents: 67
diff changeset
1011 || TREE_CODE (p) == VECTOR_TYPE;
kono
parents: 67
diff changeset
1012 p = TREE_TYPE (p))
kono
parents: 67
diff changeset
1013 {
kono
parents: 67
diff changeset
1014 /* Ada supports recusive pointers. Instead of doing recrusion check
kono
parents: 67
diff changeset
1015 just give up once the preallocated space of 8 elements is up.
kono
parents: 67
diff changeset
1016 In this case just punt to void * alias set. */
kono
parents: 67
diff changeset
1017 if (reference.length () == 8)
kono
parents: 67
diff changeset
1018 {
kono
parents: 67
diff changeset
1019 p = ptr_type_node;
kono
parents: 67
diff changeset
1020 break;
kono
parents: 67
diff changeset
1021 }
kono
parents: 67
diff changeset
1022 if (TREE_CODE (p) == REFERENCE_TYPE)
kono
parents: 67
diff changeset
1023 /* In LTO we want languages that use references to be compatible
kono
parents: 67
diff changeset
1024 with languages that use pointers. */
kono
parents: 67
diff changeset
1025 reference.safe_push (true && !in_lto_p);
kono
parents: 67
diff changeset
1026 if (TREE_CODE (p) == POINTER_TYPE)
kono
parents: 67
diff changeset
1027 reference.safe_push (false);
kono
parents: 67
diff changeset
1028 }
kono
parents: 67
diff changeset
1029 p = TYPE_MAIN_VARIANT (p);
kono
parents: 67
diff changeset
1030
kono
parents: 67
diff changeset
1031 /* Make void * compatible with char * and also void **.
kono
parents: 67
diff changeset
1032 Programs are commonly violating TBAA by this.
kono
parents: 67
diff changeset
1033
kono
parents: 67
diff changeset
1034 We also make void * to conflict with every pointer
kono
parents: 67
diff changeset
1035 (see record_component_aliases) and thus it is safe it to use it for
kono
parents: 67
diff changeset
1036 pointers to types with TYPE_STRUCTURAL_EQUALITY_P. */
kono
parents: 67
diff changeset
1037 if (TREE_CODE (p) == VOID_TYPE || TYPE_STRUCTURAL_EQUALITY_P (p))
kono
parents: 67
diff changeset
1038 set = get_alias_set (ptr_type_node);
kono
parents: 67
diff changeset
1039 else
kono
parents: 67
diff changeset
1040 {
kono
parents: 67
diff changeset
1041 /* Rebuild pointer type starting from canonical types using
kono
parents: 67
diff changeset
1042 unqualified pointers and references only. This way all such
kono
parents: 67
diff changeset
1043 pointers will have the same alias set and will conflict with
kono
parents: 67
diff changeset
1044 each other.
kono
parents: 67
diff changeset
1045
kono
parents: 67
diff changeset
1046 Most of time we already have pointers or references of a given type.
kono
parents: 67
diff changeset
1047 If not we build new one just to be sure that if someone later
kono
parents: 67
diff changeset
1048 (probably only middle-end can, as we should assign all alias
kono
parents: 67
diff changeset
1049 classes only after finishing translation unit) builds the pointer
kono
parents: 67
diff changeset
1050 type, the canonical type will match. */
kono
parents: 67
diff changeset
1051 p = TYPE_CANONICAL (p);
kono
parents: 67
diff changeset
1052 while (!reference.is_empty ())
kono
parents: 67
diff changeset
1053 {
kono
parents: 67
diff changeset
1054 if (reference.pop ())
kono
parents: 67
diff changeset
1055 p = build_reference_type (p);
kono
parents: 67
diff changeset
1056 else
kono
parents: 67
diff changeset
1057 p = build_pointer_type (p);
kono
parents: 67
diff changeset
1058 gcc_checking_assert (p == TYPE_MAIN_VARIANT (p));
kono
parents: 67
diff changeset
1059 /* build_pointer_type should always return the canonical type.
kono
parents: 67
diff changeset
1060 For LTO TYPE_CANOINCAL may be NULL, because we do not compute
kono
parents: 67
diff changeset
1061 them. Be sure that frontends do not glob canonical types of
kono
parents: 67
diff changeset
1062 pointers in unexpected way and that p == TYPE_CANONICAL (p)
kono
parents: 67
diff changeset
1063 in all other cases. */
kono
parents: 67
diff changeset
1064 gcc_checking_assert (!TYPE_CANONICAL (p)
kono
parents: 67
diff changeset
1065 || p == TYPE_CANONICAL (p));
kono
parents: 67
diff changeset
1066 }
kono
parents: 67
diff changeset
1067
kono
parents: 67
diff changeset
1068 /* Assign the alias set to both p and t.
kono
parents: 67
diff changeset
1069 We can not call get_alias_set (p) here as that would trigger
kono
parents: 67
diff changeset
1070 infinite recursion when p == t. In other cases it would just
kono
parents: 67
diff changeset
1071 trigger unnecesary legwork of rebuilding the pointer again. */
kono
parents: 67
diff changeset
1072 gcc_checking_assert (p == TYPE_MAIN_VARIANT (p));
kono
parents: 67
diff changeset
1073 if (TYPE_ALIAS_SET_KNOWN_P (p))
kono
parents: 67
diff changeset
1074 set = TYPE_ALIAS_SET (p);
kono
parents: 67
diff changeset
1075 else
kono
parents: 67
diff changeset
1076 {
kono
parents: 67
diff changeset
1077 set = new_alias_set ();
kono
parents: 67
diff changeset
1078 TYPE_ALIAS_SET (p) = set;
kono
parents: 67
diff changeset
1079 }
kono
parents: 67
diff changeset
1080 }
kono
parents: 67
diff changeset
1081 }
kono
parents: 67
diff changeset
1082 /* Alias set of ptr_type_node is special and serve as universal pointer which
kono
parents: 67
diff changeset
1083 is TBAA compatible with every other pointer type. Be sure we have the
kono
parents: 67
diff changeset
1084 alias set built even for LTO which otherwise keeps all TYPE_CANONICAL
kono
parents: 67
diff changeset
1085 of pointer types NULL. */
kono
parents: 67
diff changeset
1086 else if (t == ptr_type_node)
kono
parents: 67
diff changeset
1087 set = new_alias_set ();
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1088
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1089 /* Otherwise make a new alias set for this type. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1090 else
111
kono
parents: 67
diff changeset
1091 {
kono
parents: 67
diff changeset
1092 /* Each canonical type gets its own alias set, so canonical types
kono
parents: 67
diff changeset
1093 shouldn't form a tree. It doesn't really matter for types
kono
parents: 67
diff changeset
1094 we handle specially above, so only check it where it possibly
kono
parents: 67
diff changeset
1095 would result in a bogus alias set. */
kono
parents: 67
diff changeset
1096 gcc_checking_assert (TYPE_CANONICAL (t) == t);
kono
parents: 67
diff changeset
1097
kono
parents: 67
diff changeset
1098 set = new_alias_set ();
kono
parents: 67
diff changeset
1099 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1100
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1101 TYPE_ALIAS_SET (t) = set;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1102
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1103 /* If this is an aggregate type or a complex type, we must record any
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1104 component aliasing information. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1105 if (AGGREGATE_TYPE_P (t) || TREE_CODE (t) == COMPLEX_TYPE)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1106 record_component_aliases (t);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1107
111
kono
parents: 67
diff changeset
1108 /* We treat pointer types specially in alias_set_subset_of. */
kono
parents: 67
diff changeset
1109 if (POINTER_TYPE_P (t) && set)
kono
parents: 67
diff changeset
1110 {
kono
parents: 67
diff changeset
1111 alias_set_entry *ase = get_alias_set_entry (set);
kono
parents: 67
diff changeset
1112 if (!ase)
kono
parents: 67
diff changeset
1113 ase = init_alias_set_entry (set);
kono
parents: 67
diff changeset
1114 ase->is_pointer = true;
kono
parents: 67
diff changeset
1115 ase->has_pointer = true;
kono
parents: 67
diff changeset
1116 }
kono
parents: 67
diff changeset
1117
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1118 return set;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1119 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1120
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1121 /* Return a brand-new alias set. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1122
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1123 alias_set_type
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1124 new_alias_set (void)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1125 {
111
kono
parents: 67
diff changeset
1126 if (alias_sets == 0)
kono
parents: 67
diff changeset
1127 vec_safe_push (alias_sets, (alias_set_entry *) NULL);
kono
parents: 67
diff changeset
1128 vec_safe_push (alias_sets, (alias_set_entry *) NULL);
kono
parents: 67
diff changeset
1129 return alias_sets->length () - 1;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1130 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1131
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1132 /* Indicate that things in SUBSET can alias things in SUPERSET, but that
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1133 not everything that aliases SUPERSET also aliases SUBSET. For example,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1134 in C, a store to an `int' can alias a load of a structure containing an
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1135 `int', and vice versa. But it can't alias a load of a 'double' member
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1136 of the same structure. Here, the structure would be the SUPERSET and
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1137 `int' the SUBSET. This relationship is also described in the comment at
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1138 the beginning of this file.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1139
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1140 This function should be called only once per SUPERSET/SUBSET pair.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1141
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1142 It is illegal for SUPERSET to be zero; everything is implicitly a
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1143 subset of alias set zero. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1144
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1145 void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1146 record_alias_subset (alias_set_type superset, alias_set_type subset)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1147 {
111
kono
parents: 67
diff changeset
1148 alias_set_entry *superset_entry;
kono
parents: 67
diff changeset
1149 alias_set_entry *subset_entry;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1150
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1151 /* It is possible in complex type situations for both sets to be the same,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1152 in which case we can ignore this operation. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1153 if (superset == subset)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1154 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1155
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1156 gcc_assert (superset);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1157
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1158 superset_entry = get_alias_set_entry (superset);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1159 if (superset_entry == 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1160 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1161 /* Create an entry for the SUPERSET, so that we have a place to
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1162 attach the SUBSET. */
111
kono
parents: 67
diff changeset
1163 superset_entry = init_alias_set_entry (superset);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1164 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1165
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1166 if (subset == 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1167 superset_entry->has_zero_child = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1168 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1169 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1170 subset_entry = get_alias_set_entry (subset);
111
kono
parents: 67
diff changeset
1171 if (!superset_entry->children)
kono
parents: 67
diff changeset
1172 superset_entry->children
kono
parents: 67
diff changeset
1173 = hash_map<alias_set_hash, int>::create_ggc (64);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1174 /* If there is an entry for the subset, enter all of its children
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1175 (if they are not already present) as children of the SUPERSET. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1176 if (subset_entry)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1177 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1178 if (subset_entry->has_zero_child)
111
kono
parents: 67
diff changeset
1179 superset_entry->has_zero_child = true;
kono
parents: 67
diff changeset
1180 if (subset_entry->has_pointer)
kono
parents: 67
diff changeset
1181 superset_entry->has_pointer = true;
kono
parents: 67
diff changeset
1182
kono
parents: 67
diff changeset
1183 if (subset_entry->children)
kono
parents: 67
diff changeset
1184 {
kono
parents: 67
diff changeset
1185 hash_map<alias_set_hash, int>::iterator iter
kono
parents: 67
diff changeset
1186 = subset_entry->children->begin ();
kono
parents: 67
diff changeset
1187 for (; iter != subset_entry->children->end (); ++iter)
kono
parents: 67
diff changeset
1188 superset_entry->children->put ((*iter).first, (*iter).second);
kono
parents: 67
diff changeset
1189 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1190 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1191
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1192 /* Enter the SUBSET itself as a child of the SUPERSET. */
111
kono
parents: 67
diff changeset
1193 superset_entry->children->put (subset, 0);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1194 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1195 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1196
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1197 /* Record that component types of TYPE, if any, are part of that type for
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1198 aliasing purposes. For record types, we only record component types
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1199 for fields that are not marked non-addressable. For array types, we
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1200 only record the component type if it is not marked non-aliased. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1201
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1202 void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1203 record_component_aliases (tree type)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1204 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1205 alias_set_type superset = get_alias_set (type);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1206 tree field;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1207
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1208 if (superset == 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1209 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1210
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1211 switch (TREE_CODE (type))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1212 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1213 case RECORD_TYPE:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1214 case UNION_TYPE:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1215 case QUAL_UNION_TYPE:
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1216 for (field = TYPE_FIELDS (type); field != 0; field = DECL_CHAIN (field))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1217 if (TREE_CODE (field) == FIELD_DECL && !DECL_NONADDRESSABLE_P (field))
111
kono
parents: 67
diff changeset
1218 {
kono
parents: 67
diff changeset
1219 /* LTO type merging does not make any difference between
kono
parents: 67
diff changeset
1220 component pointer types. We may have
kono
parents: 67
diff changeset
1221
kono
parents: 67
diff changeset
1222 struct foo {int *a;};
kono
parents: 67
diff changeset
1223
kono
parents: 67
diff changeset
1224 as TYPE_CANONICAL of
kono
parents: 67
diff changeset
1225
kono
parents: 67
diff changeset
1226 struct bar {float *a;};
kono
parents: 67
diff changeset
1227
kono
parents: 67
diff changeset
1228 Because accesses to int * and float * do not alias, we would get
kono
parents: 67
diff changeset
1229 false negative when accessing the same memory location by
kono
parents: 67
diff changeset
1230 float ** and bar *. We thus record the canonical type as:
kono
parents: 67
diff changeset
1231
kono
parents: 67
diff changeset
1232 struct {void *a;};
kono
parents: 67
diff changeset
1233
kono
parents: 67
diff changeset
1234 void * is special cased and works as a universal pointer type.
kono
parents: 67
diff changeset
1235 Accesses to it conflicts with accesses to any other pointer
kono
parents: 67
diff changeset
1236 type. */
kono
parents: 67
diff changeset
1237 tree t = TREE_TYPE (field);
kono
parents: 67
diff changeset
1238 if (in_lto_p)
kono
parents: 67
diff changeset
1239 {
kono
parents: 67
diff changeset
1240 /* VECTOR_TYPE and ARRAY_TYPE share the alias set with their
kono
parents: 67
diff changeset
1241 element type and that type has to be normalized to void *,
kono
parents: 67
diff changeset
1242 too, in the case it is a pointer. */
kono
parents: 67
diff changeset
1243 while (!canonical_type_used_p (t) && !POINTER_TYPE_P (t))
kono
parents: 67
diff changeset
1244 {
kono
parents: 67
diff changeset
1245 gcc_checking_assert (TYPE_STRUCTURAL_EQUALITY_P (t));
kono
parents: 67
diff changeset
1246 t = TREE_TYPE (t);
kono
parents: 67
diff changeset
1247 }
kono
parents: 67
diff changeset
1248 if (POINTER_TYPE_P (t))
kono
parents: 67
diff changeset
1249 t = ptr_type_node;
kono
parents: 67
diff changeset
1250 else if (flag_checking)
kono
parents: 67
diff changeset
1251 gcc_checking_assert (get_alias_set (t)
kono
parents: 67
diff changeset
1252 == get_alias_set (TREE_TYPE (field)));
kono
parents: 67
diff changeset
1253 }
kono
parents: 67
diff changeset
1254
kono
parents: 67
diff changeset
1255 record_alias_subset (superset, get_alias_set (t));
kono
parents: 67
diff changeset
1256 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1257 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1258
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1259 case COMPLEX_TYPE:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1260 record_alias_subset (superset, get_alias_set (TREE_TYPE (type)));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1261 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1262
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1263 /* VECTOR_TYPE and ARRAY_TYPE share the alias set with their
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1264 element type. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1265
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1266 default:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1267 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1268 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1269 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1270
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1271 /* Allocate an alias set for use in storing and reading from the varargs
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1272 spill area. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1273
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1274 static GTY(()) alias_set_type varargs_set = -1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1275
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1276 alias_set_type
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1277 get_varargs_alias_set (void)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1278 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1279 #if 1
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1280 /* We now lower VA_ARG_EXPR, and there's currently no way to attach the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1281 varargs alias set to an INDIRECT_REF (FIXME!), so we can't
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1282 consistently use the varargs alias set for loads from the varargs
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1283 area. So don't use it anywhere. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1284 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1285 #else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1286 if (varargs_set == -1)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1287 varargs_set = new_alias_set ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1288
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1289 return varargs_set;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1290 #endif
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1291 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1292
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1293 /* Likewise, but used for the fixed portions of the frame, e.g., register
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1294 save areas. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1295
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1296 static GTY(()) alias_set_type frame_set = -1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1297
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1298 alias_set_type
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1299 get_frame_alias_set (void)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1300 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1301 if (frame_set == -1)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1302 frame_set = new_alias_set ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1303
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1304 return frame_set;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1305 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1306
111
kono
parents: 67
diff changeset
1307 /* Create a new, unique base with id ID. */
kono
parents: 67
diff changeset
1308
kono
parents: 67
diff changeset
1309 static rtx
kono
parents: 67
diff changeset
1310 unique_base_value (HOST_WIDE_INT id)
kono
parents: 67
diff changeset
1311 {
kono
parents: 67
diff changeset
1312 return gen_rtx_ADDRESS (Pmode, id);
kono
parents: 67
diff changeset
1313 }
kono
parents: 67
diff changeset
1314
kono
parents: 67
diff changeset
1315 /* Return true if accesses based on any other base value cannot alias
kono
parents: 67
diff changeset
1316 those based on X. */
kono
parents: 67
diff changeset
1317
kono
parents: 67
diff changeset
1318 static bool
kono
parents: 67
diff changeset
1319 unique_base_value_p (rtx x)
kono
parents: 67
diff changeset
1320 {
kono
parents: 67
diff changeset
1321 return GET_CODE (x) == ADDRESS && GET_MODE (x) == Pmode;
kono
parents: 67
diff changeset
1322 }
kono
parents: 67
diff changeset
1323
kono
parents: 67
diff changeset
1324 /* Return true if X is known to be a base value. */
kono
parents: 67
diff changeset
1325
kono
parents: 67
diff changeset
1326 static bool
kono
parents: 67
diff changeset
1327 known_base_value_p (rtx x)
kono
parents: 67
diff changeset
1328 {
kono
parents: 67
diff changeset
1329 switch (GET_CODE (x))
kono
parents: 67
diff changeset
1330 {
kono
parents: 67
diff changeset
1331 case LABEL_REF:
kono
parents: 67
diff changeset
1332 case SYMBOL_REF:
kono
parents: 67
diff changeset
1333 return true;
kono
parents: 67
diff changeset
1334
kono
parents: 67
diff changeset
1335 case ADDRESS:
kono
parents: 67
diff changeset
1336 /* Arguments may or may not be bases; we don't know for sure. */
kono
parents: 67
diff changeset
1337 return GET_MODE (x) != VOIDmode;
kono
parents: 67
diff changeset
1338
kono
parents: 67
diff changeset
1339 default:
kono
parents: 67
diff changeset
1340 return false;
kono
parents: 67
diff changeset
1341 }
kono
parents: 67
diff changeset
1342 }
kono
parents: 67
diff changeset
1343
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1344 /* Inside SRC, the source of a SET, find a base address. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1345
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1346 static rtx
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1347 find_base_value (rtx src)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1348 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1349 unsigned int regno;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1350 scalar_int_mode int_mode;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1351
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1352 #if defined (FIND_BASE_TERM)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1353 /* Try machine-dependent ways to find the base term. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1354 src = FIND_BASE_TERM (src);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1355 #endif
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1356
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1357 switch (GET_CODE (src))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1358 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1359 case SYMBOL_REF:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1360 case LABEL_REF:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1361 return src;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1362
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1363 case REG:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1364 regno = REGNO (src);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1365 /* At the start of a function, argument registers have known base
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1366 values which may be lost later. Returning an ADDRESS
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1367 expression here allows optimization based on argument values
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1368 even when the argument registers are used for other purposes. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1369 if (regno < FIRST_PSEUDO_REGISTER && copying_arguments)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1370 return new_reg_base_value[regno];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1371
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1372 /* If a pseudo has a known base value, return it. Do not do this
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1373 for non-fixed hard regs since it can result in a circular
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1374 dependency chain for registers which have values at function entry.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1375
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1376 The test above is not sufficient because the scheduler may move
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1377 a copy out of an arg reg past the NOTE_INSN_FUNCTION_BEGIN. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1378 if ((regno >= FIRST_PSEUDO_REGISTER || fixed_regs[regno])
111
kono
parents: 67
diff changeset
1379 && regno < vec_safe_length (reg_base_value))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1380 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1381 /* If we're inside init_alias_analysis, use new_reg_base_value
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1382 to reduce the number of relaxation iterations. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1383 if (new_reg_base_value && new_reg_base_value[regno]
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1384 && DF_REG_DEF_COUNT (regno) == 1)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1385 return new_reg_base_value[regno];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1386
111
kono
parents: 67
diff changeset
1387 if ((*reg_base_value)[regno])
kono
parents: 67
diff changeset
1388 return (*reg_base_value)[regno];
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1389 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1390
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1391 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1392
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1393 case MEM:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1394 /* Check for an argument passed in memory. Only record in the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1395 copying-arguments block; it is too hard to track changes
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1396 otherwise. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1397 if (copying_arguments
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1398 && (XEXP (src, 0) == arg_pointer_rtx
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1399 || (GET_CODE (XEXP (src, 0)) == PLUS
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1400 && XEXP (XEXP (src, 0), 0) == arg_pointer_rtx)))
111
kono
parents: 67
diff changeset
1401 return arg_base_value;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1402 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1403
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1404 case CONST:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1405 src = XEXP (src, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1406 if (GET_CODE (src) != PLUS && GET_CODE (src) != MINUS)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1407 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1408
111
kono
parents: 67
diff changeset
1409 /* fall through */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1410
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1411 case PLUS:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1412 case MINUS:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1413 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1414 rtx temp, src_0 = XEXP (src, 0), src_1 = XEXP (src, 1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1415
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1416 /* If either operand is a REG that is a known pointer, then it
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1417 is the base. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1418 if (REG_P (src_0) && REG_POINTER (src_0))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1419 return find_base_value (src_0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1420 if (REG_P (src_1) && REG_POINTER (src_1))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1421 return find_base_value (src_1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1422
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1423 /* If either operand is a REG, then see if we already have
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1424 a known value for it. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1425 if (REG_P (src_0))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1426 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1427 temp = find_base_value (src_0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1428 if (temp != 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1429 src_0 = temp;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1430 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1431
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1432 if (REG_P (src_1))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1433 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1434 temp = find_base_value (src_1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1435 if (temp!= 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1436 src_1 = temp;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1437 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1438
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1439 /* If either base is named object or a special address
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1440 (like an argument or stack reference), then use it for the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1441 base term. */
111
kono
parents: 67
diff changeset
1442 if (src_0 != 0 && known_base_value_p (src_0))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1443 return src_0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1444
111
kono
parents: 67
diff changeset
1445 if (src_1 != 0 && known_base_value_p (src_1))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1446 return src_1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1447
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1448 /* Guess which operand is the base address:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1449 If either operand is a symbol, then it is the base. If
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1450 either operand is a CONST_INT, then the other is the base. */
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
1451 if (CONST_INT_P (src_1) || CONSTANT_P (src_0))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1452 return find_base_value (src_0);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
1453 else if (CONST_INT_P (src_0) || CONSTANT_P (src_1))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1454 return find_base_value (src_1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1455
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1456 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1457 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1458
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1459 case LO_SUM:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1460 /* The standard form is (lo_sum reg sym) so look only at the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1461 second operand. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1462 return find_base_value (XEXP (src, 1));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1463
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1464 case AND:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1465 /* If the second operand is constant set the base
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1466 address to the first operand. */
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
1467 if (CONST_INT_P (XEXP (src, 1)) && INTVAL (XEXP (src, 1)) != 0)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1468 return find_base_value (XEXP (src, 0));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1469 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1470
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1471 case TRUNCATE:
111
kono
parents: 67
diff changeset
1472 /* As we do not know which address space the pointer is referring to, we can
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
1473 handle this only if the target does not support different pointer or
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
1474 address modes depending on the address space. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
1475 if (!target_default_pointer_address_modes_p ())
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
1476 break;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1477 if (!is_a <scalar_int_mode> (GET_MODE (src), &int_mode)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1478 || GET_MODE_PRECISION (int_mode) < GET_MODE_PRECISION (Pmode))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1479 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1480 /* Fall through. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1481 case HIGH:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1482 case PRE_INC:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1483 case PRE_DEC:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1484 case POST_INC:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1485 case POST_DEC:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1486 case PRE_MODIFY:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1487 case POST_MODIFY:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1488 return find_base_value (XEXP (src, 0));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1489
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1490 case ZERO_EXTEND:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1491 case SIGN_EXTEND: /* used for NT/Alpha pointers */
111
kono
parents: 67
diff changeset
1492 /* As we do not know which address space the pointer is referring to, we can
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
1493 handle this only if the target does not support different pointer or
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
1494 address modes depending on the address space. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
1495 if (!target_default_pointer_address_modes_p ())
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
1496 break;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
1497
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1498 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1499 rtx temp = find_base_value (XEXP (src, 0));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1500
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1501 if (temp != 0 && CONSTANT_P (temp))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1502 temp = convert_memory_address (Pmode, temp);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1503
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1504 return temp;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1505 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1506
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1507 default:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1508 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1509 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1510
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1511 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1512 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1513
111
kono
parents: 67
diff changeset
1514 /* Called from init_alias_analysis indirectly through note_stores,
kono
parents: 67
diff changeset
1515 or directly if DEST is a register with a REG_NOALIAS note attached.
kono
parents: 67
diff changeset
1516 SET is null in the latter case. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1517
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1518 /* While scanning insns to find base values, reg_seen[N] is nonzero if
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1519 register N has been set in this function. */
111
kono
parents: 67
diff changeset
1520 static sbitmap reg_seen;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1521
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1522 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1523 record_set (rtx dest, const_rtx set, void *data ATTRIBUTE_UNUSED)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1524 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1525 unsigned regno;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1526 rtx src;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1527 int n;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1528
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1529 if (!REG_P (dest))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1530 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1531
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1532 regno = REGNO (dest);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1533
111
kono
parents: 67
diff changeset
1534 gcc_checking_assert (regno < reg_base_value->length ());
kono
parents: 67
diff changeset
1535
kono
parents: 67
diff changeset
1536 n = REG_NREGS (dest);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1537 if (n != 1)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1538 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1539 while (--n >= 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1540 {
111
kono
parents: 67
diff changeset
1541 bitmap_set_bit (reg_seen, regno + n);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1542 new_reg_base_value[regno + n] = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1543 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1544 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1545 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1546
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1547 if (set)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1548 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1549 /* A CLOBBER wipes out any old value but does not prevent a previously
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1550 unset register from acquiring a base address (i.e. reg_seen is not
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1551 set). */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1552 if (GET_CODE (set) == CLOBBER)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1553 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1554 new_reg_base_value[regno] = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1555 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1556 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1557 /* A CLOBBER_HIGH only wipes out the old value if the mode of the old
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1558 value is greater than that of the clobber. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1559 else if (GET_CODE (set) == CLOBBER_HIGH)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1560 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1561 if (new_reg_base_value[regno] != 0
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1562 && reg_is_clobbered_by_clobber_high (
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1563 regno, GET_MODE (new_reg_base_value[regno]), XEXP (set, 0)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1564 new_reg_base_value[regno] = 0;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1565 return;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1566 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1567
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1568 src = SET_SRC (set);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1569 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1570 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1571 {
111
kono
parents: 67
diff changeset
1572 /* There's a REG_NOALIAS note against DEST. */
kono
parents: 67
diff changeset
1573 if (bitmap_bit_p (reg_seen, regno))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1574 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1575 new_reg_base_value[regno] = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1576 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1577 }
111
kono
parents: 67
diff changeset
1578 bitmap_set_bit (reg_seen, regno);
kono
parents: 67
diff changeset
1579 new_reg_base_value[regno] = unique_base_value (unique_id++);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1580 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1581 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1582
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1583 /* If this is not the first set of REGNO, see whether the new value
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1584 is related to the old one. There are two cases of interest:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1585
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1586 (1) The register might be assigned an entirely new value
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1587 that has the same base term as the original set.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1588
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1589 (2) The set might be a simple self-modification that
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1590 cannot change REGNO's base value.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1591
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1592 If neither case holds, reject the original base value as invalid.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1593 Note that the following situation is not detected:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1594
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1595 extern int x, y; int *p = &x; p += (&y-&x);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1596
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1597 ANSI C does not allow computing the difference of addresses
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1598 of distinct top level objects. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1599 if (new_reg_base_value[regno] != 0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1600 && find_base_value (src) != new_reg_base_value[regno])
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1601 switch (GET_CODE (src))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1602 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1603 case LO_SUM:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1604 case MINUS:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1605 if (XEXP (src, 0) != dest && XEXP (src, 1) != dest)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1606 new_reg_base_value[regno] = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1607 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1608 case PLUS:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1609 /* If the value we add in the PLUS is also a valid base value,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1610 this might be the actual base value, and the original value
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1611 an index. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1612 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1613 rtx other = NULL_RTX;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1614
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1615 if (XEXP (src, 0) == dest)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1616 other = XEXP (src, 1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1617 else if (XEXP (src, 1) == dest)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1618 other = XEXP (src, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1619
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1620 if (! other || find_base_value (other))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1621 new_reg_base_value[regno] = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1622 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1623 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1624 case AND:
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
1625 if (XEXP (src, 0) != dest || !CONST_INT_P (XEXP (src, 1)))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1626 new_reg_base_value[regno] = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1627 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1628 default:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1629 new_reg_base_value[regno] = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1630 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1631 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1632 /* If this is the first set of a register, record the value. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1633 else if ((regno >= FIRST_PSEUDO_REGISTER || ! fixed_regs[regno])
111
kono
parents: 67
diff changeset
1634 && ! bitmap_bit_p (reg_seen, regno) && new_reg_base_value[regno] == 0)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1635 new_reg_base_value[regno] = find_base_value (src);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1636
111
kono
parents: 67
diff changeset
1637 bitmap_set_bit (reg_seen, regno);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1638 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1639
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1640 /* Return REG_BASE_VALUE for REGNO. Selective scheduler uses this to avoid
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1641 using hard registers with non-null REG_BASE_VALUE for renaming. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1642 rtx
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1643 get_reg_base_value (unsigned int regno)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1644 {
111
kono
parents: 67
diff changeset
1645 return (*reg_base_value)[regno];
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1646 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1647
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1648 /* If a value is known for REGNO, return it. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1649
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1650 rtx
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1651 get_reg_known_value (unsigned int regno)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1652 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1653 if (regno >= FIRST_PSEUDO_REGISTER)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1654 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1655 regno -= FIRST_PSEUDO_REGISTER;
111
kono
parents: 67
diff changeset
1656 if (regno < vec_safe_length (reg_known_value))
kono
parents: 67
diff changeset
1657 return (*reg_known_value)[regno];
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1658 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1659 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1660 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1661
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1662 /* Set it. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1663
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1664 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1665 set_reg_known_value (unsigned int regno, rtx val)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1666 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1667 if (regno >= FIRST_PSEUDO_REGISTER)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1668 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1669 regno -= FIRST_PSEUDO_REGISTER;
111
kono
parents: 67
diff changeset
1670 if (regno < vec_safe_length (reg_known_value))
kono
parents: 67
diff changeset
1671 (*reg_known_value)[regno] = val;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1672 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1673 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1674
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1675 /* Similarly for reg_known_equiv_p. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1676
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1677 bool
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1678 get_reg_known_equiv_p (unsigned int regno)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1679 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1680 if (regno >= FIRST_PSEUDO_REGISTER)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1681 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1682 regno -= FIRST_PSEUDO_REGISTER;
111
kono
parents: 67
diff changeset
1683 if (regno < vec_safe_length (reg_known_value))
kono
parents: 67
diff changeset
1684 return bitmap_bit_p (reg_known_equiv_p, regno);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1685 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1686 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1687 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1688
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1689 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1690 set_reg_known_equiv_p (unsigned int regno, bool val)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1691 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1692 if (regno >= FIRST_PSEUDO_REGISTER)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1693 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1694 regno -= FIRST_PSEUDO_REGISTER;
111
kono
parents: 67
diff changeset
1695 if (regno < vec_safe_length (reg_known_value))
kono
parents: 67
diff changeset
1696 {
kono
parents: 67
diff changeset
1697 if (val)
kono
parents: 67
diff changeset
1698 bitmap_set_bit (reg_known_equiv_p, regno);
kono
parents: 67
diff changeset
1699 else
kono
parents: 67
diff changeset
1700 bitmap_clear_bit (reg_known_equiv_p, regno);
kono
parents: 67
diff changeset
1701 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1702 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1703 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1704
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1705
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1706 /* Returns a canonical version of X, from the point of view alias
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1707 analysis. (For example, if X is a MEM whose address is a register,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1708 and the register has a known value (say a SYMBOL_REF), then a MEM
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1709 whose address is the SYMBOL_REF is returned.) */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1710
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1711 rtx
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1712 canon_rtx (rtx x)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1713 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1714 /* Recursively look for equivalences. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1715 if (REG_P (x) && REGNO (x) >= FIRST_PSEUDO_REGISTER)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1716 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1717 rtx t = get_reg_known_value (REGNO (x));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1718 if (t == x)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1719 return x;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1720 if (t)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1721 return canon_rtx (t);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1722 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1723
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1724 if (GET_CODE (x) == PLUS)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1725 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1726 rtx x0 = canon_rtx (XEXP (x, 0));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1727 rtx x1 = canon_rtx (XEXP (x, 1));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1728
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1729 if (x0 != XEXP (x, 0) || x1 != XEXP (x, 1))
111
kono
parents: 67
diff changeset
1730 return simplify_gen_binary (PLUS, GET_MODE (x), x0, x1);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1731 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1732
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1733 /* This gives us much better alias analysis when called from
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1734 the loop optimizer. Note we want to leave the original
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1735 MEM alone, but need to return the canonicalized MEM with
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1736 all the flags with their original values. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1737 else if (MEM_P (x))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1738 x = replace_equiv_address_nv (x, canon_rtx (XEXP (x, 0)));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1739
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1740 return x;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1741 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1742
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1743 /* Return 1 if X and Y are identical-looking rtx's.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1744 Expect that X and Y has been already canonicalized.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1745
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1746 We use the data in reg_known_value above to see if two registers with
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1747 different numbers are, in fact, equivalent. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1748
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1749 static int
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1750 rtx_equal_for_memref_p (const_rtx x, const_rtx y)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1751 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1752 int i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1753 int j;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1754 enum rtx_code code;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1755 const char *fmt;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1756
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1757 if (x == 0 && y == 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1758 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1759 if (x == 0 || y == 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1760 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1761
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1762 if (x == y)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1763 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1764
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1765 code = GET_CODE (x);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1766 /* Rtx's of different codes cannot be equal. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1767 if (code != GET_CODE (y))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1768 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1769
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1770 /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1771 (REG:SI x) and (REG:HI x) are NOT equivalent. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1772
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1773 if (GET_MODE (x) != GET_MODE (y))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1774 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1775
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1776 /* Some RTL can be compared without a recursive examination. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1777 switch (code)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1778 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1779 case REG:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1780 return REGNO (x) == REGNO (y);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1781
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1782 case LABEL_REF:
111
kono
parents: 67
diff changeset
1783 return label_ref_label (x) == label_ref_label (y);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1784
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1785 case SYMBOL_REF:
111
kono
parents: 67
diff changeset
1786 return compare_base_symbol_refs (x, y) == 1;
kono
parents: 67
diff changeset
1787
kono
parents: 67
diff changeset
1788 case ENTRY_VALUE:
kono
parents: 67
diff changeset
1789 /* This is magic, don't go through canonicalization et al. */
kono
parents: 67
diff changeset
1790 return rtx_equal_p (ENTRY_VALUE_EXP (x), ENTRY_VALUE_EXP (y));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1791
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1792 case VALUE:
111
kono
parents: 67
diff changeset
1793 CASE_CONST_UNIQUE:
kono
parents: 67
diff changeset
1794 /* Pointer equality guarantees equality for these nodes. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1795 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1796
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1797 default:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1798 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1799 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1800
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1801 /* canon_rtx knows how to handle plus. No need to canonicalize. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1802 if (code == PLUS)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1803 return ((rtx_equal_for_memref_p (XEXP (x, 0), XEXP (y, 0))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1804 && rtx_equal_for_memref_p (XEXP (x, 1), XEXP (y, 1)))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1805 || (rtx_equal_for_memref_p (XEXP (x, 0), XEXP (y, 1))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1806 && rtx_equal_for_memref_p (XEXP (x, 1), XEXP (y, 0))));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1807 /* For commutative operations, the RTX match if the operand match in any
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1808 order. Also handle the simple binary and unary cases without a loop. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1809 if (COMMUTATIVE_P (x))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1810 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1811 rtx xop0 = canon_rtx (XEXP (x, 0));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1812 rtx yop0 = canon_rtx (XEXP (y, 0));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1813 rtx yop1 = canon_rtx (XEXP (y, 1));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1814
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1815 return ((rtx_equal_for_memref_p (xop0, yop0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1816 && rtx_equal_for_memref_p (canon_rtx (XEXP (x, 1)), yop1))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1817 || (rtx_equal_for_memref_p (xop0, yop1)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1818 && rtx_equal_for_memref_p (canon_rtx (XEXP (x, 1)), yop0)));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1819 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1820 else if (NON_COMMUTATIVE_P (x))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1821 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1822 return (rtx_equal_for_memref_p (canon_rtx (XEXP (x, 0)),
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1823 canon_rtx (XEXP (y, 0)))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1824 && rtx_equal_for_memref_p (canon_rtx (XEXP (x, 1)),
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1825 canon_rtx (XEXP (y, 1))));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1826 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1827 else if (UNARY_P (x))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1828 return rtx_equal_for_memref_p (canon_rtx (XEXP (x, 0)),
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1829 canon_rtx (XEXP (y, 0)));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1830
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1831 /* Compare the elements. If any pair of corresponding elements
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1832 fail to match, return 0 for the whole things.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1833
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1834 Limit cases to types which actually appear in addresses. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1835
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1836 fmt = GET_RTX_FORMAT (code);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1837 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1838 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1839 switch (fmt[i])
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1840 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1841 case 'i':
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1842 if (XINT (x, i) != XINT (y, i))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1843 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1844 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1845
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1846 case 'p':
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1847 if (maybe_ne (SUBREG_BYTE (x), SUBREG_BYTE (y)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1848 return 0;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1849 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1850
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1851 case 'E':
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1852 /* Two vectors must have the same length. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1853 if (XVECLEN (x, i) != XVECLEN (y, i))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1854 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1855
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1856 /* And the corresponding elements must match. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1857 for (j = 0; j < XVECLEN (x, i); j++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1858 if (rtx_equal_for_memref_p (canon_rtx (XVECEXP (x, i, j)),
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1859 canon_rtx (XVECEXP (y, i, j))) == 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1860 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1861 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1862
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1863 case 'e':
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1864 if (rtx_equal_for_memref_p (canon_rtx (XEXP (x, i)),
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1865 canon_rtx (XEXP (y, i))) == 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1866 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1867 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1868
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1869 /* This can happen for asm operands. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1870 case 's':
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1871 if (strcmp (XSTR (x, i), XSTR (y, i)))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1872 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1873 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1874
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1875 /* This can happen for an asm which clobbers memory. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1876 case '0':
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1877 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1878
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1879 /* It is believed that rtx's at this level will never
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1880 contain anything but integers and other rtx's,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1881 except for within LABEL_REFs and SYMBOL_REFs. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1882 default:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1883 gcc_unreachable ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1884 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1885 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1886 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1887 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1888
111
kono
parents: 67
diff changeset
1889 static rtx
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1890 find_base_term (rtx x, vec<std::pair<cselib_val *,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1891 struct elt_loc_list *> > &visited_vals)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1892 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1893 cselib_val *val;
111
kono
parents: 67
diff changeset
1894 struct elt_loc_list *l, *f;
kono
parents: 67
diff changeset
1895 rtx ret;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1896 scalar_int_mode int_mode;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1897
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1898 #if defined (FIND_BASE_TERM)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1899 /* Try machine-dependent ways to find the base term. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1900 x = FIND_BASE_TERM (x);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1901 #endif
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1902
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1903 switch (GET_CODE (x))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1904 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1905 case REG:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1906 return REG_BASE_VALUE (x);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1907
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1908 case TRUNCATE:
111
kono
parents: 67
diff changeset
1909 /* As we do not know which address space the pointer is referring to, we can
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
1910 handle this only if the target does not support different pointer or
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
1911 address modes depending on the address space. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
1912 if (!target_default_pointer_address_modes_p ())
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
1913 return 0;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1914 if (!is_a <scalar_int_mode> (GET_MODE (x), &int_mode)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1915 || GET_MODE_PRECISION (int_mode) < GET_MODE_PRECISION (Pmode))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1916 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1917 /* Fall through. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1918 case HIGH:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1919 case PRE_INC:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1920 case PRE_DEC:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1921 case POST_INC:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1922 case POST_DEC:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1923 case PRE_MODIFY:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1924 case POST_MODIFY:
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1925 return find_base_term (XEXP (x, 0), visited_vals);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1926
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1927 case ZERO_EXTEND:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1928 case SIGN_EXTEND: /* Used for Alpha/NT pointers */
111
kono
parents: 67
diff changeset
1929 /* As we do not know which address space the pointer is referring to, we can
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
1930 handle this only if the target does not support different pointer or
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
1931 address modes depending on the address space. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
1932 if (!target_default_pointer_address_modes_p ())
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
1933 return 0;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
1934
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1935 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1936 rtx temp = find_base_term (XEXP (x, 0), visited_vals);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1937
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1938 if (temp != 0 && CONSTANT_P (temp))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1939 temp = convert_memory_address (Pmode, temp);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1940
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1941 return temp;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1942 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1943
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1944 case VALUE:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1945 val = CSELIB_VAL_PTR (x);
111
kono
parents: 67
diff changeset
1946 ret = NULL_RTX;
kono
parents: 67
diff changeset
1947
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1948 if (!val)
111
kono
parents: 67
diff changeset
1949 return ret;
kono
parents: 67
diff changeset
1950
kono
parents: 67
diff changeset
1951 if (cselib_sp_based_value_p (val))
kono
parents: 67
diff changeset
1952 return static_reg_base_value[STACK_POINTER_REGNUM];
kono
parents: 67
diff changeset
1953
kono
parents: 67
diff changeset
1954 f = val->locs;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1955 /* Reset val->locs to avoid infinite recursion. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1956 if (f)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1957 visited_vals.safe_push (std::make_pair (val, f));
111
kono
parents: 67
diff changeset
1958 val->locs = NULL;
kono
parents: 67
diff changeset
1959
kono
parents: 67
diff changeset
1960 for (l = f; l; l = l->next)
kono
parents: 67
diff changeset
1961 if (GET_CODE (l->loc) == VALUE
kono
parents: 67
diff changeset
1962 && CSELIB_VAL_PTR (l->loc)->locs
kono
parents: 67
diff changeset
1963 && !CSELIB_VAL_PTR (l->loc)->locs->next
kono
parents: 67
diff changeset
1964 && CSELIB_VAL_PTR (l->loc)->locs->loc == x)
kono
parents: 67
diff changeset
1965 continue;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1966 else if ((ret = find_base_term (l->loc, visited_vals)) != 0)
111
kono
parents: 67
diff changeset
1967 break;
kono
parents: 67
diff changeset
1968
kono
parents: 67
diff changeset
1969 return ret;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1970
19
58ad6c70ea60 update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents: 0
diff changeset
1971 case LO_SUM:
58ad6c70ea60 update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents: 0
diff changeset
1972 /* The standard form is (lo_sum reg sym) so look only at the
58ad6c70ea60 update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents: 0
diff changeset
1973 second operand. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1974 return find_base_term (XEXP (x, 1), visited_vals);
19
58ad6c70ea60 update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents: 0
diff changeset
1975
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1976 case CONST:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1977 x = XEXP (x, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1978 if (GET_CODE (x) != PLUS && GET_CODE (x) != MINUS)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1979 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1980 /* Fall through. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1981 case PLUS:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1982 case MINUS:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1983 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1984 rtx tmp1 = XEXP (x, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1985 rtx tmp2 = XEXP (x, 1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1986
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1987 /* This is a little bit tricky since we have to determine which of
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1988 the two operands represents the real base address. Otherwise this
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1989 routine may return the index register instead of the base register.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1990
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1991 That may cause us to believe no aliasing was possible, when in
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1992 fact aliasing is possible.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1993
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1994 We use a few simple tests to guess the base register. Additional
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1995 tests can certainly be added. For example, if one of the operands
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1996 is a shift or multiply, then it must be the index register and the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1997 other operand is the base register. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1998
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1999 if (tmp1 == pic_offset_table_rtx && CONSTANT_P (tmp2))
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2000 return find_base_term (tmp2, visited_vals);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2001
111
kono
parents: 67
diff changeset
2002 /* If either operand is known to be a pointer, then prefer it
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2003 to determine the base term. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2004 if (REG_P (tmp1) && REG_POINTER (tmp1))
111
kono
parents: 67
diff changeset
2005 ;
kono
parents: 67
diff changeset
2006 else if (REG_P (tmp2) && REG_POINTER (tmp2))
kono
parents: 67
diff changeset
2007 std::swap (tmp1, tmp2);
kono
parents: 67
diff changeset
2008 /* If second argument is constant which has base term, prefer it
kono
parents: 67
diff changeset
2009 over variable tmp1. See PR64025. */
kono
parents: 67
diff changeset
2010 else if (CONSTANT_P (tmp2) && !CONST_INT_P (tmp2))
kono
parents: 67
diff changeset
2011 std::swap (tmp1, tmp2);
kono
parents: 67
diff changeset
2012
kono
parents: 67
diff changeset
2013 /* Go ahead and find the base term for both operands. If either base
kono
parents: 67
diff changeset
2014 term is from a pointer or is a named object or a special address
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2015 (like an argument or stack reference), then use it for the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2016 base term. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2017 rtx base = find_base_term (tmp1, visited_vals);
111
kono
parents: 67
diff changeset
2018 if (base != NULL_RTX
kono
parents: 67
diff changeset
2019 && ((REG_P (tmp1) && REG_POINTER (tmp1))
kono
parents: 67
diff changeset
2020 || known_base_value_p (base)))
kono
parents: 67
diff changeset
2021 return base;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2022 base = find_base_term (tmp2, visited_vals);
111
kono
parents: 67
diff changeset
2023 if (base != NULL_RTX
kono
parents: 67
diff changeset
2024 && ((REG_P (tmp2) && REG_POINTER (tmp2))
kono
parents: 67
diff changeset
2025 || known_base_value_p (base)))
kono
parents: 67
diff changeset
2026 return base;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2027
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2028 /* We could not determine which of the two operands was the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2029 base register and which was the index. So we can determine
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2030 nothing from the base alias check. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2031 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2032 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2033
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2034 case AND:
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
2035 if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) != 0)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2036 return find_base_term (XEXP (x, 0), visited_vals);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2037 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2038
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2039 case SYMBOL_REF:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2040 case LABEL_REF:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2041 return x;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2042
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2043 default:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2044 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2045 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2046 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2047
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2048 /* Wrapper around the worker above which removes locs from visited VALUEs
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2049 to avoid visiting them multiple times. We unwind that changes here. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2050
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2051 static rtx
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2052 find_base_term (rtx x)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2053 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2054 auto_vec<std::pair<cselib_val *, struct elt_loc_list *>, 32> visited_vals;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2055 rtx res = find_base_term (x, visited_vals);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2056 for (unsigned i = 0; i < visited_vals.length (); ++i)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2057 visited_vals[i].first->locs = visited_vals[i].second;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2058 return res;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2059 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2060
111
kono
parents: 67
diff changeset
2061 /* Return true if accesses to address X may alias accesses based
kono
parents: 67
diff changeset
2062 on the stack pointer. */
kono
parents: 67
diff changeset
2063
kono
parents: 67
diff changeset
2064 bool
kono
parents: 67
diff changeset
2065 may_be_sp_based_p (rtx x)
kono
parents: 67
diff changeset
2066 {
kono
parents: 67
diff changeset
2067 rtx base = find_base_term (x);
kono
parents: 67
diff changeset
2068 return !base || base == static_reg_base_value[STACK_POINTER_REGNUM];
kono
parents: 67
diff changeset
2069 }
kono
parents: 67
diff changeset
2070
kono
parents: 67
diff changeset
2071 /* BASE1 and BASE2 are decls. Return 1 if they refer to same object, 0
kono
parents: 67
diff changeset
2072 if they refer to different objects and -1 if we can not decide. */
kono
parents: 67
diff changeset
2073
kono
parents: 67
diff changeset
2074 int
kono
parents: 67
diff changeset
2075 compare_base_decls (tree base1, tree base2)
kono
parents: 67
diff changeset
2076 {
kono
parents: 67
diff changeset
2077 int ret;
kono
parents: 67
diff changeset
2078 gcc_checking_assert (DECL_P (base1) && DECL_P (base2));
kono
parents: 67
diff changeset
2079 if (base1 == base2)
kono
parents: 67
diff changeset
2080 return 1;
kono
parents: 67
diff changeset
2081
kono
parents: 67
diff changeset
2082 /* If we have two register decls with register specification we
kono
parents: 67
diff changeset
2083 cannot decide unless their assembler names are the same. */
kono
parents: 67
diff changeset
2084 if (DECL_REGISTER (base1)
kono
parents: 67
diff changeset
2085 && DECL_REGISTER (base2)
kono
parents: 67
diff changeset
2086 && HAS_DECL_ASSEMBLER_NAME_P (base1)
kono
parents: 67
diff changeset
2087 && HAS_DECL_ASSEMBLER_NAME_P (base2)
kono
parents: 67
diff changeset
2088 && DECL_ASSEMBLER_NAME_SET_P (base1)
kono
parents: 67
diff changeset
2089 && DECL_ASSEMBLER_NAME_SET_P (base2))
kono
parents: 67
diff changeset
2090 {
kono
parents: 67
diff changeset
2091 if (DECL_ASSEMBLER_NAME_RAW (base1) == DECL_ASSEMBLER_NAME_RAW (base2))
kono
parents: 67
diff changeset
2092 return 1;
kono
parents: 67
diff changeset
2093 return -1;
kono
parents: 67
diff changeset
2094 }
kono
parents: 67
diff changeset
2095
kono
parents: 67
diff changeset
2096 /* Declarations of non-automatic variables may have aliases. All other
kono
parents: 67
diff changeset
2097 decls are unique. */
kono
parents: 67
diff changeset
2098 if (!decl_in_symtab_p (base1)
kono
parents: 67
diff changeset
2099 || !decl_in_symtab_p (base2))
kono
parents: 67
diff changeset
2100 return 0;
kono
parents: 67
diff changeset
2101
kono
parents: 67
diff changeset
2102 /* Don't cause symbols to be inserted by the act of checking. */
kono
parents: 67
diff changeset
2103 symtab_node *node1 = symtab_node::get (base1);
kono
parents: 67
diff changeset
2104 if (!node1)
kono
parents: 67
diff changeset
2105 return 0;
kono
parents: 67
diff changeset
2106 symtab_node *node2 = symtab_node::get (base2);
kono
parents: 67
diff changeset
2107 if (!node2)
kono
parents: 67
diff changeset
2108 return 0;
kono
parents: 67
diff changeset
2109
kono
parents: 67
diff changeset
2110 ret = node1->equal_address_to (node2, true);
kono
parents: 67
diff changeset
2111 return ret;
kono
parents: 67
diff changeset
2112 }
kono
parents: 67
diff changeset
2113
kono
parents: 67
diff changeset
2114 /* Same as compare_base_decls but for SYMBOL_REF. */
kono
parents: 67
diff changeset
2115
kono
parents: 67
diff changeset
2116 static int
kono
parents: 67
diff changeset
2117 compare_base_symbol_refs (const_rtx x_base, const_rtx y_base)
kono
parents: 67
diff changeset
2118 {
kono
parents: 67
diff changeset
2119 tree x_decl = SYMBOL_REF_DECL (x_base);
kono
parents: 67
diff changeset
2120 tree y_decl = SYMBOL_REF_DECL (y_base);
kono
parents: 67
diff changeset
2121 bool binds_def = true;
kono
parents: 67
diff changeset
2122
kono
parents: 67
diff changeset
2123 if (XSTR (x_base, 0) == XSTR (y_base, 0))
kono
parents: 67
diff changeset
2124 return 1;
kono
parents: 67
diff changeset
2125 if (x_decl && y_decl)
kono
parents: 67
diff changeset
2126 return compare_base_decls (x_decl, y_decl);
kono
parents: 67
diff changeset
2127 if (x_decl || y_decl)
kono
parents: 67
diff changeset
2128 {
kono
parents: 67
diff changeset
2129 if (!x_decl)
kono
parents: 67
diff changeset
2130 {
kono
parents: 67
diff changeset
2131 std::swap (x_decl, y_decl);
kono
parents: 67
diff changeset
2132 std::swap (x_base, y_base);
kono
parents: 67
diff changeset
2133 }
kono
parents: 67
diff changeset
2134 /* We handle specially only section anchors and assume that other
kono
parents: 67
diff changeset
2135 labels may overlap with user variables in an arbitrary way. */
kono
parents: 67
diff changeset
2136 if (!SYMBOL_REF_HAS_BLOCK_INFO_P (y_base))
kono
parents: 67
diff changeset
2137 return -1;
kono
parents: 67
diff changeset
2138 /* Anchors contains static VAR_DECLs and CONST_DECLs. We are safe
kono
parents: 67
diff changeset
2139 to ignore CONST_DECLs because they are readonly. */
kono
parents: 67
diff changeset
2140 if (!VAR_P (x_decl)
kono
parents: 67
diff changeset
2141 || (!TREE_STATIC (x_decl) && !TREE_PUBLIC (x_decl)))
kono
parents: 67
diff changeset
2142 return 0;
kono
parents: 67
diff changeset
2143
kono
parents: 67
diff changeset
2144 symtab_node *x_node = symtab_node::get_create (x_decl)
kono
parents: 67
diff changeset
2145 ->ultimate_alias_target ();
kono
parents: 67
diff changeset
2146 /* External variable can not be in section anchor. */
kono
parents: 67
diff changeset
2147 if (!x_node->definition)
kono
parents: 67
diff changeset
2148 return 0;
kono
parents: 67
diff changeset
2149 x_base = XEXP (DECL_RTL (x_node->decl), 0);
kono
parents: 67
diff changeset
2150 /* If not in anchor, we can disambiguate. */
kono
parents: 67
diff changeset
2151 if (!SYMBOL_REF_HAS_BLOCK_INFO_P (x_base))
kono
parents: 67
diff changeset
2152 return 0;
kono
parents: 67
diff changeset
2153
kono
parents: 67
diff changeset
2154 /* We have an alias of anchored variable. If it can be interposed;
kono
parents: 67
diff changeset
2155 we must assume it may or may not alias its anchor. */
kono
parents: 67
diff changeset
2156 binds_def = decl_binds_to_current_def_p (x_decl);
kono
parents: 67
diff changeset
2157 }
kono
parents: 67
diff changeset
2158 /* If we have variable in section anchor, we can compare by offset. */
kono
parents: 67
diff changeset
2159 if (SYMBOL_REF_HAS_BLOCK_INFO_P (x_base)
kono
parents: 67
diff changeset
2160 && SYMBOL_REF_HAS_BLOCK_INFO_P (y_base))
kono
parents: 67
diff changeset
2161 {
kono
parents: 67
diff changeset
2162 if (SYMBOL_REF_BLOCK (x_base) != SYMBOL_REF_BLOCK (y_base))
kono
parents: 67
diff changeset
2163 return 0;
kono
parents: 67
diff changeset
2164 if (SYMBOL_REF_BLOCK_OFFSET (x_base) == SYMBOL_REF_BLOCK_OFFSET (y_base))
kono
parents: 67
diff changeset
2165 return binds_def ? 1 : -1;
kono
parents: 67
diff changeset
2166 if (SYMBOL_REF_ANCHOR_P (x_base) != SYMBOL_REF_ANCHOR_P (y_base))
kono
parents: 67
diff changeset
2167 return -1;
kono
parents: 67
diff changeset
2168 return 0;
kono
parents: 67
diff changeset
2169 }
kono
parents: 67
diff changeset
2170 /* In general we assume that memory locations pointed to by different labels
kono
parents: 67
diff changeset
2171 may overlap in undefined ways. */
kono
parents: 67
diff changeset
2172 return -1;
kono
parents: 67
diff changeset
2173 }
kono
parents: 67
diff changeset
2174
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2175 /* Return 0 if the addresses X and Y are known to point to different
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2176 objects, 1 if they might be pointers to the same object. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2177
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2178 static int
111
kono
parents: 67
diff changeset
2179 base_alias_check (rtx x, rtx x_base, rtx y, rtx y_base,
kono
parents: 67
diff changeset
2180 machine_mode x_mode, machine_mode y_mode)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2181 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2182 /* If the address itself has no known base see if a known equivalent
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2183 value has one. If either address still has no known base, nothing
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2184 is known about aliasing. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2185 if (x_base == 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2186 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2187 rtx x_c;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2188
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2189 if (! flag_expensive_optimizations || (x_c = canon_rtx (x)) == x)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2190 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2191
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2192 x_base = find_base_term (x_c);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2193 if (x_base == 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2194 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2195 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2196
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2197 if (y_base == 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2198 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2199 rtx y_c;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2200 if (! flag_expensive_optimizations || (y_c = canon_rtx (y)) == y)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2201 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2202
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2203 y_base = find_base_term (y_c);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2204 if (y_base == 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2205 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2206 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2207
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2208 /* If the base addresses are equal nothing is known about aliasing. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2209 if (rtx_equal_p (x_base, y_base))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2210 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2211
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2212 /* The base addresses are different expressions. If they are not accessed
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2213 via AND, there is no conflict. We can bring knowledge of object
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2214 alignment into play here. For example, on alpha, "char a, b;" can
111
kono
parents: 67
diff changeset
2215 alias one another, though "char a; long b;" cannot. AND addresses may
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2216 implicitly alias surrounding objects; i.e. unaligned access in DImode
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2217 via AND address can alias all surrounding object types except those
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2218 with aligment 8 or higher. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2219 if (GET_CODE (x) == AND && GET_CODE (y) == AND)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2220 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2221 if (GET_CODE (x) == AND
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
2222 && (!CONST_INT_P (XEXP (x, 1))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2223 || (int) GET_MODE_UNIT_SIZE (y_mode) < -INTVAL (XEXP (x, 1))))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2224 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2225 if (GET_CODE (y) == AND
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
2226 && (!CONST_INT_P (XEXP (y, 1))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2227 || (int) GET_MODE_UNIT_SIZE (x_mode) < -INTVAL (XEXP (y, 1))))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2228 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2229
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2230 /* Differing symbols not accessed via AND never alias. */
111
kono
parents: 67
diff changeset
2231 if (GET_CODE (x_base) == SYMBOL_REF && GET_CODE (y_base) == SYMBOL_REF)
kono
parents: 67
diff changeset
2232 return compare_base_symbol_refs (x_base, y_base) != 0;
kono
parents: 67
diff changeset
2233
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2234 if (GET_CODE (x_base) != ADDRESS && GET_CODE (y_base) != ADDRESS)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2235 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2236
111
kono
parents: 67
diff changeset
2237 if (unique_base_value_p (x_base) || unique_base_value_p (y_base))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2238 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2239
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2240 return 1;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2241 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2242
111
kono
parents: 67
diff changeset
2243 /* Return TRUE if EXPR refers to a VALUE whose uid is greater than
kono
parents: 67
diff changeset
2244 (or equal to) that of V. */
kono
parents: 67
diff changeset
2245
kono
parents: 67
diff changeset
2246 static bool
kono
parents: 67
diff changeset
2247 refs_newer_value_p (const_rtx expr, rtx v)
kono
parents: 67
diff changeset
2248 {
kono
parents: 67
diff changeset
2249 int minuid = CSELIB_VAL_PTR (v)->uid;
kono
parents: 67
diff changeset
2250 subrtx_iterator::array_type array;
kono
parents: 67
diff changeset
2251 FOR_EACH_SUBRTX (iter, array, expr, NONCONST)
kono
parents: 67
diff changeset
2252 if (GET_CODE (*iter) == VALUE && CSELIB_VAL_PTR (*iter)->uid >= minuid)
kono
parents: 67
diff changeset
2253 return true;
kono
parents: 67
diff changeset
2254 return false;
kono
parents: 67
diff changeset
2255 }
kono
parents: 67
diff changeset
2256
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2257 /* Convert the address X into something we can use. This is done by returning
111
kono
parents: 67
diff changeset
2258 it unchanged unless it is a VALUE or VALUE +/- constant; for VALUE
kono
parents: 67
diff changeset
2259 we call cselib to get a more useful rtx. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2260
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2261 rtx
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2262 get_addr (rtx x)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2263 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2264 cselib_val *v;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2265 struct elt_loc_list *l;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2266
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2267 if (GET_CODE (x) != VALUE)
111
kono
parents: 67
diff changeset
2268 {
kono
parents: 67
diff changeset
2269 if ((GET_CODE (x) == PLUS || GET_CODE (x) == MINUS)
kono
parents: 67
diff changeset
2270 && GET_CODE (XEXP (x, 0)) == VALUE
kono
parents: 67
diff changeset
2271 && CONST_SCALAR_INT_P (XEXP (x, 1)))
kono
parents: 67
diff changeset
2272 {
kono
parents: 67
diff changeset
2273 rtx op0 = get_addr (XEXP (x, 0));
kono
parents: 67
diff changeset
2274 if (op0 != XEXP (x, 0))
kono
parents: 67
diff changeset
2275 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2276 poly_int64 c;
111
kono
parents: 67
diff changeset
2277 if (GET_CODE (x) == PLUS
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2278 && poly_int_rtx_p (XEXP (x, 1), &c))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2279 return plus_constant (GET_MODE (x), op0, c);
111
kono
parents: 67
diff changeset
2280 return simplify_gen_binary (GET_CODE (x), GET_MODE (x),
kono
parents: 67
diff changeset
2281 op0, XEXP (x, 1));
kono
parents: 67
diff changeset
2282 }
kono
parents: 67
diff changeset
2283 }
kono
parents: 67
diff changeset
2284 return x;
kono
parents: 67
diff changeset
2285 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2286 v = CSELIB_VAL_PTR (x);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2287 if (v)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2288 {
111
kono
parents: 67
diff changeset
2289 bool have_equivs = cselib_have_permanent_equivalences ();
kono
parents: 67
diff changeset
2290 if (have_equivs)
kono
parents: 67
diff changeset
2291 v = canonical_cselib_val (v);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2292 for (l = v->locs; l; l = l->next)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2293 if (CONSTANT_P (l->loc))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2294 return l->loc;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2295 for (l = v->locs; l; l = l->next)
111
kono
parents: 67
diff changeset
2296 if (!REG_P (l->loc) && !MEM_P (l->loc)
kono
parents: 67
diff changeset
2297 /* Avoid infinite recursion when potentially dealing with
kono
parents: 67
diff changeset
2298 var-tracking artificial equivalences, by skipping the
kono
parents: 67
diff changeset
2299 equivalences themselves, and not choosing expressions
kono
parents: 67
diff changeset
2300 that refer to newer VALUEs. */
kono
parents: 67
diff changeset
2301 && (!have_equivs
kono
parents: 67
diff changeset
2302 || (GET_CODE (l->loc) != VALUE
kono
parents: 67
diff changeset
2303 && !refs_newer_value_p (l->loc, x))))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2304 return l->loc;
111
kono
parents: 67
diff changeset
2305 if (have_equivs)
kono
parents: 67
diff changeset
2306 {
kono
parents: 67
diff changeset
2307 for (l = v->locs; l; l = l->next)
kono
parents: 67
diff changeset
2308 if (REG_P (l->loc)
kono
parents: 67
diff changeset
2309 || (GET_CODE (l->loc) != VALUE
kono
parents: 67
diff changeset
2310 && !refs_newer_value_p (l->loc, x)))
kono
parents: 67
diff changeset
2311 return l->loc;
kono
parents: 67
diff changeset
2312 /* Return the canonical value. */
kono
parents: 67
diff changeset
2313 return v->val_rtx;
kono
parents: 67
diff changeset
2314 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2315 if (v->locs)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2316 return v->locs->loc;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2317 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2318 return x;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2319 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2320
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2321 /* Return the address of the (N_REFS + 1)th memory reference to ADDR
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2322 where SIZE is the size in bytes of the memory reference. If ADDR
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2323 is not modified by the memory reference then ADDR is returned. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2324
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2325 static rtx
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2326 addr_side_effect_eval (rtx addr, poly_int64 size, int n_refs)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2327 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2328 poly_int64 offset = 0;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2329
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2330 switch (GET_CODE (addr))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2331 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2332 case PRE_INC:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2333 offset = (n_refs + 1) * size;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2334 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2335 case PRE_DEC:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2336 offset = -(n_refs + 1) * size;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2337 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2338 case POST_INC:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2339 offset = n_refs * size;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2340 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2341 case POST_DEC:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2342 offset = -n_refs * size;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2343 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2344
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2345 default:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2346 return addr;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2347 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2348
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2349 addr = plus_constant (GET_MODE (addr), XEXP (addr, 0), offset);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2350 addr = canon_rtx (addr);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2351
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2352 return addr;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2353 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2354
111
kono
parents: 67
diff changeset
2355 /* Return TRUE if an object X sized at XSIZE bytes and another object
kono
parents: 67
diff changeset
2356 Y sized at YSIZE bytes, starting C bytes after X, may overlap. If
kono
parents: 67
diff changeset
2357 any of the sizes is zero, assume an overlap, otherwise use the
kono
parents: 67
diff changeset
2358 absolute value of the sizes as the actual sizes. */
kono
parents: 67
diff changeset
2359
kono
parents: 67
diff changeset
2360 static inline bool
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2361 offset_overlap_p (poly_int64 c, poly_int64 xsize, poly_int64 ysize)
111
kono
parents: 67
diff changeset
2362 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2363 if (known_eq (xsize, 0) || known_eq (ysize, 0))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2364 return true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2365
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2366 if (maybe_ge (c, 0))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2367 return maybe_gt (maybe_lt (xsize, 0) ? -xsize : xsize, c);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2368 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2369 return maybe_gt (maybe_lt (ysize, 0) ? -ysize : ysize, -c);
111
kono
parents: 67
diff changeset
2370 }
kono
parents: 67
diff changeset
2371
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2372 /* Return one if X and Y (memory addresses) reference the
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2373 same location in memory or if the references overlap.
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2374 Return zero if they do not overlap, else return
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2375 minus one in which case they still might reference the same location.
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2376
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2377 C is an offset accumulator. When
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2378 C is nonzero, we are testing aliases between X and Y + C.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2379 XSIZE is the size in bytes of the X reference,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2380 similarly YSIZE is the size in bytes for Y.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2381 Expect that canon_rtx has been already called for X and Y.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2382
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2383 If XSIZE or YSIZE is zero, we do not know the amount of memory being
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2384 referenced (the reference was BLKmode), so make the most pessimistic
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2385 assumptions.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2386
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2387 If XSIZE or YSIZE is negative, we may access memory outside the object
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2388 being referenced as a side effect. This can happen when using AND to
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2389 align memory references, as is done on the Alpha.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2390
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2391 Nice to notice that varying addresses cannot conflict with fp if no
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2392 local variables had their addresses taken, but that's too hard now.
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2393
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2394 ??? Contrary to the tree alias oracle this does not return
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2395 one for X + non-constant and Y + non-constant when X and Y are equal.
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2396 If that is fixed the TBAA hack for union type-punning can be removed. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2397
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2398 static int
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2399 memrefs_conflict_p (poly_int64 xsize, rtx x, poly_int64 ysize, rtx y,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2400 poly_int64 c)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2401 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2402 if (GET_CODE (x) == VALUE)
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2403 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2404 if (REG_P (y))
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2405 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2406 struct elt_loc_list *l = NULL;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2407 if (CSELIB_VAL_PTR (x))
111
kono
parents: 67
diff changeset
2408 for (l = canonical_cselib_val (CSELIB_VAL_PTR (x))->locs;
kono
parents: 67
diff changeset
2409 l; l = l->next)
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2410 if (REG_P (l->loc) && rtx_equal_for_memref_p (l->loc, y))
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2411 break;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2412 if (l)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2413 x = y;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2414 else
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2415 x = get_addr (x);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2416 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2417 /* Don't call get_addr if y is the same VALUE. */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2418 else if (x != y)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2419 x = get_addr (x);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2420 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2421 if (GET_CODE (y) == VALUE)
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2422 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2423 if (REG_P (x))
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2424 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2425 struct elt_loc_list *l = NULL;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2426 if (CSELIB_VAL_PTR (y))
111
kono
parents: 67
diff changeset
2427 for (l = canonical_cselib_val (CSELIB_VAL_PTR (y))->locs;
kono
parents: 67
diff changeset
2428 l; l = l->next)
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2429 if (REG_P (l->loc) && rtx_equal_for_memref_p (l->loc, x))
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2430 break;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2431 if (l)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2432 y = x;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2433 else
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2434 y = get_addr (y);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2435 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2436 /* Don't call get_addr if x is the same VALUE. */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2437 else if (y != x)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2438 y = get_addr (y);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2439 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2440 if (GET_CODE (x) == HIGH)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2441 x = XEXP (x, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2442 else if (GET_CODE (x) == LO_SUM)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2443 x = XEXP (x, 1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2444 else
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2445 x = addr_side_effect_eval (x, maybe_lt (xsize, 0) ? -xsize : xsize, 0);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2446 if (GET_CODE (y) == HIGH)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2447 y = XEXP (y, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2448 else if (GET_CODE (y) == LO_SUM)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2449 y = XEXP (y, 1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2450 else
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2451 y = addr_side_effect_eval (y, maybe_lt (ysize, 0) ? -ysize : ysize, 0);
111
kono
parents: 67
diff changeset
2452
kono
parents: 67
diff changeset
2453 if (GET_CODE (x) == SYMBOL_REF && GET_CODE (y) == SYMBOL_REF)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2454 {
111
kono
parents: 67
diff changeset
2455 int cmp = compare_base_symbol_refs (x,y);
kono
parents: 67
diff changeset
2456
kono
parents: 67
diff changeset
2457 /* If both decls are the same, decide by offsets. */
kono
parents: 67
diff changeset
2458 if (cmp == 1)
kono
parents: 67
diff changeset
2459 return offset_overlap_p (c, xsize, ysize);
kono
parents: 67
diff changeset
2460 /* Assume a potential overlap for symbolic addresses that went
kono
parents: 67
diff changeset
2461 through alignment adjustments (i.e., that have negative
kono
parents: 67
diff changeset
2462 sizes), because we can't know how far they are from each
kono
parents: 67
diff changeset
2463 other. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2464 if (maybe_lt (xsize, 0) || maybe_lt (ysize, 0))
111
kono
parents: 67
diff changeset
2465 return -1;
kono
parents: 67
diff changeset
2466 /* If decls are different or we know by offsets that there is no overlap,
kono
parents: 67
diff changeset
2467 we win. */
kono
parents: 67
diff changeset
2468 if (!cmp || !offset_overlap_p (c, xsize, ysize))
kono
parents: 67
diff changeset
2469 return 0;
kono
parents: 67
diff changeset
2470 /* Decls may or may not be different and offsets overlap....*/
kono
parents: 67
diff changeset
2471 return -1;
kono
parents: 67
diff changeset
2472 }
kono
parents: 67
diff changeset
2473 else if (rtx_equal_for_memref_p (x, y))
kono
parents: 67
diff changeset
2474 {
kono
parents: 67
diff changeset
2475 return offset_overlap_p (c, xsize, ysize);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2476 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2477
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2478 /* This code used to check for conflicts involving stack references and
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2479 globals but the base address alias code now handles these cases. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2480
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2481 if (GET_CODE (x) == PLUS)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2482 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2483 /* The fact that X is canonicalized means that this
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2484 PLUS rtx is canonicalized. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2485 rtx x0 = XEXP (x, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2486 rtx x1 = XEXP (x, 1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2487
111
kono
parents: 67
diff changeset
2488 /* However, VALUEs might end up in different positions even in
kono
parents: 67
diff changeset
2489 canonical PLUSes. Comparing their addresses is enough. */
kono
parents: 67
diff changeset
2490 if (x0 == y)
kono
parents: 67
diff changeset
2491 return memrefs_conflict_p (xsize, x1, ysize, const0_rtx, c);
kono
parents: 67
diff changeset
2492 else if (x1 == y)
kono
parents: 67
diff changeset
2493 return memrefs_conflict_p (xsize, x0, ysize, const0_rtx, c);
kono
parents: 67
diff changeset
2494
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2495 poly_int64 cx1, cy1;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2496 if (GET_CODE (y) == PLUS)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2497 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2498 /* The fact that Y is canonicalized means that this
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2499 PLUS rtx is canonicalized. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2500 rtx y0 = XEXP (y, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2501 rtx y1 = XEXP (y, 1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2502
111
kono
parents: 67
diff changeset
2503 if (x0 == y1)
kono
parents: 67
diff changeset
2504 return memrefs_conflict_p (xsize, x1, ysize, y0, c);
kono
parents: 67
diff changeset
2505 if (x1 == y0)
kono
parents: 67
diff changeset
2506 return memrefs_conflict_p (xsize, x0, ysize, y1, c);
kono
parents: 67
diff changeset
2507
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2508 if (rtx_equal_for_memref_p (x1, y1))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2509 return memrefs_conflict_p (xsize, x0, ysize, y0, c);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2510 if (rtx_equal_for_memref_p (x0, y0))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2511 return memrefs_conflict_p (xsize, x1, ysize, y1, c);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2512 if (poly_int_rtx_p (x1, &cx1))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2513 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2514 if (poly_int_rtx_p (y1, &cy1))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2515 return memrefs_conflict_p (xsize, x0, ysize, y0,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2516 c - cx1 + cy1);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2517 else
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2518 return memrefs_conflict_p (xsize, x0, ysize, y, c - cx1);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2519 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2520 else if (poly_int_rtx_p (y1, &cy1))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2521 return memrefs_conflict_p (xsize, x, ysize, y0, c + cy1);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2522
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2523 return -1;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2524 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2525 else if (poly_int_rtx_p (x1, &cx1))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2526 return memrefs_conflict_p (xsize, x0, ysize, y, c - cx1);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2527 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2528 else if (GET_CODE (y) == PLUS)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2529 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2530 /* The fact that Y is canonicalized means that this
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2531 PLUS rtx is canonicalized. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2532 rtx y0 = XEXP (y, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2533 rtx y1 = XEXP (y, 1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2534
111
kono
parents: 67
diff changeset
2535 if (x == y0)
kono
parents: 67
diff changeset
2536 return memrefs_conflict_p (xsize, const0_rtx, ysize, y1, c);
kono
parents: 67
diff changeset
2537 if (x == y1)
kono
parents: 67
diff changeset
2538 return memrefs_conflict_p (xsize, const0_rtx, ysize, y0, c);
kono
parents: 67
diff changeset
2539
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2540 poly_int64 cy1;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2541 if (poly_int_rtx_p (y1, &cy1))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2542 return memrefs_conflict_p (xsize, x, ysize, y0, c + cy1);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2543 else
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2544 return -1;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2545 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2546
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2547 if (GET_CODE (x) == GET_CODE (y))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2548 switch (GET_CODE (x))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2549 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2550 case MULT:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2551 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2552 /* Handle cases where we expect the second operands to be the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2553 same, and check only whether the first operand would conflict
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2554 or not. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2555 rtx x0, y0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2556 rtx x1 = canon_rtx (XEXP (x, 1));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2557 rtx y1 = canon_rtx (XEXP (y, 1));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2558 if (! rtx_equal_for_memref_p (x1, y1))
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2559 return -1;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2560 x0 = canon_rtx (XEXP (x, 0));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2561 y0 = canon_rtx (XEXP (y, 0));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2562 if (rtx_equal_for_memref_p (x0, y0))
111
kono
parents: 67
diff changeset
2563 return offset_overlap_p (c, xsize, ysize);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2564
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2565 /* Can't properly adjust our sizes. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2566 poly_int64 c1;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2567 if (!poly_int_rtx_p (x1, &c1)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2568 || !can_div_trunc_p (xsize, c1, &xsize)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2569 || !can_div_trunc_p (ysize, c1, &ysize)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2570 || !can_div_trunc_p (c, c1, &c))
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2571 return -1;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2572 return memrefs_conflict_p (xsize, x0, ysize, y0, c);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2573 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2574
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2575 default:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2576 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2577 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2578
111
kono
parents: 67
diff changeset
2579 /* Deal with alignment ANDs by adjusting offset and size so as to
kono
parents: 67
diff changeset
2580 cover the maximum range, without taking any previously known
kono
parents: 67
diff changeset
2581 alignment into account. Make a size negative after such an
kono
parents: 67
diff changeset
2582 adjustments, so that, if we end up with e.g. two SYMBOL_REFs, we
kono
parents: 67
diff changeset
2583 assume a potential overlap, because they may end up in contiguous
kono
parents: 67
diff changeset
2584 memory locations and the stricter-alignment access may span over
kono
parents: 67
diff changeset
2585 part of both. */
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
2586 if (GET_CODE (x) == AND && CONST_INT_P (XEXP (x, 1)))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2587 {
111
kono
parents: 67
diff changeset
2588 HOST_WIDE_INT sc = INTVAL (XEXP (x, 1));
kono
parents: 67
diff changeset
2589 unsigned HOST_WIDE_INT uc = sc;
kono
parents: 67
diff changeset
2590 if (sc < 0 && pow2_or_zerop (-uc))
kono
parents: 67
diff changeset
2591 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2592 if (maybe_gt (xsize, 0))
111
kono
parents: 67
diff changeset
2593 xsize = -xsize;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2594 if (maybe_ne (xsize, 0))
111
kono
parents: 67
diff changeset
2595 xsize += sc + 1;
kono
parents: 67
diff changeset
2596 c -= sc + 1;
kono
parents: 67
diff changeset
2597 return memrefs_conflict_p (xsize, canon_rtx (XEXP (x, 0)),
kono
parents: 67
diff changeset
2598 ysize, y, c);
kono
parents: 67
diff changeset
2599 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2600 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
2601 if (GET_CODE (y) == AND && CONST_INT_P (XEXP (y, 1)))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2602 {
111
kono
parents: 67
diff changeset
2603 HOST_WIDE_INT sc = INTVAL (XEXP (y, 1));
kono
parents: 67
diff changeset
2604 unsigned HOST_WIDE_INT uc = sc;
kono
parents: 67
diff changeset
2605 if (sc < 0 && pow2_or_zerop (-uc))
kono
parents: 67
diff changeset
2606 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2607 if (maybe_gt (ysize, 0))
111
kono
parents: 67
diff changeset
2608 ysize = -ysize;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2609 if (maybe_ne (ysize, 0))
111
kono
parents: 67
diff changeset
2610 ysize += sc + 1;
kono
parents: 67
diff changeset
2611 c += sc + 1;
kono
parents: 67
diff changeset
2612 return memrefs_conflict_p (xsize, x,
kono
parents: 67
diff changeset
2613 ysize, canon_rtx (XEXP (y, 0)), c);
kono
parents: 67
diff changeset
2614 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2615 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2616
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2617 if (CONSTANT_P (x))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2618 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2619 poly_int64 cx, cy;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2620 if (poly_int_rtx_p (x, &cx) && poly_int_rtx_p (y, &cy))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2621 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2622 c += cy - cx;
111
kono
parents: 67
diff changeset
2623 return offset_overlap_p (c, xsize, ysize);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2624 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2625
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2626 if (GET_CODE (x) == CONST)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2627 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2628 if (GET_CODE (y) == CONST)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2629 return memrefs_conflict_p (xsize, canon_rtx (XEXP (x, 0)),
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2630 ysize, canon_rtx (XEXP (y, 0)), c);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2631 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2632 return memrefs_conflict_p (xsize, canon_rtx (XEXP (x, 0)),
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2633 ysize, y, c);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2634 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2635 if (GET_CODE (y) == CONST)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2636 return memrefs_conflict_p (xsize, x, ysize,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2637 canon_rtx (XEXP (y, 0)), c);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2638
111
kono
parents: 67
diff changeset
2639 /* Assume a potential overlap for symbolic addresses that went
kono
parents: 67
diff changeset
2640 through alignment adjustments (i.e., that have negative
kono
parents: 67
diff changeset
2641 sizes), because we can't know how far they are from each
kono
parents: 67
diff changeset
2642 other. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2643 if (CONSTANT_P (y))
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2644 return (maybe_lt (xsize, 0)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2645 || maybe_lt (ysize, 0)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2646 || offset_overlap_p (c, xsize, ysize));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2647
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2648 return -1;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2649 }
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2650
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2651 return -1;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2652 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2653
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2654 /* Functions to compute memory dependencies.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2655
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2656 Since we process the insns in execution order, we can build tables
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2657 to keep track of what registers are fixed (and not aliased), what registers
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2658 are varying in known ways, and what registers are varying in unknown
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2659 ways.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2660
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2661 If both memory references are volatile, then there must always be a
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2662 dependence between the two references, since their order can not be
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2663 changed. A volatile and non-volatile reference can be interchanged
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2664 though.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2665
111
kono
parents: 67
diff changeset
2666 We also must allow AND addresses, because they may generate accesses
kono
parents: 67
diff changeset
2667 outside the object being referenced. This is used to generate aligned
kono
parents: 67
diff changeset
2668 addresses from unaligned addresses, for instance, the alpha
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2669 storeqi_unaligned pattern. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2670
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2671 /* Read dependence: X is read after read in MEM takes place. There can
111
kono
parents: 67
diff changeset
2672 only be a dependence here if both reads are volatile, or if either is
kono
parents: 67
diff changeset
2673 an explicit barrier. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2674
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2675 int
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2676 read_dependence (const_rtx mem, const_rtx x)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2677 {
111
kono
parents: 67
diff changeset
2678 if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem))
kono
parents: 67
diff changeset
2679 return true;
kono
parents: 67
diff changeset
2680 if (MEM_ALIAS_SET (x) == ALIAS_SET_MEMORY_BARRIER
kono
parents: 67
diff changeset
2681 || MEM_ALIAS_SET (mem) == ALIAS_SET_MEMORY_BARRIER)
kono
parents: 67
diff changeset
2682 return true;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2683 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2684 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2685
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2686 /* Look at the bottom of the COMPONENT_REF list for a DECL, and return it. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2687
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2688 static tree
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2689 decl_for_component_ref (tree x)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2690 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2691 do
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2692 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2693 x = TREE_OPERAND (x, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2694 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2695 while (x && TREE_CODE (x) == COMPONENT_REF);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2696
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2697 return x && DECL_P (x) ? x : NULL_TREE;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2698 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2699
111
kono
parents: 67
diff changeset
2700 /* Walk up the COMPONENT_REF list in X and adjust *OFFSET to compensate
kono
parents: 67
diff changeset
2701 for the offset of the field reference. *KNOWN_P says whether the
kono
parents: 67
diff changeset
2702 offset is known. */
kono
parents: 67
diff changeset
2703
kono
parents: 67
diff changeset
2704 static void
kono
parents: 67
diff changeset
2705 adjust_offset_for_component_ref (tree x, bool *known_p,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2706 poly_int64 *offset)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2707 {
111
kono
parents: 67
diff changeset
2708 if (!*known_p)
kono
parents: 67
diff changeset
2709 return;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2710 do
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2711 {
111
kono
parents: 67
diff changeset
2712 tree xoffset = component_ref_field_offset (x);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2713 tree field = TREE_OPERAND (x, 1);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2714 if (!poly_int_tree_p (xoffset))
111
kono
parents: 67
diff changeset
2715 {
kono
parents: 67
diff changeset
2716 *known_p = false;
kono
parents: 67
diff changeset
2717 return;
kono
parents: 67
diff changeset
2718 }
kono
parents: 67
diff changeset
2719
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2720 poly_offset_int woffset
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2721 = (wi::to_poly_offset (xoffset)
111
kono
parents: 67
diff changeset
2722 + (wi::to_offset (DECL_FIELD_BIT_OFFSET (field))
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2723 >> LOG2_BITS_PER_UNIT)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2724 + *offset);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2725 if (!woffset.to_shwi (offset))
111
kono
parents: 67
diff changeset
2726 {
kono
parents: 67
diff changeset
2727 *known_p = false;
kono
parents: 67
diff changeset
2728 return;
kono
parents: 67
diff changeset
2729 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2730
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2731 x = TREE_OPERAND (x, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2732 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2733 while (x && TREE_CODE (x) == COMPONENT_REF);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2734 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2735
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2736 /* Return nonzero if we can determine the exprs corresponding to memrefs
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2737 X and Y and they do not overlap.
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2738 If LOOP_VARIANT is set, skip offset-based disambiguation */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2739
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2740 int
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2741 nonoverlapping_memrefs_p (const_rtx x, const_rtx y, bool loop_invariant)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2742 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2743 tree exprx = MEM_EXPR (x), expry = MEM_EXPR (y);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2744 rtx rtlx, rtly;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2745 rtx basex, basey;
111
kono
parents: 67
diff changeset
2746 bool moffsetx_known_p, moffsety_known_p;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2747 poly_int64 moffsetx = 0, moffsety = 0;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2748 poly_int64 offsetx = 0, offsety = 0, sizex, sizey;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2749
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2750 /* Unless both have exprs, we can't tell anything. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2751 if (exprx == 0 || expry == 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2752 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2753
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2754 /* For spill-slot accesses make sure we have valid offsets. */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2755 if ((exprx == get_spill_slot_decl (false)
111
kono
parents: 67
diff changeset
2756 && ! MEM_OFFSET_KNOWN_P (x))
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2757 || (expry == get_spill_slot_decl (false)
111
kono
parents: 67
diff changeset
2758 && ! MEM_OFFSET_KNOWN_P (y)))
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2759 return 0;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2760
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2761 /* If the field reference test failed, look at the DECLs involved. */
111
kono
parents: 67
diff changeset
2762 moffsetx_known_p = MEM_OFFSET_KNOWN_P (x);
kono
parents: 67
diff changeset
2763 if (moffsetx_known_p)
kono
parents: 67
diff changeset
2764 moffsetx = MEM_OFFSET (x);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2765 if (TREE_CODE (exprx) == COMPONENT_REF)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2766 {
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2767 tree t = decl_for_component_ref (exprx);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2768 if (! t)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2769 return 0;
111
kono
parents: 67
diff changeset
2770 adjust_offset_for_component_ref (exprx, &moffsetx_known_p, &moffsetx);
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2771 exprx = t;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2772 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2773
111
kono
parents: 67
diff changeset
2774 moffsety_known_p = MEM_OFFSET_KNOWN_P (y);
kono
parents: 67
diff changeset
2775 if (moffsety_known_p)
kono
parents: 67
diff changeset
2776 moffsety = MEM_OFFSET (y);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2777 if (TREE_CODE (expry) == COMPONENT_REF)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2778 {
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2779 tree t = decl_for_component_ref (expry);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2780 if (! t)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2781 return 0;
111
kono
parents: 67
diff changeset
2782 adjust_offset_for_component_ref (expry, &moffsety_known_p, &moffsety);
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2783 expry = t;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2784 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2785
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2786 if (! DECL_P (exprx) || ! DECL_P (expry))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2787 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2788
111
kono
parents: 67
diff changeset
2789 /* If we refer to different gimple registers, or one gimple register
kono
parents: 67
diff changeset
2790 and one non-gimple-register, we know they can't overlap. First,
kono
parents: 67
diff changeset
2791 gimple registers don't have their addresses taken. Now, there
kono
parents: 67
diff changeset
2792 could be more than one stack slot for (different versions of) the
kono
parents: 67
diff changeset
2793 same gimple register, but we can presumably tell they don't
kono
parents: 67
diff changeset
2794 overlap based on offsets from stack base addresses elsewhere.
kono
parents: 67
diff changeset
2795 It's important that we don't proceed to DECL_RTL, because gimple
kono
parents: 67
diff changeset
2796 registers may not pass DECL_RTL_SET_P, and make_decl_rtl won't be
kono
parents: 67
diff changeset
2797 able to do anything about them since no SSA information will have
kono
parents: 67
diff changeset
2798 remained to guide it. */
kono
parents: 67
diff changeset
2799 if (is_gimple_reg (exprx) || is_gimple_reg (expry))
kono
parents: 67
diff changeset
2800 return exprx != expry
kono
parents: 67
diff changeset
2801 || (moffsetx_known_p && moffsety_known_p
kono
parents: 67
diff changeset
2802 && MEM_SIZE_KNOWN_P (x) && MEM_SIZE_KNOWN_P (y)
kono
parents: 67
diff changeset
2803 && !offset_overlap_p (moffsety - moffsetx,
kono
parents: 67
diff changeset
2804 MEM_SIZE (x), MEM_SIZE (y)));
kono
parents: 67
diff changeset
2805
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
2806 /* With invalid code we can end up storing into the constant pool.
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
2807 Bail out to avoid ICEing when creating RTL for this.
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
2808 See gfortran.dg/lto/20091028-2_0.f90. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
2809 if (TREE_CODE (exprx) == CONST_DECL
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
2810 || TREE_CODE (expry) == CONST_DECL)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
2811 return 1;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
2812
111
kono
parents: 67
diff changeset
2813 /* If one decl is known to be a function or label in a function and
kono
parents: 67
diff changeset
2814 the other is some kind of data, they can't overlap. */
kono
parents: 67
diff changeset
2815 if ((TREE_CODE (exprx) == FUNCTION_DECL
kono
parents: 67
diff changeset
2816 || TREE_CODE (exprx) == LABEL_DECL)
kono
parents: 67
diff changeset
2817 != (TREE_CODE (expry) == FUNCTION_DECL
kono
parents: 67
diff changeset
2818 || TREE_CODE (expry) == LABEL_DECL))
kono
parents: 67
diff changeset
2819 return 1;
kono
parents: 67
diff changeset
2820
kono
parents: 67
diff changeset
2821 /* If either of the decls doesn't have DECL_RTL set (e.g. marked as
kono
parents: 67
diff changeset
2822 living in multiple places), we can't tell anything. Exception
kono
parents: 67
diff changeset
2823 are FUNCTION_DECLs for which we can create DECL_RTL on demand. */
kono
parents: 67
diff changeset
2824 if ((!DECL_RTL_SET_P (exprx) && TREE_CODE (exprx) != FUNCTION_DECL)
kono
parents: 67
diff changeset
2825 || (!DECL_RTL_SET_P (expry) && TREE_CODE (expry) != FUNCTION_DECL))
kono
parents: 67
diff changeset
2826 return 0;
kono
parents: 67
diff changeset
2827
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2828 rtlx = DECL_RTL (exprx);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2829 rtly = DECL_RTL (expry);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2830
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2831 /* If either RTL is not a MEM, it must be a REG or CONCAT, meaning they
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2832 can't overlap unless they are the same because we never reuse that part
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2833 of the stack frame used for locals for spilled pseudos. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2834 if ((!MEM_P (rtlx) || !MEM_P (rtly))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2835 && ! rtx_equal_p (rtlx, rtly))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2836 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2837
111
kono
parents: 67
diff changeset
2838 /* If we have MEMs referring to different address spaces (which can
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
2839 potentially overlap), we cannot easily tell from the addresses
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
2840 whether the references overlap. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
2841 if (MEM_P (rtlx) && MEM_P (rtly)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
2842 && MEM_ADDR_SPACE (rtlx) != MEM_ADDR_SPACE (rtly))
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
2843 return 0;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
2844
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2845 /* Get the base and offsets of both decls. If either is a register, we
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2846 know both are and are the same, so use that as the base. The only
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2847 we can avoid overlap is if we can deduce that they are nonoverlapping
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2848 pieces of that decl, which is very rare. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2849 basex = MEM_P (rtlx) ? XEXP (rtlx, 0) : rtlx;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2850 basex = strip_offset_and_add (basex, &offsetx);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2851
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2852 basey = MEM_P (rtly) ? XEXP (rtly, 0) : rtly;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2853 basey = strip_offset_and_add (basey, &offsety);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2854
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2855 /* If the bases are different, we know they do not overlap if both
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2856 are constants or if one is a constant and the other a pointer into the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2857 stack frame. Otherwise a different base means we can't tell if they
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2858 overlap or not. */
111
kono
parents: 67
diff changeset
2859 if (compare_base_decls (exprx, expry) == 0)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2860 return ((CONSTANT_P (basex) && CONSTANT_P (basey))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2861 || (CONSTANT_P (basex) && REG_P (basey)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2862 && REGNO_PTR_FRAME_P (REGNO (basey)))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2863 || (CONSTANT_P (basey) && REG_P (basex)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2864 && REGNO_PTR_FRAME_P (REGNO (basex))));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2865
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2866 /* Offset based disambiguation not appropriate for loop invariant */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2867 if (loop_invariant)
111
kono
parents: 67
diff changeset
2868 return 0;
kono
parents: 67
diff changeset
2869
kono
parents: 67
diff changeset
2870 /* Offset based disambiguation is OK even if we do not know that the
kono
parents: 67
diff changeset
2871 declarations are necessarily different
kono
parents: 67
diff changeset
2872 (i.e. compare_base_decls (exprx, expry) == -1) */
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2873
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2874 sizex = (!MEM_P (rtlx) ? poly_int64 (GET_MODE_SIZE (GET_MODE (rtlx)))
111
kono
parents: 67
diff changeset
2875 : MEM_SIZE_KNOWN_P (rtlx) ? MEM_SIZE (rtlx)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2876 : -1);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2877 sizey = (!MEM_P (rtly) ? poly_int64 (GET_MODE_SIZE (GET_MODE (rtly)))
111
kono
parents: 67
diff changeset
2878 : MEM_SIZE_KNOWN_P (rtly) ? MEM_SIZE (rtly)
kono
parents: 67
diff changeset
2879 : -1);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2880
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2881 /* If we have an offset for either memref, it can update the values computed
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2882 above. */
111
kono
parents: 67
diff changeset
2883 if (moffsetx_known_p)
kono
parents: 67
diff changeset
2884 offsetx += moffsetx, sizex -= moffsetx;
kono
parents: 67
diff changeset
2885 if (moffsety_known_p)
kono
parents: 67
diff changeset
2886 offsety += moffsety, sizey -= moffsety;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2887
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2888 /* If a memref has both a size and an offset, we can use the smaller size.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2889 We can't do this if the offset isn't known because we must view this
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2890 memref as being anywhere inside the DECL's MEM. */
111
kono
parents: 67
diff changeset
2891 if (MEM_SIZE_KNOWN_P (x) && moffsetx_known_p)
kono
parents: 67
diff changeset
2892 sizex = MEM_SIZE (x);
kono
parents: 67
diff changeset
2893 if (MEM_SIZE_KNOWN_P (y) && moffsety_known_p)
kono
parents: 67
diff changeset
2894 sizey = MEM_SIZE (y);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2895
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2896 return !ranges_maybe_overlap_p (offsetx, sizex, offsety, sizey);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2897 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2898
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2899 /* Helper for true_dependence and canon_true_dependence.
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2900 Checks for true dependence: X is read after store in MEM takes place.
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2901
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2902 If MEM_CANONICALIZED is FALSE, then X_ADDR and MEM_ADDR should be
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2903 NULL_RTX, and the canonical addresses of MEM and X are both computed
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2904 here. If MEM_CANONICALIZED, then MEM must be already canonicalized.
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2905
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2906 If X_ADDR is non-NULL, it is used in preference of XEXP (x, 0).
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2907
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2908 Returns 1 if there is a true dependence, 0 otherwise. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2909
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2910 static int
111
kono
parents: 67
diff changeset
2911 true_dependence_1 (const_rtx mem, machine_mode mem_mode, rtx mem_addr,
kono
parents: 67
diff changeset
2912 const_rtx x, rtx x_addr, bool mem_canonicalized)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2913 {
111
kono
parents: 67
diff changeset
2914 rtx true_mem_addr;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2915 rtx base;
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2916 int ret;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2917
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2918 gcc_checking_assert (mem_canonicalized ? (mem_addr != NULL_RTX)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2919 : (mem_addr == NULL_RTX && x_addr == NULL_RTX));
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2920
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2921 if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2922 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2923
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2924 /* (mem:BLK (scratch)) is a special mechanism to conflict with everything.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2925 This is used in epilogue deallocation functions, and in cselib. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2926 if (GET_MODE (x) == BLKmode && GET_CODE (XEXP (x, 0)) == SCRATCH)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2927 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2928 if (GET_MODE (mem) == BLKmode && GET_CODE (XEXP (mem, 0)) == SCRATCH)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2929 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2930 if (MEM_ALIAS_SET (x) == ALIAS_SET_MEMORY_BARRIER
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2931 || MEM_ALIAS_SET (mem) == ALIAS_SET_MEMORY_BARRIER)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2932 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2933
111
kono
parents: 67
diff changeset
2934 if (! x_addr)
kono
parents: 67
diff changeset
2935 x_addr = XEXP (x, 0);
kono
parents: 67
diff changeset
2936 x_addr = get_addr (x_addr);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
2937
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2938 if (! mem_addr)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2939 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2940 mem_addr = XEXP (mem, 0);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2941 if (mem_mode == VOIDmode)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2942 mem_mode = GET_MODE (mem);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2943 }
111
kono
parents: 67
diff changeset
2944 true_mem_addr = get_addr (mem_addr);
kono
parents: 67
diff changeset
2945
kono
parents: 67
diff changeset
2946 /* Read-only memory is by definition never modified, and therefore can't
kono
parents: 67
diff changeset
2947 conflict with anything. However, don't assume anything when AND
kono
parents: 67
diff changeset
2948 addresses are involved and leave to the code below to determine
kono
parents: 67
diff changeset
2949 dependence. We don't expect to find read-only set on MEM, but
kono
parents: 67
diff changeset
2950 stupid user tricks can produce them, so don't die. */
kono
parents: 67
diff changeset
2951 if (MEM_READONLY_P (x)
kono
parents: 67
diff changeset
2952 && GET_CODE (x_addr) != AND
kono
parents: 67
diff changeset
2953 && GET_CODE (true_mem_addr) != AND)
kono
parents: 67
diff changeset
2954 return 0;
kono
parents: 67
diff changeset
2955
kono
parents: 67
diff changeset
2956 /* If we have MEMs referring to different address spaces (which can
kono
parents: 67
diff changeset
2957 potentially overlap), we cannot easily tell from the addresses
kono
parents: 67
diff changeset
2958 whether the references overlap. */
kono
parents: 67
diff changeset
2959 if (MEM_ADDR_SPACE (mem) != MEM_ADDR_SPACE (x))
kono
parents: 67
diff changeset
2960 return 1;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2961
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2962 base = find_base_term (x_addr);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2963 if (base && (GET_CODE (base) == LABEL_REF
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2964 || (GET_CODE (base) == SYMBOL_REF
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2965 && CONSTANT_POOL_ADDRESS_P (base))))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2966 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2967
111
kono
parents: 67
diff changeset
2968 rtx mem_base = find_base_term (true_mem_addr);
kono
parents: 67
diff changeset
2969 if (! base_alias_check (x_addr, base, true_mem_addr, mem_base,
kono
parents: 67
diff changeset
2970 GET_MODE (x), mem_mode))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2971 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2972
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2973 x_addr = canon_rtx (x_addr);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2974 if (!mem_canonicalized)
111
kono
parents: 67
diff changeset
2975 mem_addr = canon_rtx (true_mem_addr);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2976
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2977 if ((ret = memrefs_conflict_p (GET_MODE_SIZE (mem_mode), mem_addr,
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2978 SIZE_FOR_MODE (x), x_addr, 0)) != -1)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2979 return ret;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2980
111
kono
parents: 67
diff changeset
2981 if (mems_in_disjoint_alias_sets_p (x, mem))
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2982 return 0;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2983
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2984 if (nonoverlapping_memrefs_p (mem, x, false))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2985 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2986
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
2987 return rtx_refs_may_alias_p (x, mem, true);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2988 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2989
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2990 /* True dependence: X is read after store in MEM takes place. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2991
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2992 int
111
kono
parents: 67
diff changeset
2993 true_dependence (const_rtx mem, machine_mode mem_mode, const_rtx x)
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2994 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2995 return true_dependence_1 (mem, mem_mode, NULL_RTX,
111
kono
parents: 67
diff changeset
2996 x, NULL_RTX, /*mem_canonicalized=*/false);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2997 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2998
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2999 /* Canonical true dependence: X is read after store in MEM takes place.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3000 Variant of true_dependence which assumes MEM has already been
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3001 canonicalized (hence we no longer do that here).
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
3002 The mem_addr argument has been added, since true_dependence_1 computed
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
3003 this value prior to canonicalizing. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3004
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3005 int
111
kono
parents: 67
diff changeset
3006 canon_true_dependence (const_rtx mem, machine_mode mem_mode, rtx mem_addr,
kono
parents: 67
diff changeset
3007 const_rtx x, rtx x_addr)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3008 {
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
3009 return true_dependence_1 (mem, mem_mode, mem_addr,
111
kono
parents: 67
diff changeset
3010 x, x_addr, /*mem_canonicalized=*/true);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3011 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3012
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3013 /* Returns nonzero if a write to X might alias a previous read from
111
kono
parents: 67
diff changeset
3014 (or, if WRITEP is true, a write to) MEM.
kono
parents: 67
diff changeset
3015 If X_CANONCALIZED is true, then X_ADDR is the canonicalized address of X,
kono
parents: 67
diff changeset
3016 and X_MODE the mode for that access.
kono
parents: 67
diff changeset
3017 If MEM_CANONICALIZED is true, MEM is canonicalized. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3018
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3019 static int
111
kono
parents: 67
diff changeset
3020 write_dependence_p (const_rtx mem,
kono
parents: 67
diff changeset
3021 const_rtx x, machine_mode x_mode, rtx x_addr,
kono
parents: 67
diff changeset
3022 bool mem_canonicalized, bool x_canonicalized, bool writep)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3023 {
111
kono
parents: 67
diff changeset
3024 rtx mem_addr;
kono
parents: 67
diff changeset
3025 rtx true_mem_addr, true_x_addr;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3026 rtx base;
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
3027 int ret;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3028
111
kono
parents: 67
diff changeset
3029 gcc_checking_assert (x_canonicalized
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3030 ? (x_addr != NULL_RTX
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3031 && (x_mode != VOIDmode || GET_MODE (x) == VOIDmode))
111
kono
parents: 67
diff changeset
3032 : (x_addr == NULL_RTX && x_mode == VOIDmode));
kono
parents: 67
diff changeset
3033
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3034 if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3035 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3036
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3037 /* (mem:BLK (scratch)) is a special mechanism to conflict with everything.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3038 This is used in epilogue deallocation functions. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3039 if (GET_MODE (x) == BLKmode && GET_CODE (XEXP (x, 0)) == SCRATCH)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3040 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3041 if (GET_MODE (mem) == BLKmode && GET_CODE (XEXP (mem, 0)) == SCRATCH)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3042 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3043 if (MEM_ALIAS_SET (x) == ALIAS_SET_MEMORY_BARRIER
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3044 || MEM_ALIAS_SET (mem) == ALIAS_SET_MEMORY_BARRIER)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3045 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3046
111
kono
parents: 67
diff changeset
3047 if (!x_addr)
kono
parents: 67
diff changeset
3048 x_addr = XEXP (x, 0);
kono
parents: 67
diff changeset
3049 true_x_addr = get_addr (x_addr);
kono
parents: 67
diff changeset
3050
kono
parents: 67
diff changeset
3051 mem_addr = XEXP (mem, 0);
kono
parents: 67
diff changeset
3052 true_mem_addr = get_addr (mem_addr);
kono
parents: 67
diff changeset
3053
kono
parents: 67
diff changeset
3054 /* A read from read-only memory can't conflict with read-write memory.
kono
parents: 67
diff changeset
3055 Don't assume anything when AND addresses are involved and leave to
kono
parents: 67
diff changeset
3056 the code below to determine dependence. */
kono
parents: 67
diff changeset
3057 if (!writep
kono
parents: 67
diff changeset
3058 && MEM_READONLY_P (mem)
kono
parents: 67
diff changeset
3059 && GET_CODE (true_x_addr) != AND
kono
parents: 67
diff changeset
3060 && GET_CODE (true_mem_addr) != AND)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3061 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3062
111
kono
parents: 67
diff changeset
3063 /* If we have MEMs referring to different address spaces (which can
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
3064 potentially overlap), we cannot easily tell from the addresses
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
3065 whether the references overlap. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
3066 if (MEM_ADDR_SPACE (mem) != MEM_ADDR_SPACE (x))
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
3067 return 1;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
3068
111
kono
parents: 67
diff changeset
3069 base = find_base_term (true_mem_addr);
kono
parents: 67
diff changeset
3070 if (! writep
kono
parents: 67
diff changeset
3071 && base
kono
parents: 67
diff changeset
3072 && (GET_CODE (base) == LABEL_REF
kono
parents: 67
diff changeset
3073 || (GET_CODE (base) == SYMBOL_REF
kono
parents: 67
diff changeset
3074 && CONSTANT_POOL_ADDRESS_P (base))))
kono
parents: 67
diff changeset
3075 return 0;
kono
parents: 67
diff changeset
3076
kono
parents: 67
diff changeset
3077 rtx x_base = find_base_term (true_x_addr);
kono
parents: 67
diff changeset
3078 if (! base_alias_check (true_x_addr, x_base, true_mem_addr, base,
kono
parents: 67
diff changeset
3079 GET_MODE (x), GET_MODE (mem)))
kono
parents: 67
diff changeset
3080 return 0;
kono
parents: 67
diff changeset
3081
kono
parents: 67
diff changeset
3082 if (!x_canonicalized)
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
3083 {
111
kono
parents: 67
diff changeset
3084 x_addr = canon_rtx (true_x_addr);
kono
parents: 67
diff changeset
3085 x_mode = GET_MODE (x);
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
3086 }
111
kono
parents: 67
diff changeset
3087 if (!mem_canonicalized)
kono
parents: 67
diff changeset
3088 mem_addr = canon_rtx (true_mem_addr);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3089
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
3090 if ((ret = memrefs_conflict_p (SIZE_FOR_MODE (mem), mem_addr,
111
kono
parents: 67
diff changeset
3091 GET_MODE_SIZE (x_mode), x_addr, 0)) != -1)
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
3092 return ret;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
3093
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
3094 if (nonoverlapping_memrefs_p (x, mem, false))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3095 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3096
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 36
diff changeset
3097 return rtx_refs_may_alias_p (x, mem, false);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3098 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3099
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3100 /* Anti dependence: X is written after read in MEM takes place. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3101
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3102 int
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3103 anti_dependence (const_rtx mem, const_rtx x)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3104 {
111
kono
parents: 67
diff changeset
3105 return write_dependence_p (mem, x, VOIDmode, NULL_RTX,
kono
parents: 67
diff changeset
3106 /*mem_canonicalized=*/false,
kono
parents: 67
diff changeset
3107 /*x_canonicalized*/false, /*writep=*/false);
kono
parents: 67
diff changeset
3108 }
kono
parents: 67
diff changeset
3109
kono
parents: 67
diff changeset
3110 /* Likewise, but we already have a canonicalized MEM, and X_ADDR for X.
kono
parents: 67
diff changeset
3111 Also, consider X in X_MODE (which might be from an enclosing
kono
parents: 67
diff changeset
3112 STRICT_LOW_PART / ZERO_EXTRACT).
kono
parents: 67
diff changeset
3113 If MEM_CANONICALIZED is true, MEM is canonicalized. */
kono
parents: 67
diff changeset
3114
kono
parents: 67
diff changeset
3115 int
kono
parents: 67
diff changeset
3116 canon_anti_dependence (const_rtx mem, bool mem_canonicalized,
kono
parents: 67
diff changeset
3117 const_rtx x, machine_mode x_mode, rtx x_addr)
kono
parents: 67
diff changeset
3118 {
kono
parents: 67
diff changeset
3119 return write_dependence_p (mem, x, x_mode, x_addr,
kono
parents: 67
diff changeset
3120 mem_canonicalized, /*x_canonicalized=*/true,
kono
parents: 67
diff changeset
3121 /*writep=*/false);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3122 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3123
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3124 /* Output dependence: X is written after store in MEM takes place. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3125
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3126 int
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3127 output_dependence (const_rtx mem, const_rtx x)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3128 {
111
kono
parents: 67
diff changeset
3129 return write_dependence_p (mem, x, VOIDmode, NULL_RTX,
kono
parents: 67
diff changeset
3130 /*mem_canonicalized=*/false,
kono
parents: 67
diff changeset
3131 /*x_canonicalized*/false, /*writep=*/true);
kono
parents: 67
diff changeset
3132 }
kono
parents: 67
diff changeset
3133
kono
parents: 67
diff changeset
3134 /* Likewise, but we already have a canonicalized MEM, and X_ADDR for X.
kono
parents: 67
diff changeset
3135 Also, consider X in X_MODE (which might be from an enclosing
kono
parents: 67
diff changeset
3136 STRICT_LOW_PART / ZERO_EXTRACT).
kono
parents: 67
diff changeset
3137 If MEM_CANONICALIZED is true, MEM is canonicalized. */
kono
parents: 67
diff changeset
3138
kono
parents: 67
diff changeset
3139 int
kono
parents: 67
diff changeset
3140 canon_output_dependence (const_rtx mem, bool mem_canonicalized,
kono
parents: 67
diff changeset
3141 const_rtx x, machine_mode x_mode, rtx x_addr)
kono
parents: 67
diff changeset
3142 {
kono
parents: 67
diff changeset
3143 return write_dependence_p (mem, x, x_mode, x_addr,
kono
parents: 67
diff changeset
3144 mem_canonicalized, /*x_canonicalized=*/true,
kono
parents: 67
diff changeset
3145 /*writep=*/true);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3146 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3147
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3148
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
3149
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
3150 /* Check whether X may be aliased with MEM. Don't do offset-based
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
3151 memory disambiguation & TBAA. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
3152 int
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
3153 may_alias_p (const_rtx mem, const_rtx x)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
3154 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
3155 rtx x_addr, mem_addr;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
3156
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
3157 if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
3158 return 1;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
3159
111
kono
parents: 67
diff changeset
3160 /* (mem:BLK (scratch)) is a special mechanism to conflict with everything.
kono
parents: 67
diff changeset
3161 This is used in epilogue deallocation functions. */
kono
parents: 67
diff changeset
3162 if (GET_MODE (x) == BLKmode && GET_CODE (XEXP (x, 0)) == SCRATCH)
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
3163 return 1;
111
kono
parents: 67
diff changeset
3164 if (GET_MODE (mem) == BLKmode && GET_CODE (XEXP (mem, 0)) == SCRATCH)
kono
parents: 67
diff changeset
3165 return 1;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
3166 if (MEM_ALIAS_SET (x) == ALIAS_SET_MEMORY_BARRIER
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
3167 || MEM_ALIAS_SET (mem) == ALIAS_SET_MEMORY_BARRIER)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
3168 return 1;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
3169
111
kono
parents: 67
diff changeset
3170 x_addr = XEXP (x, 0);
kono
parents: 67
diff changeset
3171 x_addr = get_addr (x_addr);
kono
parents: 67
diff changeset
3172
kono
parents: 67
diff changeset
3173 mem_addr = XEXP (mem, 0);
kono
parents: 67
diff changeset
3174 mem_addr = get_addr (mem_addr);
kono
parents: 67
diff changeset
3175
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
3176 /* Read-only memory is by definition never modified, and therefore can't
111
kono
parents: 67
diff changeset
3177 conflict with anything. However, don't assume anything when AND
kono
parents: 67
diff changeset
3178 addresses are involved and leave to the code below to determine
kono
parents: 67
diff changeset
3179 dependence. We don't expect to find read-only set on MEM, but
kono
parents: 67
diff changeset
3180 stupid user tricks can produce them, so don't die. */
kono
parents: 67
diff changeset
3181 if (MEM_READONLY_P (x)
kono
parents: 67
diff changeset
3182 && GET_CODE (x_addr) != AND
kono
parents: 67
diff changeset
3183 && GET_CODE (mem_addr) != AND)
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
3184 return 0;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
3185
111
kono
parents: 67
diff changeset
3186 /* If we have MEMs referring to different address spaces (which can
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
3187 potentially overlap), we cannot easily tell from the addresses
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
3188 whether the references overlap. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
3189 if (MEM_ADDR_SPACE (mem) != MEM_ADDR_SPACE (x))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
3190 return 1;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
3191
111
kono
parents: 67
diff changeset
3192 rtx x_base = find_base_term (x_addr);
kono
parents: 67
diff changeset
3193 rtx mem_base = find_base_term (mem_addr);
kono
parents: 67
diff changeset
3194 if (! base_alias_check (x_addr, x_base, mem_addr, mem_base,
kono
parents: 67
diff changeset
3195 GET_MODE (x), GET_MODE (mem_addr)))
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
3196 return 0;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
3197
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
3198 if (nonoverlapping_memrefs_p (mem, x, true))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
3199 return 0;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
3200
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
3201 /* TBAA not valid for loop_invarint */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
3202 return rtx_refs_may_alias_p (x, mem, false);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
3203 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
3204
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3205 void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3206 init_alias_target (void)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3207 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3208 int i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3209
111
kono
parents: 67
diff changeset
3210 if (!arg_base_value)
kono
parents: 67
diff changeset
3211 arg_base_value = gen_rtx_ADDRESS (VOIDmode, 0);
kono
parents: 67
diff changeset
3212
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3213 memset (static_reg_base_value, 0, sizeof static_reg_base_value);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3214
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3215 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3216 /* Check whether this register can hold an incoming pointer
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3217 argument. FUNCTION_ARG_REGNO_P tests outgoing register
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3218 numbers, so translate if necessary due to register windows. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3219 if (FUNCTION_ARG_REGNO_P (OUTGOING_REGNO (i))
111
kono
parents: 67
diff changeset
3220 && targetm.hard_regno_mode_ok (i, Pmode))
kono
parents: 67
diff changeset
3221 static_reg_base_value[i] = arg_base_value;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3222
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3223 /* RTL code is required to be consistent about whether it uses the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3224 stack pointer, the frame pointer or the argument pointer to
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3225 access a given area of the frame. We can therefore use the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3226 base address to distinguish between the different areas. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3227 static_reg_base_value[STACK_POINTER_REGNUM]
111
kono
parents: 67
diff changeset
3228 = unique_base_value (UNIQUE_BASE_VALUE_SP);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3229 static_reg_base_value[ARG_POINTER_REGNUM]
111
kono
parents: 67
diff changeset
3230 = unique_base_value (UNIQUE_BASE_VALUE_ARGP);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3231 static_reg_base_value[FRAME_POINTER_REGNUM]
111
kono
parents: 67
diff changeset
3232 = unique_base_value (UNIQUE_BASE_VALUE_FP);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3233
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3234 /* The above rules extend post-reload, with eliminations applying
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3235 consistently to each of the three pointers. Cope with cases in
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3236 which the frame pointer is eliminated to the hard frame pointer
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3237 rather than the stack pointer. */
111
kono
parents: 67
diff changeset
3238 if (!HARD_FRAME_POINTER_IS_FRAME_POINTER)
kono
parents: 67
diff changeset
3239 static_reg_base_value[HARD_FRAME_POINTER_REGNUM]
kono
parents: 67
diff changeset
3240 = unique_base_value (UNIQUE_BASE_VALUE_HFP);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3241 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3242
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3243 /* Set MEMORY_MODIFIED when X modifies DATA (that is assumed
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3244 to be memory reference. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3245 static bool memory_modified;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3246 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3247 memory_modified_1 (rtx x, const_rtx pat ATTRIBUTE_UNUSED, void *data)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3248 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3249 if (MEM_P (x))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3250 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3251 if (anti_dependence (x, (const_rtx)data) || output_dependence (x, (const_rtx)data))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3252 memory_modified = true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3253 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3254 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3255
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3256
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3257 /* Return true when INSN possibly modify memory contents of MEM
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3258 (i.e. address can be modified). */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3259 bool
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3260 memory_modified_in_insn_p (const_rtx mem, const_rtx insn)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3261 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3262 if (!INSN_P (insn))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3263 return false;
111
kono
parents: 67
diff changeset
3264 /* Conservatively assume all non-readonly MEMs might be modified in
kono
parents: 67
diff changeset
3265 calls. */
kono
parents: 67
diff changeset
3266 if (CALL_P (insn))
kono
parents: 67
diff changeset
3267 return true;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3268 memory_modified = false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3269 note_stores (PATTERN (insn), memory_modified_1, CONST_CAST_RTX(mem));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3270 return memory_modified;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3271 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3272
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3273 /* Initialize the aliasing machinery. Initialize the REG_KNOWN_VALUE
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3274 array. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3275
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3276 void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3277 init_alias_analysis (void)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3278 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3279 unsigned int maxreg = max_reg_num ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3280 int changed, pass;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3281 int i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3282 unsigned int ui;
111
kono
parents: 67
diff changeset
3283 rtx_insn *insn;
kono
parents: 67
diff changeset
3284 rtx val;
kono
parents: 67
diff changeset
3285 int rpo_cnt;
kono
parents: 67
diff changeset
3286 int *rpo;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3287
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3288 timevar_push (TV_ALIAS_ANALYSIS);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3289
111
kono
parents: 67
diff changeset
3290 vec_safe_grow_cleared (reg_known_value, maxreg - FIRST_PSEUDO_REGISTER);
kono
parents: 67
diff changeset
3291 reg_known_equiv_p = sbitmap_alloc (maxreg - FIRST_PSEUDO_REGISTER);
kono
parents: 67
diff changeset
3292 bitmap_clear (reg_known_equiv_p);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3293
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3294 /* If we have memory allocated from the previous run, use it. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3295 if (old_reg_base_value)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3296 reg_base_value = old_reg_base_value;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3297
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3298 if (reg_base_value)
111
kono
parents: 67
diff changeset
3299 reg_base_value->truncate (0);
kono
parents: 67
diff changeset
3300
kono
parents: 67
diff changeset
3301 vec_safe_grow_cleared (reg_base_value, maxreg);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3302
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3303 new_reg_base_value = XNEWVEC (rtx, maxreg);
111
kono
parents: 67
diff changeset
3304 reg_seen = sbitmap_alloc (maxreg);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3305
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3306 /* The basic idea is that each pass through this loop will use the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3307 "constant" information from the previous pass to propagate alias
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3308 information through another level of assignments.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3309
111
kono
parents: 67
diff changeset
3310 The propagation is done on the CFG in reverse post-order, to propagate
kono
parents: 67
diff changeset
3311 things forward as far as possible in each iteration.
kono
parents: 67
diff changeset
3312
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3313 This could get expensive if the assignment chains are long. Maybe
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3314 we should throttle the number of iterations, possibly based on
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3315 the optimization level or flag_expensive_optimizations.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3316
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3317 We could propagate more information in the first pass by making use
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3318 of DF_REG_DEF_COUNT to determine immediately that the alias information
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3319 for a pseudo is "constant".
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3320
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3321 A program with an uninitialized variable can cause an infinite loop
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3322 here. Instead of doing a full dataflow analysis to detect such problems
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3323 we just cap the number of iterations for the loop.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3324
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3325 The state of the arrays for the set chain in question does not matter
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3326 since the program has undefined behavior. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3327
111
kono
parents: 67
diff changeset
3328 rpo = XNEWVEC (int, n_basic_blocks_for_fn (cfun));
kono
parents: 67
diff changeset
3329 rpo_cnt = pre_and_rev_post_order_compute (NULL, rpo, false);
kono
parents: 67
diff changeset
3330
kono
parents: 67
diff changeset
3331 /* The prologue/epilogue insns are not threaded onto the
kono
parents: 67
diff changeset
3332 insn chain until after reload has completed. Thus,
kono
parents: 67
diff changeset
3333 there is no sense wasting time checking if INSN is in
kono
parents: 67
diff changeset
3334 the prologue/epilogue until after reload has completed. */
kono
parents: 67
diff changeset
3335 bool could_be_prologue_epilogue = ((targetm.have_prologue ()
kono
parents: 67
diff changeset
3336 || targetm.have_epilogue ())
kono
parents: 67
diff changeset
3337 && reload_completed);
kono
parents: 67
diff changeset
3338
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3339 pass = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3340 do
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3341 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3342 /* Assume nothing will change this iteration of the loop. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3343 changed = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3344
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3345 /* We want to assign the same IDs each iteration of this loop, so
111
kono
parents: 67
diff changeset
3346 start counting from one each iteration of the loop. */
kono
parents: 67
diff changeset
3347 unique_id = 1;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3348
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3349 /* We're at the start of the function each iteration through the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3350 loop, so we're copying arguments. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3351 copying_arguments = true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3352
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3353 /* Wipe the potential alias information clean for this pass. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3354 memset (new_reg_base_value, 0, maxreg * sizeof (rtx));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3355
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3356 /* Wipe the reg_seen array clean. */
111
kono
parents: 67
diff changeset
3357 bitmap_clear (reg_seen);
kono
parents: 67
diff changeset
3358
kono
parents: 67
diff changeset
3359 /* Initialize the alias information for this pass. */
kono
parents: 67
diff changeset
3360 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3361 if (static_reg_base_value[i]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3362 /* Don't treat the hard frame pointer as special if we
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3363 eliminated the frame pointer to the stack pointer instead. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3364 && !(i == HARD_FRAME_POINTER_REGNUM
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3365 && reload_completed
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3366 && !frame_pointer_needed
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3367 && targetm.can_eliminate (FRAME_POINTER_REGNUM,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3368 STACK_POINTER_REGNUM)))
111
kono
parents: 67
diff changeset
3369 {
kono
parents: 67
diff changeset
3370 new_reg_base_value[i] = static_reg_base_value[i];
kono
parents: 67
diff changeset
3371 bitmap_set_bit (reg_seen, i);
kono
parents: 67
diff changeset
3372 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3373
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3374 /* Walk the insns adding values to the new_reg_base_value array. */
111
kono
parents: 67
diff changeset
3375 for (i = 0; i < rpo_cnt; i++)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3376 {
111
kono
parents: 67
diff changeset
3377 basic_block bb = BASIC_BLOCK_FOR_FN (cfun, rpo[i]);
kono
parents: 67
diff changeset
3378 FOR_BB_INSNS (bb, insn)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3379 {
111
kono
parents: 67
diff changeset
3380 if (NONDEBUG_INSN_P (insn))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3381 {
111
kono
parents: 67
diff changeset
3382 rtx note, set;
kono
parents: 67
diff changeset
3383
kono
parents: 67
diff changeset
3384 if (could_be_prologue_epilogue
kono
parents: 67
diff changeset
3385 && prologue_epilogue_contains (insn))
kono
parents: 67
diff changeset
3386 continue;
kono
parents: 67
diff changeset
3387
kono
parents: 67
diff changeset
3388 /* If this insn has a noalias note, process it, Otherwise,
kono
parents: 67
diff changeset
3389 scan for sets. A simple set will have no side effects
kono
parents: 67
diff changeset
3390 which could change the base value of any other register. */
kono
parents: 67
diff changeset
3391
kono
parents: 67
diff changeset
3392 if (GET_CODE (PATTERN (insn)) == SET
kono
parents: 67
diff changeset
3393 && REG_NOTES (insn) != 0
kono
parents: 67
diff changeset
3394 && find_reg_note (insn, REG_NOALIAS, NULL_RTX))
kono
parents: 67
diff changeset
3395 record_set (SET_DEST (PATTERN (insn)), NULL_RTX, NULL);
kono
parents: 67
diff changeset
3396 else
kono
parents: 67
diff changeset
3397 note_stores (PATTERN (insn), record_set, NULL);
kono
parents: 67
diff changeset
3398
kono
parents: 67
diff changeset
3399 set = single_set (insn);
kono
parents: 67
diff changeset
3400
kono
parents: 67
diff changeset
3401 if (set != 0
kono
parents: 67
diff changeset
3402 && REG_P (SET_DEST (set))
kono
parents: 67
diff changeset
3403 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3404 {
111
kono
parents: 67
diff changeset
3405 unsigned int regno = REGNO (SET_DEST (set));
kono
parents: 67
diff changeset
3406 rtx src = SET_SRC (set);
kono
parents: 67
diff changeset
3407 rtx t;
kono
parents: 67
diff changeset
3408
kono
parents: 67
diff changeset
3409 note = find_reg_equal_equiv_note (insn);
kono
parents: 67
diff changeset
3410 if (note && REG_NOTE_KIND (note) == REG_EQUAL
kono
parents: 67
diff changeset
3411 && DF_REG_DEF_COUNT (regno) != 1)
kono
parents: 67
diff changeset
3412 note = NULL_RTX;
kono
parents: 67
diff changeset
3413
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3414 poly_int64 offset;
111
kono
parents: 67
diff changeset
3415 if (note != NULL_RTX
kono
parents: 67
diff changeset
3416 && GET_CODE (XEXP (note, 0)) != EXPR_LIST
kono
parents: 67
diff changeset
3417 && ! rtx_varies_p (XEXP (note, 0), 1)
kono
parents: 67
diff changeset
3418 && ! reg_overlap_mentioned_p (SET_DEST (set),
kono
parents: 67
diff changeset
3419 XEXP (note, 0)))
kono
parents: 67
diff changeset
3420 {
kono
parents: 67
diff changeset
3421 set_reg_known_value (regno, XEXP (note, 0));
kono
parents: 67
diff changeset
3422 set_reg_known_equiv_p (regno,
kono
parents: 67
diff changeset
3423 REG_NOTE_KIND (note) == REG_EQUIV);
kono
parents: 67
diff changeset
3424 }
kono
parents: 67
diff changeset
3425 else if (DF_REG_DEF_COUNT (regno) == 1
kono
parents: 67
diff changeset
3426 && GET_CODE (src) == PLUS
kono
parents: 67
diff changeset
3427 && REG_P (XEXP (src, 0))
kono
parents: 67
diff changeset
3428 && (t = get_reg_known_value (REGNO (XEXP (src, 0))))
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3429 && poly_int_rtx_p (XEXP (src, 1), &offset))
111
kono
parents: 67
diff changeset
3430 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3431 t = plus_constant (GET_MODE (src), t, offset);
111
kono
parents: 67
diff changeset
3432 set_reg_known_value (regno, t);
kono
parents: 67
diff changeset
3433 set_reg_known_equiv_p (regno, false);
kono
parents: 67
diff changeset
3434 }
kono
parents: 67
diff changeset
3435 else if (DF_REG_DEF_COUNT (regno) == 1
kono
parents: 67
diff changeset
3436 && ! rtx_varies_p (src, 1))
kono
parents: 67
diff changeset
3437 {
kono
parents: 67
diff changeset
3438 set_reg_known_value (regno, src);
kono
parents: 67
diff changeset
3439 set_reg_known_equiv_p (regno, false);
kono
parents: 67
diff changeset
3440 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3441 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3442 }
111
kono
parents: 67
diff changeset
3443 else if (NOTE_P (insn)
kono
parents: 67
diff changeset
3444 && NOTE_KIND (insn) == NOTE_INSN_FUNCTION_BEG)
kono
parents: 67
diff changeset
3445 copying_arguments = false;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3446 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3447 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3448
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3449 /* Now propagate values from new_reg_base_value to reg_base_value. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3450 gcc_assert (maxreg == (unsigned int) max_reg_num ());
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3451
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3452 for (ui = 0; ui < maxreg; ui++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3453 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3454 if (new_reg_base_value[ui]
111
kono
parents: 67
diff changeset
3455 && new_reg_base_value[ui] != (*reg_base_value)[ui]
kono
parents: 67
diff changeset
3456 && ! rtx_equal_p (new_reg_base_value[ui], (*reg_base_value)[ui]))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3457 {
111
kono
parents: 67
diff changeset
3458 (*reg_base_value)[ui] = new_reg_base_value[ui];
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3459 changed = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3460 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3461 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3462 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3463 while (changed && ++pass < MAX_ALIAS_LOOP_PASSES);
111
kono
parents: 67
diff changeset
3464 XDELETEVEC (rpo);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3465
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3466 /* Fill in the remaining entries. */
111
kono
parents: 67
diff changeset
3467 FOR_EACH_VEC_ELT (*reg_known_value, i, val)
kono
parents: 67
diff changeset
3468 {
kono
parents: 67
diff changeset
3469 int regno = i + FIRST_PSEUDO_REGISTER;
kono
parents: 67
diff changeset
3470 if (! val)
kono
parents: 67
diff changeset
3471 set_reg_known_value (regno, regno_reg_rtx[regno]);
kono
parents: 67
diff changeset
3472 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3473
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3474 /* Clean up. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3475 free (new_reg_base_value);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3476 new_reg_base_value = 0;
111
kono
parents: 67
diff changeset
3477 sbitmap_free (reg_seen);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3478 reg_seen = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3479 timevar_pop (TV_ALIAS_ANALYSIS);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3480 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3481
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
3482 /* Equate REG_BASE_VALUE (reg1) to REG_BASE_VALUE (reg2).
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
3483 Special API for var-tracking pass purposes. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
3484
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
3485 void
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
3486 vt_equate_reg_base_value (const_rtx reg1, const_rtx reg2)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
3487 {
111
kono
parents: 67
diff changeset
3488 (*reg_base_value)[REGNO (reg1)] = REG_BASE_VALUE (reg2);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
3489 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
3490
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3491 void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3492 end_alias_analysis (void)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3493 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3494 old_reg_base_value = reg_base_value;
111
kono
parents: 67
diff changeset
3495 vec_free (reg_known_value);
kono
parents: 67
diff changeset
3496 sbitmap_free (reg_known_equiv_p);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3497 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3498
111
kono
parents: 67
diff changeset
3499 void
kono
parents: 67
diff changeset
3500 dump_alias_stats_in_alias_c (FILE *s)
kono
parents: 67
diff changeset
3501 {
kono
parents: 67
diff changeset
3502 fprintf (s, " TBAA oracle: %llu disambiguations %llu queries\n"
kono
parents: 67
diff changeset
3503 " %llu are in alias set 0\n"
kono
parents: 67
diff changeset
3504 " %llu queries asked about the same object\n"
kono
parents: 67
diff changeset
3505 " %llu queries asked about the same alias set\n"
kono
parents: 67
diff changeset
3506 " %llu access volatile\n"
kono
parents: 67
diff changeset
3507 " %llu are dependent in the DAG\n"
kono
parents: 67
diff changeset
3508 " %llu are aritificially in conflict with void *\n",
kono
parents: 67
diff changeset
3509 alias_stats.num_disambiguated,
kono
parents: 67
diff changeset
3510 alias_stats.num_alias_zero + alias_stats.num_same_alias_set
kono
parents: 67
diff changeset
3511 + alias_stats.num_same_objects + alias_stats.num_volatile
kono
parents: 67
diff changeset
3512 + alias_stats.num_dag + alias_stats.num_disambiguated
kono
parents: 67
diff changeset
3513 + alias_stats.num_universal,
kono
parents: 67
diff changeset
3514 alias_stats.num_alias_zero, alias_stats.num_same_alias_set,
kono
parents: 67
diff changeset
3515 alias_stats.num_same_objects, alias_stats.num_volatile,
kono
parents: 67
diff changeset
3516 alias_stats.num_dag, alias_stats.num_universal);
kono
parents: 67
diff changeset
3517 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3518 #include "gt-alias.h"