1*e4b17023SJohn Marino /* Alias analysis for trees.
2*e4b17023SJohn Marino Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
3*e4b17023SJohn Marino Free Software Foundation, Inc.
4*e4b17023SJohn Marino Contributed by Diego Novillo <dnovillo@redhat.com>
5*e4b17023SJohn Marino
6*e4b17023SJohn Marino This file is part of GCC.
7*e4b17023SJohn Marino
8*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify
9*e4b17023SJohn Marino it under the terms of the GNU General Public License as published by
10*e4b17023SJohn Marino the Free Software Foundation; either version 3, or (at your option)
11*e4b17023SJohn Marino any later version.
12*e4b17023SJohn Marino
13*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful,
14*e4b17023SJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of
15*e4b17023SJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16*e4b17023SJohn Marino GNU General Public License for more details.
17*e4b17023SJohn Marino
18*e4b17023SJohn Marino You should have received a copy of the GNU General Public License
19*e4b17023SJohn Marino along with GCC; see the file COPYING3. If not see
20*e4b17023SJohn Marino <http://www.gnu.org/licenses/>. */
21*e4b17023SJohn Marino
22*e4b17023SJohn Marino #include "config.h"
23*e4b17023SJohn Marino #include "system.h"
24*e4b17023SJohn Marino #include "coretypes.h"
25*e4b17023SJohn Marino #include "tm.h"
26*e4b17023SJohn Marino #include "tree.h"
27*e4b17023SJohn Marino #include "tm_p.h"
28*e4b17023SJohn Marino #include "target.h"
29*e4b17023SJohn Marino #include "basic-block.h"
30*e4b17023SJohn Marino #include "timevar.h"
31*e4b17023SJohn Marino #include "ggc.h"
32*e4b17023SJohn Marino #include "langhooks.h"
33*e4b17023SJohn Marino #include "flags.h"
34*e4b17023SJohn Marino #include "function.h"
35*e4b17023SJohn Marino #include "tree-pretty-print.h"
36*e4b17023SJohn Marino #include "tree-dump.h"
37*e4b17023SJohn Marino #include "gimple.h"
38*e4b17023SJohn Marino #include "tree-flow.h"
39*e4b17023SJohn Marino #include "tree-inline.h"
40*e4b17023SJohn Marino #include "tree-pass.h"
41*e4b17023SJohn Marino #include "convert.h"
42*e4b17023SJohn Marino #include "params.h"
43*e4b17023SJohn Marino #include "vec.h"
44*e4b17023SJohn Marino #include "bitmap.h"
45*e4b17023SJohn Marino #include "vecprim.h"
46*e4b17023SJohn Marino #include "pointer-set.h"
47*e4b17023SJohn Marino #include "alloc-pool.h"
48*e4b17023SJohn Marino #include "tree-ssa-alias.h"
49*e4b17023SJohn Marino
50*e4b17023SJohn Marino /* Broad overview of how alias analysis on gimple works:
51*e4b17023SJohn Marino
52*e4b17023SJohn Marino Statements clobbering or using memory are linked through the
53*e4b17023SJohn Marino virtual operand factored use-def chain. The virtual operand
54*e4b17023SJohn Marino is unique per function, its symbol is accessible via gimple_vop (cfun).
55*e4b17023SJohn Marino Virtual operands are used for efficiently walking memory statements
56*e4b17023SJohn Marino in the gimple IL and are useful for things like value-numbering as
57*e4b17023SJohn Marino a generation count for memory references.
58*e4b17023SJohn Marino
59*e4b17023SJohn Marino SSA_NAME pointers may have associated points-to information
60*e4b17023SJohn Marino accessible via the SSA_NAME_PTR_INFO macro. Flow-insensitive
61*e4b17023SJohn Marino points-to information is (re-)computed by the TODO_rebuild_alias
62*e4b17023SJohn Marino pass manager todo. Points-to information is also used for more
63*e4b17023SJohn Marino precise tracking of call-clobbered and call-used variables and
64*e4b17023SJohn Marino related disambiguations.
65*e4b17023SJohn Marino
66*e4b17023SJohn Marino This file contains functions for disambiguating memory references,
67*e4b17023SJohn Marino the so called alias-oracle and tools for walking of the gimple IL.
68*e4b17023SJohn Marino
69*e4b17023SJohn Marino The main alias-oracle entry-points are
70*e4b17023SJohn Marino
71*e4b17023SJohn Marino bool stmt_may_clobber_ref_p (gimple, tree)
72*e4b17023SJohn Marino
73*e4b17023SJohn Marino This function queries if a statement may invalidate (parts of)
74*e4b17023SJohn Marino the memory designated by the reference tree argument.
75*e4b17023SJohn Marino
76*e4b17023SJohn Marino bool ref_maybe_used_by_stmt_p (gimple, tree)
77*e4b17023SJohn Marino
78*e4b17023SJohn Marino This function queries if a statement may need (parts of) the
79*e4b17023SJohn Marino memory designated by the reference tree argument.
80*e4b17023SJohn Marino
81*e4b17023SJohn Marino There are variants of these functions that only handle the call
82*e4b17023SJohn Marino part of a statement, call_may_clobber_ref_p and ref_maybe_used_by_call_p.
83*e4b17023SJohn Marino Note that these do not disambiguate against a possible call lhs.
84*e4b17023SJohn Marino
85*e4b17023SJohn Marino bool refs_may_alias_p (tree, tree)
86*e4b17023SJohn Marino
87*e4b17023SJohn Marino This function tries to disambiguate two reference trees.
88*e4b17023SJohn Marino
89*e4b17023SJohn Marino bool ptr_deref_may_alias_global_p (tree)
90*e4b17023SJohn Marino
91*e4b17023SJohn Marino This function queries if dereferencing a pointer variable may
92*e4b17023SJohn Marino alias global memory.
93*e4b17023SJohn Marino
94*e4b17023SJohn Marino More low-level disambiguators are available and documented in
95*e4b17023SJohn Marino this file. Low-level disambiguators dealing with points-to
96*e4b17023SJohn Marino information are in tree-ssa-structalias.c. */
97*e4b17023SJohn Marino
98*e4b17023SJohn Marino
99*e4b17023SJohn Marino /* Query statistics for the different low-level disambiguators.
100*e4b17023SJohn Marino A high-level query may trigger multiple of them. */
101*e4b17023SJohn Marino
102*e4b17023SJohn Marino static struct {
103*e4b17023SJohn Marino unsigned HOST_WIDE_INT refs_may_alias_p_may_alias;
104*e4b17023SJohn Marino unsigned HOST_WIDE_INT refs_may_alias_p_no_alias;
105*e4b17023SJohn Marino unsigned HOST_WIDE_INT ref_maybe_used_by_call_p_may_alias;
106*e4b17023SJohn Marino unsigned HOST_WIDE_INT ref_maybe_used_by_call_p_no_alias;
107*e4b17023SJohn Marino unsigned HOST_WIDE_INT call_may_clobber_ref_p_may_alias;
108*e4b17023SJohn Marino unsigned HOST_WIDE_INT call_may_clobber_ref_p_no_alias;
109*e4b17023SJohn Marino } alias_stats;
110*e4b17023SJohn Marino
111*e4b17023SJohn Marino void
dump_alias_stats(FILE * s)112*e4b17023SJohn Marino dump_alias_stats (FILE *s)
113*e4b17023SJohn Marino {
114*e4b17023SJohn Marino fprintf (s, "\nAlias oracle query stats:\n");
115*e4b17023SJohn Marino fprintf (s, " refs_may_alias_p: "
116*e4b17023SJohn Marino HOST_WIDE_INT_PRINT_DEC" disambiguations, "
117*e4b17023SJohn Marino HOST_WIDE_INT_PRINT_DEC" queries\n",
118*e4b17023SJohn Marino alias_stats.refs_may_alias_p_no_alias,
119*e4b17023SJohn Marino alias_stats.refs_may_alias_p_no_alias
120*e4b17023SJohn Marino + alias_stats.refs_may_alias_p_may_alias);
121*e4b17023SJohn Marino fprintf (s, " ref_maybe_used_by_call_p: "
122*e4b17023SJohn Marino HOST_WIDE_INT_PRINT_DEC" disambiguations, "
123*e4b17023SJohn Marino HOST_WIDE_INT_PRINT_DEC" queries\n",
124*e4b17023SJohn Marino alias_stats.ref_maybe_used_by_call_p_no_alias,
125*e4b17023SJohn Marino alias_stats.refs_may_alias_p_no_alias
126*e4b17023SJohn Marino + alias_stats.ref_maybe_used_by_call_p_may_alias);
127*e4b17023SJohn Marino fprintf (s, " call_may_clobber_ref_p: "
128*e4b17023SJohn Marino HOST_WIDE_INT_PRINT_DEC" disambiguations, "
129*e4b17023SJohn Marino HOST_WIDE_INT_PRINT_DEC" queries\n",
130*e4b17023SJohn Marino alias_stats.call_may_clobber_ref_p_no_alias,
131*e4b17023SJohn Marino alias_stats.call_may_clobber_ref_p_no_alias
132*e4b17023SJohn Marino + alias_stats.call_may_clobber_ref_p_may_alias);
133*e4b17023SJohn Marino }
134*e4b17023SJohn Marino
135*e4b17023SJohn Marino
136*e4b17023SJohn Marino /* Return true, if dereferencing PTR may alias with a global variable. */
137*e4b17023SJohn Marino
138*e4b17023SJohn Marino bool
ptr_deref_may_alias_global_p(tree ptr)139*e4b17023SJohn Marino ptr_deref_may_alias_global_p (tree ptr)
140*e4b17023SJohn Marino {
141*e4b17023SJohn Marino struct ptr_info_def *pi;
142*e4b17023SJohn Marino
143*e4b17023SJohn Marino /* If we end up with a pointer constant here that may point
144*e4b17023SJohn Marino to global memory. */
145*e4b17023SJohn Marino if (TREE_CODE (ptr) != SSA_NAME)
146*e4b17023SJohn Marino return true;
147*e4b17023SJohn Marino
148*e4b17023SJohn Marino pi = SSA_NAME_PTR_INFO (ptr);
149*e4b17023SJohn Marino
150*e4b17023SJohn Marino /* If we do not have points-to information for this variable,
151*e4b17023SJohn Marino we have to punt. */
152*e4b17023SJohn Marino if (!pi)
153*e4b17023SJohn Marino return true;
154*e4b17023SJohn Marino
155*e4b17023SJohn Marino /* ??? This does not use TBAA to prune globals ptr may not access. */
156*e4b17023SJohn Marino return pt_solution_includes_global (&pi->pt);
157*e4b17023SJohn Marino }
158*e4b17023SJohn Marino
159*e4b17023SJohn Marino /* Return true if dereferencing PTR may alias DECL.
160*e4b17023SJohn Marino The caller is responsible for applying TBAA to see if PTR
161*e4b17023SJohn Marino may access DECL at all. */
162*e4b17023SJohn Marino
163*e4b17023SJohn Marino static bool
ptr_deref_may_alias_decl_p(tree ptr,tree decl)164*e4b17023SJohn Marino ptr_deref_may_alias_decl_p (tree ptr, tree decl)
165*e4b17023SJohn Marino {
166*e4b17023SJohn Marino struct ptr_info_def *pi;
167*e4b17023SJohn Marino
168*e4b17023SJohn Marino /* Conversions are irrelevant for points-to information and
169*e4b17023SJohn Marino data-dependence analysis can feed us those. */
170*e4b17023SJohn Marino STRIP_NOPS (ptr);
171*e4b17023SJohn Marino
172*e4b17023SJohn Marino /* Anything we do not explicilty handle aliases. */
173*e4b17023SJohn Marino if ((TREE_CODE (ptr) != SSA_NAME
174*e4b17023SJohn Marino && TREE_CODE (ptr) != ADDR_EXPR
175*e4b17023SJohn Marino && TREE_CODE (ptr) != POINTER_PLUS_EXPR)
176*e4b17023SJohn Marino || !POINTER_TYPE_P (TREE_TYPE (ptr))
177*e4b17023SJohn Marino || (TREE_CODE (decl) != VAR_DECL
178*e4b17023SJohn Marino && TREE_CODE (decl) != PARM_DECL
179*e4b17023SJohn Marino && TREE_CODE (decl) != RESULT_DECL))
180*e4b17023SJohn Marino return true;
181*e4b17023SJohn Marino
182*e4b17023SJohn Marino /* Disregard pointer offsetting. */
183*e4b17023SJohn Marino if (TREE_CODE (ptr) == POINTER_PLUS_EXPR)
184*e4b17023SJohn Marino {
185*e4b17023SJohn Marino do
186*e4b17023SJohn Marino {
187*e4b17023SJohn Marino ptr = TREE_OPERAND (ptr, 0);
188*e4b17023SJohn Marino }
189*e4b17023SJohn Marino while (TREE_CODE (ptr) == POINTER_PLUS_EXPR);
190*e4b17023SJohn Marino return ptr_deref_may_alias_decl_p (ptr, decl);
191*e4b17023SJohn Marino }
192*e4b17023SJohn Marino
193*e4b17023SJohn Marino /* ADDR_EXPR pointers either just offset another pointer or directly
194*e4b17023SJohn Marino specify the pointed-to set. */
195*e4b17023SJohn Marino if (TREE_CODE (ptr) == ADDR_EXPR)
196*e4b17023SJohn Marino {
197*e4b17023SJohn Marino tree base = get_base_address (TREE_OPERAND (ptr, 0));
198*e4b17023SJohn Marino if (base
199*e4b17023SJohn Marino && (TREE_CODE (base) == MEM_REF
200*e4b17023SJohn Marino || TREE_CODE (base) == TARGET_MEM_REF))
201*e4b17023SJohn Marino ptr = TREE_OPERAND (base, 0);
202*e4b17023SJohn Marino else if (base
203*e4b17023SJohn Marino && DECL_P (base))
204*e4b17023SJohn Marino return base == decl;
205*e4b17023SJohn Marino else if (base
206*e4b17023SJohn Marino && CONSTANT_CLASS_P (base))
207*e4b17023SJohn Marino return false;
208*e4b17023SJohn Marino else
209*e4b17023SJohn Marino return true;
210*e4b17023SJohn Marino }
211*e4b17023SJohn Marino
212*e4b17023SJohn Marino /* Non-aliased variables can not be pointed to. */
213*e4b17023SJohn Marino if (!may_be_aliased (decl))
214*e4b17023SJohn Marino return false;
215*e4b17023SJohn Marino
216*e4b17023SJohn Marino /* If we do not have useful points-to information for this pointer
217*e4b17023SJohn Marino we cannot disambiguate anything else. */
218*e4b17023SJohn Marino pi = SSA_NAME_PTR_INFO (ptr);
219*e4b17023SJohn Marino if (!pi)
220*e4b17023SJohn Marino return true;
221*e4b17023SJohn Marino
222*e4b17023SJohn Marino return pt_solution_includes (&pi->pt, decl);
223*e4b17023SJohn Marino }
224*e4b17023SJohn Marino
225*e4b17023SJohn Marino /* Return true if dereferenced PTR1 and PTR2 may alias.
226*e4b17023SJohn Marino The caller is responsible for applying TBAA to see if accesses
227*e4b17023SJohn Marino through PTR1 and PTR2 may conflict at all. */
228*e4b17023SJohn Marino
229*e4b17023SJohn Marino bool
ptr_derefs_may_alias_p(tree ptr1,tree ptr2)230*e4b17023SJohn Marino ptr_derefs_may_alias_p (tree ptr1, tree ptr2)
231*e4b17023SJohn Marino {
232*e4b17023SJohn Marino struct ptr_info_def *pi1, *pi2;
233*e4b17023SJohn Marino
234*e4b17023SJohn Marino /* Conversions are irrelevant for points-to information and
235*e4b17023SJohn Marino data-dependence analysis can feed us those. */
236*e4b17023SJohn Marino STRIP_NOPS (ptr1);
237*e4b17023SJohn Marino STRIP_NOPS (ptr2);
238*e4b17023SJohn Marino
239*e4b17023SJohn Marino /* Disregard pointer offsetting. */
240*e4b17023SJohn Marino if (TREE_CODE (ptr1) == POINTER_PLUS_EXPR)
241*e4b17023SJohn Marino {
242*e4b17023SJohn Marino do
243*e4b17023SJohn Marino {
244*e4b17023SJohn Marino ptr1 = TREE_OPERAND (ptr1, 0);
245*e4b17023SJohn Marino }
246*e4b17023SJohn Marino while (TREE_CODE (ptr1) == POINTER_PLUS_EXPR);
247*e4b17023SJohn Marino return ptr_derefs_may_alias_p (ptr1, ptr2);
248*e4b17023SJohn Marino }
249*e4b17023SJohn Marino if (TREE_CODE (ptr2) == POINTER_PLUS_EXPR)
250*e4b17023SJohn Marino {
251*e4b17023SJohn Marino do
252*e4b17023SJohn Marino {
253*e4b17023SJohn Marino ptr2 = TREE_OPERAND (ptr2, 0);
254*e4b17023SJohn Marino }
255*e4b17023SJohn Marino while (TREE_CODE (ptr2) == POINTER_PLUS_EXPR);
256*e4b17023SJohn Marino return ptr_derefs_may_alias_p (ptr1, ptr2);
257*e4b17023SJohn Marino }
258*e4b17023SJohn Marino
259*e4b17023SJohn Marino /* ADDR_EXPR pointers either just offset another pointer or directly
260*e4b17023SJohn Marino specify the pointed-to set. */
261*e4b17023SJohn Marino if (TREE_CODE (ptr1) == ADDR_EXPR)
262*e4b17023SJohn Marino {
263*e4b17023SJohn Marino tree base = get_base_address (TREE_OPERAND (ptr1, 0));
264*e4b17023SJohn Marino if (base
265*e4b17023SJohn Marino && (TREE_CODE (base) == MEM_REF
266*e4b17023SJohn Marino || TREE_CODE (base) == TARGET_MEM_REF))
267*e4b17023SJohn Marino return ptr_derefs_may_alias_p (TREE_OPERAND (base, 0), ptr2);
268*e4b17023SJohn Marino else if (base
269*e4b17023SJohn Marino && DECL_P (base))
270*e4b17023SJohn Marino return ptr_deref_may_alias_decl_p (ptr2, base);
271*e4b17023SJohn Marino else
272*e4b17023SJohn Marino return true;
273*e4b17023SJohn Marino }
274*e4b17023SJohn Marino if (TREE_CODE (ptr2) == ADDR_EXPR)
275*e4b17023SJohn Marino {
276*e4b17023SJohn Marino tree base = get_base_address (TREE_OPERAND (ptr2, 0));
277*e4b17023SJohn Marino if (base
278*e4b17023SJohn Marino && (TREE_CODE (base) == MEM_REF
279*e4b17023SJohn Marino || TREE_CODE (base) == TARGET_MEM_REF))
280*e4b17023SJohn Marino return ptr_derefs_may_alias_p (ptr1, TREE_OPERAND (base, 0));
281*e4b17023SJohn Marino else if (base
282*e4b17023SJohn Marino && DECL_P (base))
283*e4b17023SJohn Marino return ptr_deref_may_alias_decl_p (ptr1, base);
284*e4b17023SJohn Marino else
285*e4b17023SJohn Marino return true;
286*e4b17023SJohn Marino }
287*e4b17023SJohn Marino
288*e4b17023SJohn Marino /* From here we require SSA name pointers. Anything else aliases. */
289*e4b17023SJohn Marino if (TREE_CODE (ptr1) != SSA_NAME
290*e4b17023SJohn Marino || TREE_CODE (ptr2) != SSA_NAME
291*e4b17023SJohn Marino || !POINTER_TYPE_P (TREE_TYPE (ptr1))
292*e4b17023SJohn Marino || !POINTER_TYPE_P (TREE_TYPE (ptr2)))
293*e4b17023SJohn Marino return true;
294*e4b17023SJohn Marino
295*e4b17023SJohn Marino /* We may end up with two empty points-to solutions for two same pointers.
296*e4b17023SJohn Marino In this case we still want to say both pointers alias, so shortcut
297*e4b17023SJohn Marino that here. */
298*e4b17023SJohn Marino if (ptr1 == ptr2)
299*e4b17023SJohn Marino return true;
300*e4b17023SJohn Marino
301*e4b17023SJohn Marino /* If we do not have useful points-to information for either pointer
302*e4b17023SJohn Marino we cannot disambiguate anything else. */
303*e4b17023SJohn Marino pi1 = SSA_NAME_PTR_INFO (ptr1);
304*e4b17023SJohn Marino pi2 = SSA_NAME_PTR_INFO (ptr2);
305*e4b17023SJohn Marino if (!pi1 || !pi2)
306*e4b17023SJohn Marino return true;
307*e4b17023SJohn Marino
308*e4b17023SJohn Marino /* ??? This does not use TBAA to prune decls from the intersection
309*e4b17023SJohn Marino that not both pointers may access. */
310*e4b17023SJohn Marino return pt_solutions_intersect (&pi1->pt, &pi2->pt);
311*e4b17023SJohn Marino }
312*e4b17023SJohn Marino
313*e4b17023SJohn Marino /* Return true if dereferencing PTR may alias *REF.
314*e4b17023SJohn Marino The caller is responsible for applying TBAA to see if PTR
315*e4b17023SJohn Marino may access *REF at all. */
316*e4b17023SJohn Marino
317*e4b17023SJohn Marino static bool
ptr_deref_may_alias_ref_p_1(tree ptr,ao_ref * ref)318*e4b17023SJohn Marino ptr_deref_may_alias_ref_p_1 (tree ptr, ao_ref *ref)
319*e4b17023SJohn Marino {
320*e4b17023SJohn Marino tree base = ao_ref_base (ref);
321*e4b17023SJohn Marino
322*e4b17023SJohn Marino if (TREE_CODE (base) == MEM_REF
323*e4b17023SJohn Marino || TREE_CODE (base) == TARGET_MEM_REF)
324*e4b17023SJohn Marino return ptr_derefs_may_alias_p (ptr, TREE_OPERAND (base, 0));
325*e4b17023SJohn Marino else if (DECL_P (base))
326*e4b17023SJohn Marino return ptr_deref_may_alias_decl_p (ptr, base);
327*e4b17023SJohn Marino
328*e4b17023SJohn Marino return true;
329*e4b17023SJohn Marino }
330*e4b17023SJohn Marino
331*e4b17023SJohn Marino
332*e4b17023SJohn Marino /* Dump alias information on FILE. */
333*e4b17023SJohn Marino
334*e4b17023SJohn Marino void
dump_alias_info(FILE * file)335*e4b17023SJohn Marino dump_alias_info (FILE *file)
336*e4b17023SJohn Marino {
337*e4b17023SJohn Marino size_t i;
338*e4b17023SJohn Marino const char *funcname
339*e4b17023SJohn Marino = lang_hooks.decl_printable_name (current_function_decl, 2);
340*e4b17023SJohn Marino referenced_var_iterator rvi;
341*e4b17023SJohn Marino tree var;
342*e4b17023SJohn Marino
343*e4b17023SJohn Marino fprintf (file, "\n\nAlias information for %s\n\n", funcname);
344*e4b17023SJohn Marino
345*e4b17023SJohn Marino fprintf (file, "Aliased symbols\n\n");
346*e4b17023SJohn Marino
347*e4b17023SJohn Marino FOR_EACH_REFERENCED_VAR (cfun, var, rvi)
348*e4b17023SJohn Marino {
349*e4b17023SJohn Marino if (may_be_aliased (var))
350*e4b17023SJohn Marino dump_variable (file, var);
351*e4b17023SJohn Marino }
352*e4b17023SJohn Marino
353*e4b17023SJohn Marino fprintf (file, "\nCall clobber information\n");
354*e4b17023SJohn Marino
355*e4b17023SJohn Marino fprintf (file, "\nESCAPED");
356*e4b17023SJohn Marino dump_points_to_solution (file, &cfun->gimple_df->escaped);
357*e4b17023SJohn Marino
358*e4b17023SJohn Marino fprintf (file, "\n\nFlow-insensitive points-to information\n\n");
359*e4b17023SJohn Marino
360*e4b17023SJohn Marino for (i = 1; i < num_ssa_names; i++)
361*e4b17023SJohn Marino {
362*e4b17023SJohn Marino tree ptr = ssa_name (i);
363*e4b17023SJohn Marino struct ptr_info_def *pi;
364*e4b17023SJohn Marino
365*e4b17023SJohn Marino if (ptr == NULL_TREE
366*e4b17023SJohn Marino || SSA_NAME_IN_FREE_LIST (ptr))
367*e4b17023SJohn Marino continue;
368*e4b17023SJohn Marino
369*e4b17023SJohn Marino pi = SSA_NAME_PTR_INFO (ptr);
370*e4b17023SJohn Marino if (pi)
371*e4b17023SJohn Marino dump_points_to_info_for (file, ptr);
372*e4b17023SJohn Marino }
373*e4b17023SJohn Marino
374*e4b17023SJohn Marino fprintf (file, "\n");
375*e4b17023SJohn Marino }
376*e4b17023SJohn Marino
377*e4b17023SJohn Marino
378*e4b17023SJohn Marino /* Dump alias information on stderr. */
379*e4b17023SJohn Marino
380*e4b17023SJohn Marino DEBUG_FUNCTION void
debug_alias_info(void)381*e4b17023SJohn Marino debug_alias_info (void)
382*e4b17023SJohn Marino {
383*e4b17023SJohn Marino dump_alias_info (stderr);
384*e4b17023SJohn Marino }
385*e4b17023SJohn Marino
386*e4b17023SJohn Marino
387*e4b17023SJohn Marino /* Dump the points-to set *PT into FILE. */
388*e4b17023SJohn Marino
389*e4b17023SJohn Marino void
dump_points_to_solution(FILE * file,struct pt_solution * pt)390*e4b17023SJohn Marino dump_points_to_solution (FILE *file, struct pt_solution *pt)
391*e4b17023SJohn Marino {
392*e4b17023SJohn Marino if (pt->anything)
393*e4b17023SJohn Marino fprintf (file, ", points-to anything");
394*e4b17023SJohn Marino
395*e4b17023SJohn Marino if (pt->nonlocal)
396*e4b17023SJohn Marino fprintf (file, ", points-to non-local");
397*e4b17023SJohn Marino
398*e4b17023SJohn Marino if (pt->escaped)
399*e4b17023SJohn Marino fprintf (file, ", points-to escaped");
400*e4b17023SJohn Marino
401*e4b17023SJohn Marino if (pt->ipa_escaped)
402*e4b17023SJohn Marino fprintf (file, ", points-to unit escaped");
403*e4b17023SJohn Marino
404*e4b17023SJohn Marino if (pt->null)
405*e4b17023SJohn Marino fprintf (file, ", points-to NULL");
406*e4b17023SJohn Marino
407*e4b17023SJohn Marino if (pt->vars)
408*e4b17023SJohn Marino {
409*e4b17023SJohn Marino fprintf (file, ", points-to vars: ");
410*e4b17023SJohn Marino dump_decl_set (file, pt->vars);
411*e4b17023SJohn Marino if (pt->vars_contains_global)
412*e4b17023SJohn Marino fprintf (file, " (includes global vars)");
413*e4b17023SJohn Marino }
414*e4b17023SJohn Marino }
415*e4b17023SJohn Marino
416*e4b17023SJohn Marino /* Dump points-to information for SSA_NAME PTR into FILE. */
417*e4b17023SJohn Marino
418*e4b17023SJohn Marino void
dump_points_to_info_for(FILE * file,tree ptr)419*e4b17023SJohn Marino dump_points_to_info_for (FILE *file, tree ptr)
420*e4b17023SJohn Marino {
421*e4b17023SJohn Marino struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr);
422*e4b17023SJohn Marino
423*e4b17023SJohn Marino print_generic_expr (file, ptr, dump_flags);
424*e4b17023SJohn Marino
425*e4b17023SJohn Marino if (pi)
426*e4b17023SJohn Marino dump_points_to_solution (file, &pi->pt);
427*e4b17023SJohn Marino else
428*e4b17023SJohn Marino fprintf (file, ", points-to anything");
429*e4b17023SJohn Marino
430*e4b17023SJohn Marino fprintf (file, "\n");
431*e4b17023SJohn Marino }
432*e4b17023SJohn Marino
433*e4b17023SJohn Marino
434*e4b17023SJohn Marino /* Dump points-to information for VAR into stderr. */
435*e4b17023SJohn Marino
436*e4b17023SJohn Marino DEBUG_FUNCTION void
debug_points_to_info_for(tree var)437*e4b17023SJohn Marino debug_points_to_info_for (tree var)
438*e4b17023SJohn Marino {
439*e4b17023SJohn Marino dump_points_to_info_for (stderr, var);
440*e4b17023SJohn Marino }
441*e4b17023SJohn Marino
442*e4b17023SJohn Marino
443*e4b17023SJohn Marino /* Initializes the alias-oracle reference representation *R from REF. */
444*e4b17023SJohn Marino
445*e4b17023SJohn Marino void
ao_ref_init(ao_ref * r,tree ref)446*e4b17023SJohn Marino ao_ref_init (ao_ref *r, tree ref)
447*e4b17023SJohn Marino {
448*e4b17023SJohn Marino r->ref = ref;
449*e4b17023SJohn Marino r->base = NULL_TREE;
450*e4b17023SJohn Marino r->offset = 0;
451*e4b17023SJohn Marino r->size = -1;
452*e4b17023SJohn Marino r->max_size = -1;
453*e4b17023SJohn Marino r->ref_alias_set = -1;
454*e4b17023SJohn Marino r->base_alias_set = -1;
455*e4b17023SJohn Marino r->volatile_p = ref ? TREE_THIS_VOLATILE (ref) : false;
456*e4b17023SJohn Marino }
457*e4b17023SJohn Marino
458*e4b17023SJohn Marino /* Returns the base object of the memory reference *REF. */
459*e4b17023SJohn Marino
460*e4b17023SJohn Marino tree
ao_ref_base(ao_ref * ref)461*e4b17023SJohn Marino ao_ref_base (ao_ref *ref)
462*e4b17023SJohn Marino {
463*e4b17023SJohn Marino if (ref->base)
464*e4b17023SJohn Marino return ref->base;
465*e4b17023SJohn Marino ref->base = get_ref_base_and_extent (ref->ref, &ref->offset, &ref->size,
466*e4b17023SJohn Marino &ref->max_size);
467*e4b17023SJohn Marino return ref->base;
468*e4b17023SJohn Marino }
469*e4b17023SJohn Marino
470*e4b17023SJohn Marino /* Returns the base object alias set of the memory reference *REF. */
471*e4b17023SJohn Marino
472*e4b17023SJohn Marino static alias_set_type
ao_ref_base_alias_set(ao_ref * ref)473*e4b17023SJohn Marino ao_ref_base_alias_set (ao_ref *ref)
474*e4b17023SJohn Marino {
475*e4b17023SJohn Marino tree base_ref;
476*e4b17023SJohn Marino if (ref->base_alias_set != -1)
477*e4b17023SJohn Marino return ref->base_alias_set;
478*e4b17023SJohn Marino if (!ref->ref)
479*e4b17023SJohn Marino return 0;
480*e4b17023SJohn Marino base_ref = ref->ref;
481*e4b17023SJohn Marino while (handled_component_p (base_ref))
482*e4b17023SJohn Marino base_ref = TREE_OPERAND (base_ref, 0);
483*e4b17023SJohn Marino ref->base_alias_set = get_alias_set (base_ref);
484*e4b17023SJohn Marino return ref->base_alias_set;
485*e4b17023SJohn Marino }
486*e4b17023SJohn Marino
487*e4b17023SJohn Marino /* Returns the reference alias set of the memory reference *REF. */
488*e4b17023SJohn Marino
489*e4b17023SJohn Marino alias_set_type
ao_ref_alias_set(ao_ref * ref)490*e4b17023SJohn Marino ao_ref_alias_set (ao_ref *ref)
491*e4b17023SJohn Marino {
492*e4b17023SJohn Marino if (ref->ref_alias_set != -1)
493*e4b17023SJohn Marino return ref->ref_alias_set;
494*e4b17023SJohn Marino ref->ref_alias_set = get_alias_set (ref->ref);
495*e4b17023SJohn Marino return ref->ref_alias_set;
496*e4b17023SJohn Marino }
497*e4b17023SJohn Marino
498*e4b17023SJohn Marino /* Init an alias-oracle reference representation from a gimple pointer
499*e4b17023SJohn Marino PTR and a gimple size SIZE in bytes. If SIZE is NULL_TREE the the
500*e4b17023SJohn Marino size is assumed to be unknown. The access is assumed to be only
501*e4b17023SJohn Marino to or after of the pointer target, not before it. */
502*e4b17023SJohn Marino
503*e4b17023SJohn Marino void
ao_ref_init_from_ptr_and_size(ao_ref * ref,tree ptr,tree size)504*e4b17023SJohn Marino ao_ref_init_from_ptr_and_size (ao_ref *ref, tree ptr, tree size)
505*e4b17023SJohn Marino {
506*e4b17023SJohn Marino HOST_WIDE_INT t1, t2;
507*e4b17023SJohn Marino ref->ref = NULL_TREE;
508*e4b17023SJohn Marino if (TREE_CODE (ptr) == ADDR_EXPR)
509*e4b17023SJohn Marino ref->base = get_ref_base_and_extent (TREE_OPERAND (ptr, 0),
510*e4b17023SJohn Marino &ref->offset, &t1, &t2);
511*e4b17023SJohn Marino else
512*e4b17023SJohn Marino {
513*e4b17023SJohn Marino ref->base = build2 (MEM_REF, char_type_node,
514*e4b17023SJohn Marino ptr, null_pointer_node);
515*e4b17023SJohn Marino ref->offset = 0;
516*e4b17023SJohn Marino }
517*e4b17023SJohn Marino if (size
518*e4b17023SJohn Marino && host_integerp (size, 0)
519*e4b17023SJohn Marino && TREE_INT_CST_LOW (size) * 8 / 8 == TREE_INT_CST_LOW (size))
520*e4b17023SJohn Marino ref->max_size = ref->size = TREE_INT_CST_LOW (size) * 8;
521*e4b17023SJohn Marino else
522*e4b17023SJohn Marino ref->max_size = ref->size = -1;
523*e4b17023SJohn Marino ref->ref_alias_set = 0;
524*e4b17023SJohn Marino ref->base_alias_set = 0;
525*e4b17023SJohn Marino ref->volatile_p = false;
526*e4b17023SJohn Marino }
527*e4b17023SJohn Marino
528*e4b17023SJohn Marino /* Return 1 if TYPE1 and TYPE2 are to be considered equivalent for the
529*e4b17023SJohn Marino purpose of TBAA. Return 0 if they are distinct and -1 if we cannot
530*e4b17023SJohn Marino decide. */
531*e4b17023SJohn Marino
532*e4b17023SJohn Marino static inline int
same_type_for_tbaa(tree type1,tree type2)533*e4b17023SJohn Marino same_type_for_tbaa (tree type1, tree type2)
534*e4b17023SJohn Marino {
535*e4b17023SJohn Marino type1 = TYPE_MAIN_VARIANT (type1);
536*e4b17023SJohn Marino type2 = TYPE_MAIN_VARIANT (type2);
537*e4b17023SJohn Marino
538*e4b17023SJohn Marino /* If we would have to do structural comparison bail out. */
539*e4b17023SJohn Marino if (TYPE_STRUCTURAL_EQUALITY_P (type1)
540*e4b17023SJohn Marino || TYPE_STRUCTURAL_EQUALITY_P (type2))
541*e4b17023SJohn Marino return -1;
542*e4b17023SJohn Marino
543*e4b17023SJohn Marino /* Compare the canonical types. */
544*e4b17023SJohn Marino if (TYPE_CANONICAL (type1) == TYPE_CANONICAL (type2))
545*e4b17023SJohn Marino return 1;
546*e4b17023SJohn Marino
547*e4b17023SJohn Marino /* ??? Array types are not properly unified in all cases as we have
548*e4b17023SJohn Marino spurious changes in the index types for example. Removing this
549*e4b17023SJohn Marino causes all sorts of problems with the Fortran frontend. */
550*e4b17023SJohn Marino if (TREE_CODE (type1) == ARRAY_TYPE
551*e4b17023SJohn Marino && TREE_CODE (type2) == ARRAY_TYPE)
552*e4b17023SJohn Marino return -1;
553*e4b17023SJohn Marino
554*e4b17023SJohn Marino /* ??? In Ada, an lvalue of an unconstrained type can be used to access an
555*e4b17023SJohn Marino object of one of its constrained subtypes, e.g. when a function with an
556*e4b17023SJohn Marino unconstrained parameter passed by reference is called on an object and
557*e4b17023SJohn Marino inlined. But, even in the case of a fixed size, type and subtypes are
558*e4b17023SJohn Marino not equivalent enough as to share the same TYPE_CANONICAL, since this
559*e4b17023SJohn Marino would mean that conversions between them are useless, whereas they are
560*e4b17023SJohn Marino not (e.g. type and subtypes can have different modes). So, in the end,
561*e4b17023SJohn Marino they are only guaranteed to have the same alias set. */
562*e4b17023SJohn Marino if (get_alias_set (type1) == get_alias_set (type2))
563*e4b17023SJohn Marino return -1;
564*e4b17023SJohn Marino
565*e4b17023SJohn Marino /* The types are known to be not equal. */
566*e4b17023SJohn Marino return 0;
567*e4b17023SJohn Marino }
568*e4b17023SJohn Marino
569*e4b17023SJohn Marino /* Determine if the two component references REF1 and REF2 which are
570*e4b17023SJohn Marino based on access types TYPE1 and TYPE2 and of which at least one is based
571*e4b17023SJohn Marino on an indirect reference may alias. REF2 is the only one that can
572*e4b17023SJohn Marino be a decl in which case REF2_IS_DECL is true.
573*e4b17023SJohn Marino REF1_ALIAS_SET, BASE1_ALIAS_SET, REF2_ALIAS_SET and BASE2_ALIAS_SET
574*e4b17023SJohn Marino are the respective alias sets. */
575*e4b17023SJohn Marino
576*e4b17023SJohn Marino static bool
aliasing_component_refs_p(tree ref1,alias_set_type ref1_alias_set,alias_set_type base1_alias_set,HOST_WIDE_INT offset1,HOST_WIDE_INT max_size1,tree ref2,alias_set_type ref2_alias_set,alias_set_type base2_alias_set,HOST_WIDE_INT offset2,HOST_WIDE_INT max_size2,bool ref2_is_decl)577*e4b17023SJohn Marino aliasing_component_refs_p (tree ref1,
578*e4b17023SJohn Marino alias_set_type ref1_alias_set,
579*e4b17023SJohn Marino alias_set_type base1_alias_set,
580*e4b17023SJohn Marino HOST_WIDE_INT offset1, HOST_WIDE_INT max_size1,
581*e4b17023SJohn Marino tree ref2,
582*e4b17023SJohn Marino alias_set_type ref2_alias_set,
583*e4b17023SJohn Marino alias_set_type base2_alias_set,
584*e4b17023SJohn Marino HOST_WIDE_INT offset2, HOST_WIDE_INT max_size2,
585*e4b17023SJohn Marino bool ref2_is_decl)
586*e4b17023SJohn Marino {
587*e4b17023SJohn Marino /* If one reference is a component references through pointers try to find a
588*e4b17023SJohn Marino common base and apply offset based disambiguation. This handles
589*e4b17023SJohn Marino for example
590*e4b17023SJohn Marino struct A { int i; int j; } *q;
591*e4b17023SJohn Marino struct B { struct A a; int k; } *p;
592*e4b17023SJohn Marino disambiguating q->i and p->a.j. */
593*e4b17023SJohn Marino tree base1, base2;
594*e4b17023SJohn Marino tree type1, type2;
595*e4b17023SJohn Marino tree *refp;
596*e4b17023SJohn Marino int same_p;
597*e4b17023SJohn Marino
598*e4b17023SJohn Marino /* Choose bases and base types to search for. */
599*e4b17023SJohn Marino base1 = ref1;
600*e4b17023SJohn Marino while (handled_component_p (base1))
601*e4b17023SJohn Marino base1 = TREE_OPERAND (base1, 0);
602*e4b17023SJohn Marino type1 = TREE_TYPE (base1);
603*e4b17023SJohn Marino base2 = ref2;
604*e4b17023SJohn Marino while (handled_component_p (base2))
605*e4b17023SJohn Marino base2 = TREE_OPERAND (base2, 0);
606*e4b17023SJohn Marino type2 = TREE_TYPE (base2);
607*e4b17023SJohn Marino
608*e4b17023SJohn Marino /* Now search for the type1 in the access path of ref2. This
609*e4b17023SJohn Marino would be a common base for doing offset based disambiguation on. */
610*e4b17023SJohn Marino refp = &ref2;
611*e4b17023SJohn Marino while (handled_component_p (*refp)
612*e4b17023SJohn Marino && same_type_for_tbaa (TREE_TYPE (*refp), type1) == 0)
613*e4b17023SJohn Marino refp = &TREE_OPERAND (*refp, 0);
614*e4b17023SJohn Marino same_p = same_type_for_tbaa (TREE_TYPE (*refp), type1);
615*e4b17023SJohn Marino /* If we couldn't compare types we have to bail out. */
616*e4b17023SJohn Marino if (same_p == -1)
617*e4b17023SJohn Marino return true;
618*e4b17023SJohn Marino else if (same_p == 1)
619*e4b17023SJohn Marino {
620*e4b17023SJohn Marino HOST_WIDE_INT offadj, sztmp, msztmp;
621*e4b17023SJohn Marino get_ref_base_and_extent (*refp, &offadj, &sztmp, &msztmp);
622*e4b17023SJohn Marino offset2 -= offadj;
623*e4b17023SJohn Marino get_ref_base_and_extent (base1, &offadj, &sztmp, &msztmp);
624*e4b17023SJohn Marino offset1 -= offadj;
625*e4b17023SJohn Marino return ranges_overlap_p (offset1, max_size1, offset2, max_size2);
626*e4b17023SJohn Marino }
627*e4b17023SJohn Marino /* If we didn't find a common base, try the other way around. */
628*e4b17023SJohn Marino refp = &ref1;
629*e4b17023SJohn Marino while (handled_component_p (*refp)
630*e4b17023SJohn Marino && same_type_for_tbaa (TREE_TYPE (*refp), type2) == 0)
631*e4b17023SJohn Marino refp = &TREE_OPERAND (*refp, 0);
632*e4b17023SJohn Marino same_p = same_type_for_tbaa (TREE_TYPE (*refp), type2);
633*e4b17023SJohn Marino /* If we couldn't compare types we have to bail out. */
634*e4b17023SJohn Marino if (same_p == -1)
635*e4b17023SJohn Marino return true;
636*e4b17023SJohn Marino else if (same_p == 1)
637*e4b17023SJohn Marino {
638*e4b17023SJohn Marino HOST_WIDE_INT offadj, sztmp, msztmp;
639*e4b17023SJohn Marino get_ref_base_and_extent (*refp, &offadj, &sztmp, &msztmp);
640*e4b17023SJohn Marino offset1 -= offadj;
641*e4b17023SJohn Marino get_ref_base_and_extent (base2, &offadj, &sztmp, &msztmp);
642*e4b17023SJohn Marino offset2 -= offadj;
643*e4b17023SJohn Marino return ranges_overlap_p (offset1, max_size1, offset2, max_size2);
644*e4b17023SJohn Marino }
645*e4b17023SJohn Marino
646*e4b17023SJohn Marino /* If we have two type access paths B1.path1 and B2.path2 they may
647*e4b17023SJohn Marino only alias if either B1 is in B2.path2 or B2 is in B1.path1.
648*e4b17023SJohn Marino But we can still have a path that goes B1.path1...B2.path2 with
649*e4b17023SJohn Marino a part that we do not see. So we can only disambiguate now
650*e4b17023SJohn Marino if there is no B2 in the tail of path1 and no B1 on the
651*e4b17023SJohn Marino tail of path2. */
652*e4b17023SJohn Marino if (base1_alias_set == ref2_alias_set
653*e4b17023SJohn Marino || alias_set_subset_of (base1_alias_set, ref2_alias_set))
654*e4b17023SJohn Marino return true;
655*e4b17023SJohn Marino /* If this is ptr vs. decl then we know there is no ptr ... decl path. */
656*e4b17023SJohn Marino if (!ref2_is_decl)
657*e4b17023SJohn Marino return (base2_alias_set == ref1_alias_set
658*e4b17023SJohn Marino || alias_set_subset_of (base2_alias_set, ref1_alias_set));
659*e4b17023SJohn Marino return false;
660*e4b17023SJohn Marino }
661*e4b17023SJohn Marino
662*e4b17023SJohn Marino /* Return true if two memory references based on the variables BASE1
663*e4b17023SJohn Marino and BASE2 constrained to [OFFSET1, OFFSET1 + MAX_SIZE1) and
664*e4b17023SJohn Marino [OFFSET2, OFFSET2 + MAX_SIZE2) may alias. */
665*e4b17023SJohn Marino
666*e4b17023SJohn Marino static bool
decl_refs_may_alias_p(tree base1,HOST_WIDE_INT offset1,HOST_WIDE_INT max_size1,tree base2,HOST_WIDE_INT offset2,HOST_WIDE_INT max_size2)667*e4b17023SJohn Marino decl_refs_may_alias_p (tree base1,
668*e4b17023SJohn Marino HOST_WIDE_INT offset1, HOST_WIDE_INT max_size1,
669*e4b17023SJohn Marino tree base2,
670*e4b17023SJohn Marino HOST_WIDE_INT offset2, HOST_WIDE_INT max_size2)
671*e4b17023SJohn Marino {
672*e4b17023SJohn Marino gcc_checking_assert (DECL_P (base1) && DECL_P (base2));
673*e4b17023SJohn Marino
674*e4b17023SJohn Marino /* If both references are based on different variables, they cannot alias. */
675*e4b17023SJohn Marino if (base1 != base2)
676*e4b17023SJohn Marino return false;
677*e4b17023SJohn Marino
678*e4b17023SJohn Marino /* If both references are based on the same variable, they cannot alias if
679*e4b17023SJohn Marino the accesses do not overlap. */
680*e4b17023SJohn Marino return ranges_overlap_p (offset1, max_size1, offset2, max_size2);
681*e4b17023SJohn Marino }
682*e4b17023SJohn Marino
683*e4b17023SJohn Marino /* Return true if an indirect reference based on *PTR1 constrained
684*e4b17023SJohn Marino to [OFFSET1, OFFSET1 + MAX_SIZE1) may alias a variable based on BASE2
685*e4b17023SJohn Marino constrained to [OFFSET2, OFFSET2 + MAX_SIZE2). *PTR1 and BASE2 have
686*e4b17023SJohn Marino the alias sets BASE1_ALIAS_SET and BASE2_ALIAS_SET which can be -1
687*e4b17023SJohn Marino in which case they are computed on-demand. REF1 and REF2
688*e4b17023SJohn Marino if non-NULL are the complete memory reference trees. */
689*e4b17023SJohn Marino
690*e4b17023SJohn Marino static bool
indirect_ref_may_alias_decl_p(tree ref1 ATTRIBUTE_UNUSED,tree base1,HOST_WIDE_INT offset1,HOST_WIDE_INT max_size1 ATTRIBUTE_UNUSED,alias_set_type ref1_alias_set,alias_set_type base1_alias_set,tree ref2 ATTRIBUTE_UNUSED,tree base2,HOST_WIDE_INT offset2,HOST_WIDE_INT max_size2,alias_set_type ref2_alias_set,alias_set_type base2_alias_set,bool tbaa_p)691*e4b17023SJohn Marino indirect_ref_may_alias_decl_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
692*e4b17023SJohn Marino HOST_WIDE_INT offset1,
693*e4b17023SJohn Marino HOST_WIDE_INT max_size1 ATTRIBUTE_UNUSED,
694*e4b17023SJohn Marino alias_set_type ref1_alias_set,
695*e4b17023SJohn Marino alias_set_type base1_alias_set,
696*e4b17023SJohn Marino tree ref2 ATTRIBUTE_UNUSED, tree base2,
697*e4b17023SJohn Marino HOST_WIDE_INT offset2, HOST_WIDE_INT max_size2,
698*e4b17023SJohn Marino alias_set_type ref2_alias_set,
699*e4b17023SJohn Marino alias_set_type base2_alias_set, bool tbaa_p)
700*e4b17023SJohn Marino {
701*e4b17023SJohn Marino tree ptr1;
702*e4b17023SJohn Marino tree ptrtype1, dbase2;
703*e4b17023SJohn Marino HOST_WIDE_INT offset1p = offset1, offset2p = offset2;
704*e4b17023SJohn Marino HOST_WIDE_INT doffset1, doffset2;
705*e4b17023SJohn Marino double_int moff;
706*e4b17023SJohn Marino
707*e4b17023SJohn Marino gcc_checking_assert ((TREE_CODE (base1) == MEM_REF
708*e4b17023SJohn Marino || TREE_CODE (base1) == TARGET_MEM_REF)
709*e4b17023SJohn Marino && DECL_P (base2));
710*e4b17023SJohn Marino
711*e4b17023SJohn Marino ptr1 = TREE_OPERAND (base1, 0);
712*e4b17023SJohn Marino
713*e4b17023SJohn Marino /* The offset embedded in MEM_REFs can be negative. Bias them
714*e4b17023SJohn Marino so that the resulting offset adjustment is positive. */
715*e4b17023SJohn Marino moff = mem_ref_offset (base1);
716*e4b17023SJohn Marino moff = double_int_lshift (moff,
717*e4b17023SJohn Marino BITS_PER_UNIT == 8
718*e4b17023SJohn Marino ? 3 : exact_log2 (BITS_PER_UNIT),
719*e4b17023SJohn Marino HOST_BITS_PER_DOUBLE_INT, true);
720*e4b17023SJohn Marino if (double_int_negative_p (moff))
721*e4b17023SJohn Marino offset2p += double_int_neg (moff).low;
722*e4b17023SJohn Marino else
723*e4b17023SJohn Marino offset1p += moff.low;
724*e4b17023SJohn Marino
725*e4b17023SJohn Marino /* If only one reference is based on a variable, they cannot alias if
726*e4b17023SJohn Marino the pointer access is beyond the extent of the variable access.
727*e4b17023SJohn Marino (the pointer base cannot validly point to an offset less than zero
728*e4b17023SJohn Marino of the variable).
729*e4b17023SJohn Marino ??? IVOPTs creates bases that do not honor this restriction,
730*e4b17023SJohn Marino so do not apply this optimization for TARGET_MEM_REFs. */
731*e4b17023SJohn Marino if (TREE_CODE (base1) != TARGET_MEM_REF
732*e4b17023SJohn Marino && !ranges_overlap_p (MAX (0, offset1p), -1, offset2p, max_size2))
733*e4b17023SJohn Marino return false;
734*e4b17023SJohn Marino /* They also cannot alias if the pointer may not point to the decl. */
735*e4b17023SJohn Marino if (!ptr_deref_may_alias_decl_p (ptr1, base2))
736*e4b17023SJohn Marino return false;
737*e4b17023SJohn Marino
738*e4b17023SJohn Marino /* Disambiguations that rely on strict aliasing rules follow. */
739*e4b17023SJohn Marino if (!flag_strict_aliasing || !tbaa_p)
740*e4b17023SJohn Marino return true;
741*e4b17023SJohn Marino
742*e4b17023SJohn Marino ptrtype1 = TREE_TYPE (TREE_OPERAND (base1, 1));
743*e4b17023SJohn Marino
744*e4b17023SJohn Marino /* If the alias set for a pointer access is zero all bets are off. */
745*e4b17023SJohn Marino if (base1_alias_set == -1)
746*e4b17023SJohn Marino base1_alias_set = get_deref_alias_set (ptrtype1);
747*e4b17023SJohn Marino if (base1_alias_set == 0)
748*e4b17023SJohn Marino return true;
749*e4b17023SJohn Marino if (base2_alias_set == -1)
750*e4b17023SJohn Marino base2_alias_set = get_alias_set (base2);
751*e4b17023SJohn Marino
752*e4b17023SJohn Marino /* When we are trying to disambiguate an access with a pointer dereference
753*e4b17023SJohn Marino as base versus one with a decl as base we can use both the size
754*e4b17023SJohn Marino of the decl and its dynamic type for extra disambiguation.
755*e4b17023SJohn Marino ??? We do not know anything about the dynamic type of the decl
756*e4b17023SJohn Marino other than that its alias-set contains base2_alias_set as a subset
757*e4b17023SJohn Marino which does not help us here. */
758*e4b17023SJohn Marino /* As we know nothing useful about the dynamic type of the decl just
759*e4b17023SJohn Marino use the usual conflict check rather than a subset test.
760*e4b17023SJohn Marino ??? We could introduce -fvery-strict-aliasing when the language
761*e4b17023SJohn Marino does not allow decls to have a dynamic type that differs from their
762*e4b17023SJohn Marino static type. Then we can check
763*e4b17023SJohn Marino !alias_set_subset_of (base1_alias_set, base2_alias_set) instead. */
764*e4b17023SJohn Marino if (base1_alias_set != base2_alias_set
765*e4b17023SJohn Marino && !alias_sets_conflict_p (base1_alias_set, base2_alias_set))
766*e4b17023SJohn Marino return false;
767*e4b17023SJohn Marino /* If the size of the access relevant for TBAA through the pointer
768*e4b17023SJohn Marino is bigger than the size of the decl we can't possibly access the
769*e4b17023SJohn Marino decl via that pointer. */
770*e4b17023SJohn Marino if (DECL_SIZE (base2) && COMPLETE_TYPE_P (TREE_TYPE (ptrtype1))
771*e4b17023SJohn Marino && TREE_CODE (DECL_SIZE (base2)) == INTEGER_CST
772*e4b17023SJohn Marino && TREE_CODE (TYPE_SIZE (TREE_TYPE (ptrtype1))) == INTEGER_CST
773*e4b17023SJohn Marino /* ??? This in turn may run afoul when a decl of type T which is
774*e4b17023SJohn Marino a member of union type U is accessed through a pointer to
775*e4b17023SJohn Marino type U and sizeof T is smaller than sizeof U. */
776*e4b17023SJohn Marino && TREE_CODE (TREE_TYPE (ptrtype1)) != UNION_TYPE
777*e4b17023SJohn Marino && TREE_CODE (TREE_TYPE (ptrtype1)) != QUAL_UNION_TYPE
778*e4b17023SJohn Marino && tree_int_cst_lt (DECL_SIZE (base2), TYPE_SIZE (TREE_TYPE (ptrtype1))))
779*e4b17023SJohn Marino return false;
780*e4b17023SJohn Marino
781*e4b17023SJohn Marino if (!ref2)
782*e4b17023SJohn Marino return true;
783*e4b17023SJohn Marino
784*e4b17023SJohn Marino /* If the decl is accessed via a MEM_REF, reconstruct the base
785*e4b17023SJohn Marino we can use for TBAA and an appropriately adjusted offset. */
786*e4b17023SJohn Marino dbase2 = ref2;
787*e4b17023SJohn Marino while (handled_component_p (dbase2))
788*e4b17023SJohn Marino dbase2 = TREE_OPERAND (dbase2, 0);
789*e4b17023SJohn Marino doffset1 = offset1;
790*e4b17023SJohn Marino doffset2 = offset2;
791*e4b17023SJohn Marino if (TREE_CODE (dbase2) == MEM_REF
792*e4b17023SJohn Marino || TREE_CODE (dbase2) == TARGET_MEM_REF)
793*e4b17023SJohn Marino {
794*e4b17023SJohn Marino double_int moff = mem_ref_offset (dbase2);
795*e4b17023SJohn Marino moff = double_int_lshift (moff,
796*e4b17023SJohn Marino BITS_PER_UNIT == 8
797*e4b17023SJohn Marino ? 3 : exact_log2 (BITS_PER_UNIT),
798*e4b17023SJohn Marino HOST_BITS_PER_DOUBLE_INT, true);
799*e4b17023SJohn Marino if (double_int_negative_p (moff))
800*e4b17023SJohn Marino doffset1 -= double_int_neg (moff).low;
801*e4b17023SJohn Marino else
802*e4b17023SJohn Marino doffset2 -= moff.low;
803*e4b17023SJohn Marino }
804*e4b17023SJohn Marino
805*e4b17023SJohn Marino /* If either reference is view-converted, give up now. */
806*e4b17023SJohn Marino if (same_type_for_tbaa (TREE_TYPE (base1), TREE_TYPE (ptrtype1)) != 1
807*e4b17023SJohn Marino || same_type_for_tbaa (TREE_TYPE (dbase2), TREE_TYPE (base2)) != 1)
808*e4b17023SJohn Marino return true;
809*e4b17023SJohn Marino
810*e4b17023SJohn Marino /* If both references are through the same type, they do not alias
811*e4b17023SJohn Marino if the accesses do not overlap. This does extra disambiguation
812*e4b17023SJohn Marino for mixed/pointer accesses but requires strict aliasing.
813*e4b17023SJohn Marino For MEM_REFs we require that the component-ref offset we computed
814*e4b17023SJohn Marino is relative to the start of the type which we ensure by
815*e4b17023SJohn Marino comparing rvalue and access type and disregarding the constant
816*e4b17023SJohn Marino pointer offset. */
817*e4b17023SJohn Marino if ((TREE_CODE (base1) != TARGET_MEM_REF
818*e4b17023SJohn Marino || (!TMR_INDEX (base1) && !TMR_INDEX2 (base1)))
819*e4b17023SJohn Marino && same_type_for_tbaa (TREE_TYPE (base1), TREE_TYPE (dbase2)) == 1)
820*e4b17023SJohn Marino return ranges_overlap_p (doffset1, max_size1, doffset2, max_size2);
821*e4b17023SJohn Marino
822*e4b17023SJohn Marino /* Do access-path based disambiguation. */
823*e4b17023SJohn Marino if (ref1 && ref2
824*e4b17023SJohn Marino && (handled_component_p (ref1) || handled_component_p (ref2)))
825*e4b17023SJohn Marino return aliasing_component_refs_p (ref1,
826*e4b17023SJohn Marino ref1_alias_set, base1_alias_set,
827*e4b17023SJohn Marino offset1, max_size1,
828*e4b17023SJohn Marino ref2,
829*e4b17023SJohn Marino ref2_alias_set, base2_alias_set,
830*e4b17023SJohn Marino offset2, max_size2, true);
831*e4b17023SJohn Marino
832*e4b17023SJohn Marino return true;
833*e4b17023SJohn Marino }
834*e4b17023SJohn Marino
835*e4b17023SJohn Marino /* Return true if two indirect references based on *PTR1
836*e4b17023SJohn Marino and *PTR2 constrained to [OFFSET1, OFFSET1 + MAX_SIZE1) and
837*e4b17023SJohn Marino [OFFSET2, OFFSET2 + MAX_SIZE2) may alias. *PTR1 and *PTR2 have
838*e4b17023SJohn Marino the alias sets BASE1_ALIAS_SET and BASE2_ALIAS_SET which can be -1
839*e4b17023SJohn Marino in which case they are computed on-demand. REF1 and REF2
840*e4b17023SJohn Marino if non-NULL are the complete memory reference trees. */
841*e4b17023SJohn Marino
842*e4b17023SJohn Marino static bool
indirect_refs_may_alias_p(tree ref1 ATTRIBUTE_UNUSED,tree base1,HOST_WIDE_INT offset1,HOST_WIDE_INT max_size1,alias_set_type ref1_alias_set,alias_set_type base1_alias_set,tree ref2 ATTRIBUTE_UNUSED,tree base2,HOST_WIDE_INT offset2,HOST_WIDE_INT max_size2,alias_set_type ref2_alias_set,alias_set_type base2_alias_set,bool tbaa_p)843*e4b17023SJohn Marino indirect_refs_may_alias_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
844*e4b17023SJohn Marino HOST_WIDE_INT offset1, HOST_WIDE_INT max_size1,
845*e4b17023SJohn Marino alias_set_type ref1_alias_set,
846*e4b17023SJohn Marino alias_set_type base1_alias_set,
847*e4b17023SJohn Marino tree ref2 ATTRIBUTE_UNUSED, tree base2,
848*e4b17023SJohn Marino HOST_WIDE_INT offset2, HOST_WIDE_INT max_size2,
849*e4b17023SJohn Marino alias_set_type ref2_alias_set,
850*e4b17023SJohn Marino alias_set_type base2_alias_set, bool tbaa_p)
851*e4b17023SJohn Marino {
852*e4b17023SJohn Marino tree ptr1;
853*e4b17023SJohn Marino tree ptr2;
854*e4b17023SJohn Marino tree ptrtype1, ptrtype2;
855*e4b17023SJohn Marino
856*e4b17023SJohn Marino gcc_checking_assert ((TREE_CODE (base1) == MEM_REF
857*e4b17023SJohn Marino || TREE_CODE (base1) == TARGET_MEM_REF)
858*e4b17023SJohn Marino && (TREE_CODE (base2) == MEM_REF
859*e4b17023SJohn Marino || TREE_CODE (base2) == TARGET_MEM_REF));
860*e4b17023SJohn Marino
861*e4b17023SJohn Marino ptr1 = TREE_OPERAND (base1, 0);
862*e4b17023SJohn Marino ptr2 = TREE_OPERAND (base2, 0);
863*e4b17023SJohn Marino
864*e4b17023SJohn Marino /* If both bases are based on pointers they cannot alias if they may not
865*e4b17023SJohn Marino point to the same memory object or if they point to the same object
866*e4b17023SJohn Marino and the accesses do not overlap. */
867*e4b17023SJohn Marino if ((!cfun || gimple_in_ssa_p (cfun))
868*e4b17023SJohn Marino && operand_equal_p (ptr1, ptr2, 0)
869*e4b17023SJohn Marino && (((TREE_CODE (base1) != TARGET_MEM_REF
870*e4b17023SJohn Marino || (!TMR_INDEX (base1) && !TMR_INDEX2 (base1)))
871*e4b17023SJohn Marino && (TREE_CODE (base2) != TARGET_MEM_REF
872*e4b17023SJohn Marino || (!TMR_INDEX (base2) && !TMR_INDEX2 (base2))))
873*e4b17023SJohn Marino || (TREE_CODE (base1) == TARGET_MEM_REF
874*e4b17023SJohn Marino && TREE_CODE (base2) == TARGET_MEM_REF
875*e4b17023SJohn Marino && (TMR_STEP (base1) == TMR_STEP (base2)
876*e4b17023SJohn Marino || (TMR_STEP (base1) && TMR_STEP (base2)
877*e4b17023SJohn Marino && operand_equal_p (TMR_STEP (base1),
878*e4b17023SJohn Marino TMR_STEP (base2), 0)))
879*e4b17023SJohn Marino && (TMR_INDEX (base1) == TMR_INDEX (base2)
880*e4b17023SJohn Marino || (TMR_INDEX (base1) && TMR_INDEX (base2)
881*e4b17023SJohn Marino && operand_equal_p (TMR_INDEX (base1),
882*e4b17023SJohn Marino TMR_INDEX (base2), 0)))
883*e4b17023SJohn Marino && (TMR_INDEX2 (base1) == TMR_INDEX2 (base2)
884*e4b17023SJohn Marino || (TMR_INDEX2 (base1) && TMR_INDEX2 (base2)
885*e4b17023SJohn Marino && operand_equal_p (TMR_INDEX2 (base1),
886*e4b17023SJohn Marino TMR_INDEX2 (base2), 0))))))
887*e4b17023SJohn Marino {
888*e4b17023SJohn Marino double_int moff;
889*e4b17023SJohn Marino /* The offset embedded in MEM_REFs can be negative. Bias them
890*e4b17023SJohn Marino so that the resulting offset adjustment is positive. */
891*e4b17023SJohn Marino moff = mem_ref_offset (base1);
892*e4b17023SJohn Marino moff = double_int_lshift (moff,
893*e4b17023SJohn Marino BITS_PER_UNIT == 8
894*e4b17023SJohn Marino ? 3 : exact_log2 (BITS_PER_UNIT),
895*e4b17023SJohn Marino HOST_BITS_PER_DOUBLE_INT, true);
896*e4b17023SJohn Marino if (double_int_negative_p (moff))
897*e4b17023SJohn Marino offset2 += double_int_neg (moff).low;
898*e4b17023SJohn Marino else
899*e4b17023SJohn Marino offset1 += moff.low;
900*e4b17023SJohn Marino moff = mem_ref_offset (base2);
901*e4b17023SJohn Marino moff = double_int_lshift (moff,
902*e4b17023SJohn Marino BITS_PER_UNIT == 8
903*e4b17023SJohn Marino ? 3 : exact_log2 (BITS_PER_UNIT),
904*e4b17023SJohn Marino HOST_BITS_PER_DOUBLE_INT, true);
905*e4b17023SJohn Marino if (double_int_negative_p (moff))
906*e4b17023SJohn Marino offset1 += double_int_neg (moff).low;
907*e4b17023SJohn Marino else
908*e4b17023SJohn Marino offset2 += moff.low;
909*e4b17023SJohn Marino return ranges_overlap_p (offset1, max_size1, offset2, max_size2);
910*e4b17023SJohn Marino }
911*e4b17023SJohn Marino if (!ptr_derefs_may_alias_p (ptr1, ptr2))
912*e4b17023SJohn Marino return false;
913*e4b17023SJohn Marino
914*e4b17023SJohn Marino /* Disambiguations that rely on strict aliasing rules follow. */
915*e4b17023SJohn Marino if (!flag_strict_aliasing || !tbaa_p)
916*e4b17023SJohn Marino return true;
917*e4b17023SJohn Marino
918*e4b17023SJohn Marino ptrtype1 = TREE_TYPE (TREE_OPERAND (base1, 1));
919*e4b17023SJohn Marino ptrtype2 = TREE_TYPE (TREE_OPERAND (base2, 1));
920*e4b17023SJohn Marino
921*e4b17023SJohn Marino /* If the alias set for a pointer access is zero all bets are off. */
922*e4b17023SJohn Marino if (base1_alias_set == -1)
923*e4b17023SJohn Marino base1_alias_set = get_deref_alias_set (ptrtype1);
924*e4b17023SJohn Marino if (base1_alias_set == 0)
925*e4b17023SJohn Marino return true;
926*e4b17023SJohn Marino if (base2_alias_set == -1)
927*e4b17023SJohn Marino base2_alias_set = get_deref_alias_set (ptrtype2);
928*e4b17023SJohn Marino if (base2_alias_set == 0)
929*e4b17023SJohn Marino return true;
930*e4b17023SJohn Marino
931*e4b17023SJohn Marino /* If both references are through the same type, they do not alias
932*e4b17023SJohn Marino if the accesses do not overlap. This does extra disambiguation
933*e4b17023SJohn Marino for mixed/pointer accesses but requires strict aliasing. */
934*e4b17023SJohn Marino if ((TREE_CODE (base1) != TARGET_MEM_REF
935*e4b17023SJohn Marino || (!TMR_INDEX (base1) && !TMR_INDEX2 (base1)))
936*e4b17023SJohn Marino && (TREE_CODE (base2) != TARGET_MEM_REF
937*e4b17023SJohn Marino || (!TMR_INDEX (base2) && !TMR_INDEX2 (base2)))
938*e4b17023SJohn Marino && same_type_for_tbaa (TREE_TYPE (base1), TREE_TYPE (ptrtype1)) == 1
939*e4b17023SJohn Marino && same_type_for_tbaa (TREE_TYPE (base2), TREE_TYPE (ptrtype2)) == 1
940*e4b17023SJohn Marino && same_type_for_tbaa (TREE_TYPE (ptrtype1),
941*e4b17023SJohn Marino TREE_TYPE (ptrtype2)) == 1)
942*e4b17023SJohn Marino return ranges_overlap_p (offset1, max_size1, offset2, max_size2);
943*e4b17023SJohn Marino
944*e4b17023SJohn Marino /* Do type-based disambiguation. */
945*e4b17023SJohn Marino if (base1_alias_set != base2_alias_set
946*e4b17023SJohn Marino && !alias_sets_conflict_p (base1_alias_set, base2_alias_set))
947*e4b17023SJohn Marino return false;
948*e4b17023SJohn Marino
949*e4b17023SJohn Marino /* Do access-path based disambiguation. */
950*e4b17023SJohn Marino if (ref1 && ref2
951*e4b17023SJohn Marino && (handled_component_p (ref1) || handled_component_p (ref2))
952*e4b17023SJohn Marino && same_type_for_tbaa (TREE_TYPE (base1), TREE_TYPE (ptrtype1)) == 1
953*e4b17023SJohn Marino && same_type_for_tbaa (TREE_TYPE (base2), TREE_TYPE (ptrtype2)) == 1)
954*e4b17023SJohn Marino return aliasing_component_refs_p (ref1,
955*e4b17023SJohn Marino ref1_alias_set, base1_alias_set,
956*e4b17023SJohn Marino offset1, max_size1,
957*e4b17023SJohn Marino ref2,
958*e4b17023SJohn Marino ref2_alias_set, base2_alias_set,
959*e4b17023SJohn Marino offset2, max_size2, false);
960*e4b17023SJohn Marino
961*e4b17023SJohn Marino return true;
962*e4b17023SJohn Marino }
963*e4b17023SJohn Marino
964*e4b17023SJohn Marino /* Return true, if the two memory references REF1 and REF2 may alias. */
965*e4b17023SJohn Marino
966*e4b17023SJohn Marino bool
refs_may_alias_p_1(ao_ref * ref1,ao_ref * ref2,bool tbaa_p)967*e4b17023SJohn Marino refs_may_alias_p_1 (ao_ref *ref1, ao_ref *ref2, bool tbaa_p)
968*e4b17023SJohn Marino {
969*e4b17023SJohn Marino tree base1, base2;
970*e4b17023SJohn Marino HOST_WIDE_INT offset1 = 0, offset2 = 0;
971*e4b17023SJohn Marino HOST_WIDE_INT max_size1 = -1, max_size2 = -1;
972*e4b17023SJohn Marino bool var1_p, var2_p, ind1_p, ind2_p;
973*e4b17023SJohn Marino
974*e4b17023SJohn Marino gcc_checking_assert ((!ref1->ref
975*e4b17023SJohn Marino || TREE_CODE (ref1->ref) == SSA_NAME
976*e4b17023SJohn Marino || DECL_P (ref1->ref)
977*e4b17023SJohn Marino || TREE_CODE (ref1->ref) == STRING_CST
978*e4b17023SJohn Marino || handled_component_p (ref1->ref)
979*e4b17023SJohn Marino || TREE_CODE (ref1->ref) == MEM_REF
980*e4b17023SJohn Marino || TREE_CODE (ref1->ref) == TARGET_MEM_REF)
981*e4b17023SJohn Marino && (!ref2->ref
982*e4b17023SJohn Marino || TREE_CODE (ref2->ref) == SSA_NAME
983*e4b17023SJohn Marino || DECL_P (ref2->ref)
984*e4b17023SJohn Marino || TREE_CODE (ref2->ref) == STRING_CST
985*e4b17023SJohn Marino || handled_component_p (ref2->ref)
986*e4b17023SJohn Marino || TREE_CODE (ref2->ref) == MEM_REF
987*e4b17023SJohn Marino || TREE_CODE (ref2->ref) == TARGET_MEM_REF));
988*e4b17023SJohn Marino
989*e4b17023SJohn Marino /* Decompose the references into their base objects and the access. */
990*e4b17023SJohn Marino base1 = ao_ref_base (ref1);
991*e4b17023SJohn Marino offset1 = ref1->offset;
992*e4b17023SJohn Marino max_size1 = ref1->max_size;
993*e4b17023SJohn Marino base2 = ao_ref_base (ref2);
994*e4b17023SJohn Marino offset2 = ref2->offset;
995*e4b17023SJohn Marino max_size2 = ref2->max_size;
996*e4b17023SJohn Marino
997*e4b17023SJohn Marino /* We can end up with registers or constants as bases for example from
998*e4b17023SJohn Marino *D.1663_44 = VIEW_CONVERT_EXPR<struct DB_LSN>(__tmp$B0F64_59);
999*e4b17023SJohn Marino which is seen as a struct copy. */
1000*e4b17023SJohn Marino if (TREE_CODE (base1) == SSA_NAME
1001*e4b17023SJohn Marino || TREE_CODE (base1) == CONST_DECL
1002*e4b17023SJohn Marino || TREE_CODE (base1) == CONSTRUCTOR
1003*e4b17023SJohn Marino || TREE_CODE (base1) == ADDR_EXPR
1004*e4b17023SJohn Marino || CONSTANT_CLASS_P (base1)
1005*e4b17023SJohn Marino || TREE_CODE (base2) == SSA_NAME
1006*e4b17023SJohn Marino || TREE_CODE (base2) == CONST_DECL
1007*e4b17023SJohn Marino || TREE_CODE (base2) == CONSTRUCTOR
1008*e4b17023SJohn Marino || TREE_CODE (base2) == ADDR_EXPR
1009*e4b17023SJohn Marino || CONSTANT_CLASS_P (base2))
1010*e4b17023SJohn Marino return false;
1011*e4b17023SJohn Marino
1012*e4b17023SJohn Marino /* We can end up refering to code via function and label decls.
1013*e4b17023SJohn Marino As we likely do not properly track code aliases conservatively
1014*e4b17023SJohn Marino bail out. */
1015*e4b17023SJohn Marino if (TREE_CODE (base1) == FUNCTION_DECL
1016*e4b17023SJohn Marino || TREE_CODE (base1) == LABEL_DECL
1017*e4b17023SJohn Marino || TREE_CODE (base2) == FUNCTION_DECL
1018*e4b17023SJohn Marino || TREE_CODE (base2) == LABEL_DECL)
1019*e4b17023SJohn Marino return true;
1020*e4b17023SJohn Marino
1021*e4b17023SJohn Marino /* Two volatile accesses always conflict. */
1022*e4b17023SJohn Marino if (ref1->volatile_p
1023*e4b17023SJohn Marino && ref2->volatile_p)
1024*e4b17023SJohn Marino return true;
1025*e4b17023SJohn Marino
1026*e4b17023SJohn Marino /* Defer to simple offset based disambiguation if we have
1027*e4b17023SJohn Marino references based on two decls. Do this before defering to
1028*e4b17023SJohn Marino TBAA to handle must-alias cases in conformance with the
1029*e4b17023SJohn Marino GCC extension of allowing type-punning through unions. */
1030*e4b17023SJohn Marino var1_p = DECL_P (base1);
1031*e4b17023SJohn Marino var2_p = DECL_P (base2);
1032*e4b17023SJohn Marino if (var1_p && var2_p)
1033*e4b17023SJohn Marino return decl_refs_may_alias_p (base1, offset1, max_size1,
1034*e4b17023SJohn Marino base2, offset2, max_size2);
1035*e4b17023SJohn Marino
1036*e4b17023SJohn Marino ind1_p = (TREE_CODE (base1) == MEM_REF
1037*e4b17023SJohn Marino || TREE_CODE (base1) == TARGET_MEM_REF);
1038*e4b17023SJohn Marino ind2_p = (TREE_CODE (base2) == MEM_REF
1039*e4b17023SJohn Marino || TREE_CODE (base2) == TARGET_MEM_REF);
1040*e4b17023SJohn Marino
1041*e4b17023SJohn Marino /* Canonicalize the pointer-vs-decl case. */
1042*e4b17023SJohn Marino if (ind1_p && var2_p)
1043*e4b17023SJohn Marino {
1044*e4b17023SJohn Marino HOST_WIDE_INT tmp1;
1045*e4b17023SJohn Marino tree tmp2;
1046*e4b17023SJohn Marino ao_ref *tmp3;
1047*e4b17023SJohn Marino tmp1 = offset1; offset1 = offset2; offset2 = tmp1;
1048*e4b17023SJohn Marino tmp1 = max_size1; max_size1 = max_size2; max_size2 = tmp1;
1049*e4b17023SJohn Marino tmp2 = base1; base1 = base2; base2 = tmp2;
1050*e4b17023SJohn Marino tmp3 = ref1; ref1 = ref2; ref2 = tmp3;
1051*e4b17023SJohn Marino var1_p = true;
1052*e4b17023SJohn Marino ind1_p = false;
1053*e4b17023SJohn Marino var2_p = false;
1054*e4b17023SJohn Marino ind2_p = true;
1055*e4b17023SJohn Marino }
1056*e4b17023SJohn Marino
1057*e4b17023SJohn Marino /* First defer to TBAA if possible. */
1058*e4b17023SJohn Marino if (tbaa_p
1059*e4b17023SJohn Marino && flag_strict_aliasing
1060*e4b17023SJohn Marino && !alias_sets_conflict_p (ao_ref_alias_set (ref1),
1061*e4b17023SJohn Marino ao_ref_alias_set (ref2)))
1062*e4b17023SJohn Marino return false;
1063*e4b17023SJohn Marino
1064*e4b17023SJohn Marino /* Dispatch to the pointer-vs-decl or pointer-vs-pointer disambiguators. */
1065*e4b17023SJohn Marino if (var1_p && ind2_p)
1066*e4b17023SJohn Marino return indirect_ref_may_alias_decl_p (ref2->ref, base2,
1067*e4b17023SJohn Marino offset2, max_size2,
1068*e4b17023SJohn Marino ao_ref_alias_set (ref2), -1,
1069*e4b17023SJohn Marino ref1->ref, base1,
1070*e4b17023SJohn Marino offset1, max_size1,
1071*e4b17023SJohn Marino ao_ref_alias_set (ref1),
1072*e4b17023SJohn Marino ao_ref_base_alias_set (ref1),
1073*e4b17023SJohn Marino tbaa_p);
1074*e4b17023SJohn Marino else if (ind1_p && ind2_p)
1075*e4b17023SJohn Marino return indirect_refs_may_alias_p (ref1->ref, base1,
1076*e4b17023SJohn Marino offset1, max_size1,
1077*e4b17023SJohn Marino ao_ref_alias_set (ref1), -1,
1078*e4b17023SJohn Marino ref2->ref, base2,
1079*e4b17023SJohn Marino offset2, max_size2,
1080*e4b17023SJohn Marino ao_ref_alias_set (ref2), -1,
1081*e4b17023SJohn Marino tbaa_p);
1082*e4b17023SJohn Marino
1083*e4b17023SJohn Marino /* We really do not want to end up here, but returning true is safe. */
1084*e4b17023SJohn Marino #ifdef ENABLE_CHECKING
1085*e4b17023SJohn Marino gcc_unreachable ();
1086*e4b17023SJohn Marino #else
1087*e4b17023SJohn Marino return true;
1088*e4b17023SJohn Marino #endif
1089*e4b17023SJohn Marino }
1090*e4b17023SJohn Marino
1091*e4b17023SJohn Marino bool
refs_may_alias_p(tree ref1,tree ref2)1092*e4b17023SJohn Marino refs_may_alias_p (tree ref1, tree ref2)
1093*e4b17023SJohn Marino {
1094*e4b17023SJohn Marino ao_ref r1, r2;
1095*e4b17023SJohn Marino bool res;
1096*e4b17023SJohn Marino ao_ref_init (&r1, ref1);
1097*e4b17023SJohn Marino ao_ref_init (&r2, ref2);
1098*e4b17023SJohn Marino res = refs_may_alias_p_1 (&r1, &r2, true);
1099*e4b17023SJohn Marino if (res)
1100*e4b17023SJohn Marino ++alias_stats.refs_may_alias_p_may_alias;
1101*e4b17023SJohn Marino else
1102*e4b17023SJohn Marino ++alias_stats.refs_may_alias_p_no_alias;
1103*e4b17023SJohn Marino return res;
1104*e4b17023SJohn Marino }
1105*e4b17023SJohn Marino
1106*e4b17023SJohn Marino /* Returns true if there is a anti-dependence for the STORE that
1107*e4b17023SJohn Marino executes after the LOAD. */
1108*e4b17023SJohn Marino
1109*e4b17023SJohn Marino bool
refs_anti_dependent_p(tree load,tree store)1110*e4b17023SJohn Marino refs_anti_dependent_p (tree load, tree store)
1111*e4b17023SJohn Marino {
1112*e4b17023SJohn Marino ao_ref r1, r2;
1113*e4b17023SJohn Marino ao_ref_init (&r1, load);
1114*e4b17023SJohn Marino ao_ref_init (&r2, store);
1115*e4b17023SJohn Marino return refs_may_alias_p_1 (&r1, &r2, false);
1116*e4b17023SJohn Marino }
1117*e4b17023SJohn Marino
1118*e4b17023SJohn Marino /* Returns true if there is a output dependence for the stores
1119*e4b17023SJohn Marino STORE1 and STORE2. */
1120*e4b17023SJohn Marino
1121*e4b17023SJohn Marino bool
refs_output_dependent_p(tree store1,tree store2)1122*e4b17023SJohn Marino refs_output_dependent_p (tree store1, tree store2)
1123*e4b17023SJohn Marino {
1124*e4b17023SJohn Marino ao_ref r1, r2;
1125*e4b17023SJohn Marino ao_ref_init (&r1, store1);
1126*e4b17023SJohn Marino ao_ref_init (&r2, store2);
1127*e4b17023SJohn Marino return refs_may_alias_p_1 (&r1, &r2, false);
1128*e4b17023SJohn Marino }
1129*e4b17023SJohn Marino
1130*e4b17023SJohn Marino /* If the call CALL may use the memory reference REF return true,
1131*e4b17023SJohn Marino otherwise return false. */
1132*e4b17023SJohn Marino
1133*e4b17023SJohn Marino static bool
ref_maybe_used_by_call_p_1(gimple call,ao_ref * ref)1134*e4b17023SJohn Marino ref_maybe_used_by_call_p_1 (gimple call, ao_ref *ref)
1135*e4b17023SJohn Marino {
1136*e4b17023SJohn Marino tree base, callee;
1137*e4b17023SJohn Marino unsigned i;
1138*e4b17023SJohn Marino int flags = gimple_call_flags (call);
1139*e4b17023SJohn Marino
1140*e4b17023SJohn Marino /* Const functions without a static chain do not implicitly use memory. */
1141*e4b17023SJohn Marino if (!gimple_call_chain (call)
1142*e4b17023SJohn Marino && (flags & (ECF_CONST|ECF_NOVOPS)))
1143*e4b17023SJohn Marino goto process_args;
1144*e4b17023SJohn Marino
1145*e4b17023SJohn Marino base = ao_ref_base (ref);
1146*e4b17023SJohn Marino if (!base)
1147*e4b17023SJohn Marino return true;
1148*e4b17023SJohn Marino
1149*e4b17023SJohn Marino /* A call that is not without side-effects might involve volatile
1150*e4b17023SJohn Marino accesses and thus conflicts with all other volatile accesses. */
1151*e4b17023SJohn Marino if (ref->volatile_p)
1152*e4b17023SJohn Marino return true;
1153*e4b17023SJohn Marino
1154*e4b17023SJohn Marino /* If the reference is based on a decl that is not aliased the call
1155*e4b17023SJohn Marino cannot possibly use it. */
1156*e4b17023SJohn Marino if (DECL_P (base)
1157*e4b17023SJohn Marino && !may_be_aliased (base)
1158*e4b17023SJohn Marino /* But local statics can be used through recursion. */
1159*e4b17023SJohn Marino && !is_global_var (base))
1160*e4b17023SJohn Marino goto process_args;
1161*e4b17023SJohn Marino
1162*e4b17023SJohn Marino callee = gimple_call_fndecl (call);
1163*e4b17023SJohn Marino
1164*e4b17023SJohn Marino /* Handle those builtin functions explicitly that do not act as
1165*e4b17023SJohn Marino escape points. See tree-ssa-structalias.c:find_func_aliases
1166*e4b17023SJohn Marino for the list of builtins we might need to handle here. */
1167*e4b17023SJohn Marino if (callee != NULL_TREE
1168*e4b17023SJohn Marino && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL)
1169*e4b17023SJohn Marino switch (DECL_FUNCTION_CODE (callee))
1170*e4b17023SJohn Marino {
1171*e4b17023SJohn Marino /* All the following functions read memory pointed to by
1172*e4b17023SJohn Marino their second argument. strcat/strncat additionally
1173*e4b17023SJohn Marino reads memory pointed to by the first argument. */
1174*e4b17023SJohn Marino case BUILT_IN_STRCAT:
1175*e4b17023SJohn Marino case BUILT_IN_STRNCAT:
1176*e4b17023SJohn Marino {
1177*e4b17023SJohn Marino ao_ref dref;
1178*e4b17023SJohn Marino ao_ref_init_from_ptr_and_size (&dref,
1179*e4b17023SJohn Marino gimple_call_arg (call, 0),
1180*e4b17023SJohn Marino NULL_TREE);
1181*e4b17023SJohn Marino if (refs_may_alias_p_1 (&dref, ref, false))
1182*e4b17023SJohn Marino return true;
1183*e4b17023SJohn Marino }
1184*e4b17023SJohn Marino /* FALLTHRU */
1185*e4b17023SJohn Marino case BUILT_IN_STRCPY:
1186*e4b17023SJohn Marino case BUILT_IN_STRNCPY:
1187*e4b17023SJohn Marino case BUILT_IN_MEMCPY:
1188*e4b17023SJohn Marino case BUILT_IN_MEMMOVE:
1189*e4b17023SJohn Marino case BUILT_IN_MEMPCPY:
1190*e4b17023SJohn Marino case BUILT_IN_STPCPY:
1191*e4b17023SJohn Marino case BUILT_IN_STPNCPY:
1192*e4b17023SJohn Marino case BUILT_IN_TM_MEMCPY:
1193*e4b17023SJohn Marino case BUILT_IN_TM_MEMMOVE:
1194*e4b17023SJohn Marino {
1195*e4b17023SJohn Marino ao_ref dref;
1196*e4b17023SJohn Marino tree size = NULL_TREE;
1197*e4b17023SJohn Marino if (gimple_call_num_args (call) == 3)
1198*e4b17023SJohn Marino size = gimple_call_arg (call, 2);
1199*e4b17023SJohn Marino ao_ref_init_from_ptr_and_size (&dref,
1200*e4b17023SJohn Marino gimple_call_arg (call, 1),
1201*e4b17023SJohn Marino size);
1202*e4b17023SJohn Marino return refs_may_alias_p_1 (&dref, ref, false);
1203*e4b17023SJohn Marino }
1204*e4b17023SJohn Marino case BUILT_IN_STRCAT_CHK:
1205*e4b17023SJohn Marino case BUILT_IN_STRNCAT_CHK:
1206*e4b17023SJohn Marino {
1207*e4b17023SJohn Marino ao_ref dref;
1208*e4b17023SJohn Marino ao_ref_init_from_ptr_and_size (&dref,
1209*e4b17023SJohn Marino gimple_call_arg (call, 0),
1210*e4b17023SJohn Marino NULL_TREE);
1211*e4b17023SJohn Marino if (refs_may_alias_p_1 (&dref, ref, false))
1212*e4b17023SJohn Marino return true;
1213*e4b17023SJohn Marino }
1214*e4b17023SJohn Marino /* FALLTHRU */
1215*e4b17023SJohn Marino case BUILT_IN_STRCPY_CHK:
1216*e4b17023SJohn Marino case BUILT_IN_STRNCPY_CHK:
1217*e4b17023SJohn Marino case BUILT_IN_MEMCPY_CHK:
1218*e4b17023SJohn Marino case BUILT_IN_MEMMOVE_CHK:
1219*e4b17023SJohn Marino case BUILT_IN_MEMPCPY_CHK:
1220*e4b17023SJohn Marino case BUILT_IN_STPCPY_CHK:
1221*e4b17023SJohn Marino case BUILT_IN_STPNCPY_CHK:
1222*e4b17023SJohn Marino {
1223*e4b17023SJohn Marino ao_ref dref;
1224*e4b17023SJohn Marino tree size = NULL_TREE;
1225*e4b17023SJohn Marino if (gimple_call_num_args (call) == 4)
1226*e4b17023SJohn Marino size = gimple_call_arg (call, 2);
1227*e4b17023SJohn Marino ao_ref_init_from_ptr_and_size (&dref,
1228*e4b17023SJohn Marino gimple_call_arg (call, 1),
1229*e4b17023SJohn Marino size);
1230*e4b17023SJohn Marino return refs_may_alias_p_1 (&dref, ref, false);
1231*e4b17023SJohn Marino }
1232*e4b17023SJohn Marino case BUILT_IN_BCOPY:
1233*e4b17023SJohn Marino {
1234*e4b17023SJohn Marino ao_ref dref;
1235*e4b17023SJohn Marino tree size = gimple_call_arg (call, 2);
1236*e4b17023SJohn Marino ao_ref_init_from_ptr_and_size (&dref,
1237*e4b17023SJohn Marino gimple_call_arg (call, 0),
1238*e4b17023SJohn Marino size);
1239*e4b17023SJohn Marino return refs_may_alias_p_1 (&dref, ref, false);
1240*e4b17023SJohn Marino }
1241*e4b17023SJohn Marino
1242*e4b17023SJohn Marino /* The following functions read memory pointed to by their
1243*e4b17023SJohn Marino first argument. */
1244*e4b17023SJohn Marino CASE_BUILT_IN_TM_LOAD (1):
1245*e4b17023SJohn Marino CASE_BUILT_IN_TM_LOAD (2):
1246*e4b17023SJohn Marino CASE_BUILT_IN_TM_LOAD (4):
1247*e4b17023SJohn Marino CASE_BUILT_IN_TM_LOAD (8):
1248*e4b17023SJohn Marino CASE_BUILT_IN_TM_LOAD (FLOAT):
1249*e4b17023SJohn Marino CASE_BUILT_IN_TM_LOAD (DOUBLE):
1250*e4b17023SJohn Marino CASE_BUILT_IN_TM_LOAD (LDOUBLE):
1251*e4b17023SJohn Marino CASE_BUILT_IN_TM_LOAD (M64):
1252*e4b17023SJohn Marino CASE_BUILT_IN_TM_LOAD (M128):
1253*e4b17023SJohn Marino CASE_BUILT_IN_TM_LOAD (M256):
1254*e4b17023SJohn Marino case BUILT_IN_TM_LOG:
1255*e4b17023SJohn Marino case BUILT_IN_TM_LOG_1:
1256*e4b17023SJohn Marino case BUILT_IN_TM_LOG_2:
1257*e4b17023SJohn Marino case BUILT_IN_TM_LOG_4:
1258*e4b17023SJohn Marino case BUILT_IN_TM_LOG_8:
1259*e4b17023SJohn Marino case BUILT_IN_TM_LOG_FLOAT:
1260*e4b17023SJohn Marino case BUILT_IN_TM_LOG_DOUBLE:
1261*e4b17023SJohn Marino case BUILT_IN_TM_LOG_LDOUBLE:
1262*e4b17023SJohn Marino case BUILT_IN_TM_LOG_M64:
1263*e4b17023SJohn Marino case BUILT_IN_TM_LOG_M128:
1264*e4b17023SJohn Marino case BUILT_IN_TM_LOG_M256:
1265*e4b17023SJohn Marino return ptr_deref_may_alias_ref_p_1 (gimple_call_arg (call, 0), ref);
1266*e4b17023SJohn Marino
1267*e4b17023SJohn Marino /* These read memory pointed to by the first argument. */
1268*e4b17023SJohn Marino case BUILT_IN_STRDUP:
1269*e4b17023SJohn Marino case BUILT_IN_STRNDUP:
1270*e4b17023SJohn Marino {
1271*e4b17023SJohn Marino ao_ref dref;
1272*e4b17023SJohn Marino tree size = NULL_TREE;
1273*e4b17023SJohn Marino if (gimple_call_num_args (call) == 2)
1274*e4b17023SJohn Marino size = gimple_call_arg (call, 1);
1275*e4b17023SJohn Marino ao_ref_init_from_ptr_and_size (&dref,
1276*e4b17023SJohn Marino gimple_call_arg (call, 0),
1277*e4b17023SJohn Marino size);
1278*e4b17023SJohn Marino return refs_may_alias_p_1 (&dref, ref, false);
1279*e4b17023SJohn Marino }
1280*e4b17023SJohn Marino /* The following builtins do not read from memory. */
1281*e4b17023SJohn Marino case BUILT_IN_FREE:
1282*e4b17023SJohn Marino case BUILT_IN_MALLOC:
1283*e4b17023SJohn Marino case BUILT_IN_CALLOC:
1284*e4b17023SJohn Marino case BUILT_IN_ALLOCA:
1285*e4b17023SJohn Marino case BUILT_IN_ALLOCA_WITH_ALIGN:
1286*e4b17023SJohn Marino case BUILT_IN_STACK_SAVE:
1287*e4b17023SJohn Marino case BUILT_IN_STACK_RESTORE:
1288*e4b17023SJohn Marino case BUILT_IN_MEMSET:
1289*e4b17023SJohn Marino case BUILT_IN_TM_MEMSET:
1290*e4b17023SJohn Marino case BUILT_IN_MEMSET_CHK:
1291*e4b17023SJohn Marino case BUILT_IN_FREXP:
1292*e4b17023SJohn Marino case BUILT_IN_FREXPF:
1293*e4b17023SJohn Marino case BUILT_IN_FREXPL:
1294*e4b17023SJohn Marino case BUILT_IN_GAMMA_R:
1295*e4b17023SJohn Marino case BUILT_IN_GAMMAF_R:
1296*e4b17023SJohn Marino case BUILT_IN_GAMMAL_R:
1297*e4b17023SJohn Marino case BUILT_IN_LGAMMA_R:
1298*e4b17023SJohn Marino case BUILT_IN_LGAMMAF_R:
1299*e4b17023SJohn Marino case BUILT_IN_LGAMMAL_R:
1300*e4b17023SJohn Marino case BUILT_IN_MODF:
1301*e4b17023SJohn Marino case BUILT_IN_MODFF:
1302*e4b17023SJohn Marino case BUILT_IN_MODFL:
1303*e4b17023SJohn Marino case BUILT_IN_REMQUO:
1304*e4b17023SJohn Marino case BUILT_IN_REMQUOF:
1305*e4b17023SJohn Marino case BUILT_IN_REMQUOL:
1306*e4b17023SJohn Marino case BUILT_IN_SINCOS:
1307*e4b17023SJohn Marino case BUILT_IN_SINCOSF:
1308*e4b17023SJohn Marino case BUILT_IN_SINCOSL:
1309*e4b17023SJohn Marino case BUILT_IN_ASSUME_ALIGNED:
1310*e4b17023SJohn Marino case BUILT_IN_VA_END:
1311*e4b17023SJohn Marino return false;
1312*e4b17023SJohn Marino /* __sync_* builtins and some OpenMP builtins act as threading
1313*e4b17023SJohn Marino barriers. */
1314*e4b17023SJohn Marino #undef DEF_SYNC_BUILTIN
1315*e4b17023SJohn Marino #define DEF_SYNC_BUILTIN(ENUM, NAME, TYPE, ATTRS) case ENUM:
1316*e4b17023SJohn Marino #include "sync-builtins.def"
1317*e4b17023SJohn Marino #undef DEF_SYNC_BUILTIN
1318*e4b17023SJohn Marino case BUILT_IN_GOMP_ATOMIC_START:
1319*e4b17023SJohn Marino case BUILT_IN_GOMP_ATOMIC_END:
1320*e4b17023SJohn Marino case BUILT_IN_GOMP_BARRIER:
1321*e4b17023SJohn Marino case BUILT_IN_GOMP_TASKWAIT:
1322*e4b17023SJohn Marino case BUILT_IN_GOMP_CRITICAL_START:
1323*e4b17023SJohn Marino case BUILT_IN_GOMP_CRITICAL_END:
1324*e4b17023SJohn Marino case BUILT_IN_GOMP_CRITICAL_NAME_START:
1325*e4b17023SJohn Marino case BUILT_IN_GOMP_CRITICAL_NAME_END:
1326*e4b17023SJohn Marino case BUILT_IN_GOMP_LOOP_END:
1327*e4b17023SJohn Marino case BUILT_IN_GOMP_ORDERED_START:
1328*e4b17023SJohn Marino case BUILT_IN_GOMP_ORDERED_END:
1329*e4b17023SJohn Marino case BUILT_IN_GOMP_PARALLEL_END:
1330*e4b17023SJohn Marino case BUILT_IN_GOMP_SECTIONS_END:
1331*e4b17023SJohn Marino case BUILT_IN_GOMP_SINGLE_COPY_START:
1332*e4b17023SJohn Marino case BUILT_IN_GOMP_SINGLE_COPY_END:
1333*e4b17023SJohn Marino return true;
1334*e4b17023SJohn Marino
1335*e4b17023SJohn Marino default:
1336*e4b17023SJohn Marino /* Fallthru to general call handling. */;
1337*e4b17023SJohn Marino }
1338*e4b17023SJohn Marino
1339*e4b17023SJohn Marino /* Check if base is a global static variable that is not read
1340*e4b17023SJohn Marino by the function. */
1341*e4b17023SJohn Marino if (callee != NULL_TREE
1342*e4b17023SJohn Marino && TREE_CODE (base) == VAR_DECL
1343*e4b17023SJohn Marino && TREE_STATIC (base))
1344*e4b17023SJohn Marino {
1345*e4b17023SJohn Marino struct cgraph_node *node = cgraph_get_node (callee);
1346*e4b17023SJohn Marino bitmap not_read;
1347*e4b17023SJohn Marino
1348*e4b17023SJohn Marino /* FIXME: Callee can be an OMP builtin that does not have a call graph
1349*e4b17023SJohn Marino node yet. We should enforce that there are nodes for all decls in the
1350*e4b17023SJohn Marino IL and remove this check instead. */
1351*e4b17023SJohn Marino if (node
1352*e4b17023SJohn Marino && (not_read = ipa_reference_get_not_read_global (node))
1353*e4b17023SJohn Marino && bitmap_bit_p (not_read, DECL_UID (base)))
1354*e4b17023SJohn Marino goto process_args;
1355*e4b17023SJohn Marino }
1356*e4b17023SJohn Marino
1357*e4b17023SJohn Marino /* Check if the base variable is call-used. */
1358*e4b17023SJohn Marino if (DECL_P (base))
1359*e4b17023SJohn Marino {
1360*e4b17023SJohn Marino if (pt_solution_includes (gimple_call_use_set (call), base))
1361*e4b17023SJohn Marino return true;
1362*e4b17023SJohn Marino }
1363*e4b17023SJohn Marino else if ((TREE_CODE (base) == MEM_REF
1364*e4b17023SJohn Marino || TREE_CODE (base) == TARGET_MEM_REF)
1365*e4b17023SJohn Marino && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
1366*e4b17023SJohn Marino {
1367*e4b17023SJohn Marino struct ptr_info_def *pi = SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0));
1368*e4b17023SJohn Marino if (!pi)
1369*e4b17023SJohn Marino return true;
1370*e4b17023SJohn Marino
1371*e4b17023SJohn Marino if (pt_solutions_intersect (gimple_call_use_set (call), &pi->pt))
1372*e4b17023SJohn Marino return true;
1373*e4b17023SJohn Marino }
1374*e4b17023SJohn Marino else
1375*e4b17023SJohn Marino return true;
1376*e4b17023SJohn Marino
1377*e4b17023SJohn Marino /* Inspect call arguments for passed-by-value aliases. */
1378*e4b17023SJohn Marino process_args:
1379*e4b17023SJohn Marino for (i = 0; i < gimple_call_num_args (call); ++i)
1380*e4b17023SJohn Marino {
1381*e4b17023SJohn Marino tree op = gimple_call_arg (call, i);
1382*e4b17023SJohn Marino int flags = gimple_call_arg_flags (call, i);
1383*e4b17023SJohn Marino
1384*e4b17023SJohn Marino if (flags & EAF_UNUSED)
1385*e4b17023SJohn Marino continue;
1386*e4b17023SJohn Marino
1387*e4b17023SJohn Marino if (TREE_CODE (op) == WITH_SIZE_EXPR)
1388*e4b17023SJohn Marino op = TREE_OPERAND (op, 0);
1389*e4b17023SJohn Marino
1390*e4b17023SJohn Marino if (TREE_CODE (op) != SSA_NAME
1391*e4b17023SJohn Marino && !is_gimple_min_invariant (op))
1392*e4b17023SJohn Marino {
1393*e4b17023SJohn Marino ao_ref r;
1394*e4b17023SJohn Marino ao_ref_init (&r, op);
1395*e4b17023SJohn Marino if (refs_may_alias_p_1 (&r, ref, true))
1396*e4b17023SJohn Marino return true;
1397*e4b17023SJohn Marino }
1398*e4b17023SJohn Marino }
1399*e4b17023SJohn Marino
1400*e4b17023SJohn Marino return false;
1401*e4b17023SJohn Marino }
1402*e4b17023SJohn Marino
1403*e4b17023SJohn Marino static bool
ref_maybe_used_by_call_p(gimple call,tree ref)1404*e4b17023SJohn Marino ref_maybe_used_by_call_p (gimple call, tree ref)
1405*e4b17023SJohn Marino {
1406*e4b17023SJohn Marino ao_ref r;
1407*e4b17023SJohn Marino bool res;
1408*e4b17023SJohn Marino ao_ref_init (&r, ref);
1409*e4b17023SJohn Marino res = ref_maybe_used_by_call_p_1 (call, &r);
1410*e4b17023SJohn Marino if (res)
1411*e4b17023SJohn Marino ++alias_stats.ref_maybe_used_by_call_p_may_alias;
1412*e4b17023SJohn Marino else
1413*e4b17023SJohn Marino ++alias_stats.ref_maybe_used_by_call_p_no_alias;
1414*e4b17023SJohn Marino return res;
1415*e4b17023SJohn Marino }
1416*e4b17023SJohn Marino
1417*e4b17023SJohn Marino
1418*e4b17023SJohn Marino /* If the statement STMT may use the memory reference REF return
1419*e4b17023SJohn Marino true, otherwise return false. */
1420*e4b17023SJohn Marino
1421*e4b17023SJohn Marino bool
ref_maybe_used_by_stmt_p(gimple stmt,tree ref)1422*e4b17023SJohn Marino ref_maybe_used_by_stmt_p (gimple stmt, tree ref)
1423*e4b17023SJohn Marino {
1424*e4b17023SJohn Marino if (is_gimple_assign (stmt))
1425*e4b17023SJohn Marino {
1426*e4b17023SJohn Marino tree rhs;
1427*e4b17023SJohn Marino
1428*e4b17023SJohn Marino /* All memory assign statements are single. */
1429*e4b17023SJohn Marino if (!gimple_assign_single_p (stmt))
1430*e4b17023SJohn Marino return false;
1431*e4b17023SJohn Marino
1432*e4b17023SJohn Marino rhs = gimple_assign_rhs1 (stmt);
1433*e4b17023SJohn Marino if (is_gimple_reg (rhs)
1434*e4b17023SJohn Marino || is_gimple_min_invariant (rhs)
1435*e4b17023SJohn Marino || gimple_assign_rhs_code (stmt) == CONSTRUCTOR)
1436*e4b17023SJohn Marino return false;
1437*e4b17023SJohn Marino
1438*e4b17023SJohn Marino return refs_may_alias_p (rhs, ref);
1439*e4b17023SJohn Marino }
1440*e4b17023SJohn Marino else if (is_gimple_call (stmt))
1441*e4b17023SJohn Marino return ref_maybe_used_by_call_p (stmt, ref);
1442*e4b17023SJohn Marino else if (gimple_code (stmt) == GIMPLE_RETURN)
1443*e4b17023SJohn Marino {
1444*e4b17023SJohn Marino tree retval = gimple_return_retval (stmt);
1445*e4b17023SJohn Marino tree base;
1446*e4b17023SJohn Marino if (retval
1447*e4b17023SJohn Marino && TREE_CODE (retval) != SSA_NAME
1448*e4b17023SJohn Marino && !is_gimple_min_invariant (retval)
1449*e4b17023SJohn Marino && refs_may_alias_p (retval, ref))
1450*e4b17023SJohn Marino return true;
1451*e4b17023SJohn Marino /* If ref escapes the function then the return acts as a use. */
1452*e4b17023SJohn Marino base = get_base_address (ref);
1453*e4b17023SJohn Marino if (!base)
1454*e4b17023SJohn Marino ;
1455*e4b17023SJohn Marino else if (DECL_P (base))
1456*e4b17023SJohn Marino return is_global_var (base);
1457*e4b17023SJohn Marino else if (TREE_CODE (base) == MEM_REF
1458*e4b17023SJohn Marino || TREE_CODE (base) == TARGET_MEM_REF)
1459*e4b17023SJohn Marino return ptr_deref_may_alias_global_p (TREE_OPERAND (base, 0));
1460*e4b17023SJohn Marino return false;
1461*e4b17023SJohn Marino }
1462*e4b17023SJohn Marino
1463*e4b17023SJohn Marino return true;
1464*e4b17023SJohn Marino }
1465*e4b17023SJohn Marino
1466*e4b17023SJohn Marino /* If the call in statement CALL may clobber the memory reference REF
1467*e4b17023SJohn Marino return true, otherwise return false. */
1468*e4b17023SJohn Marino
1469*e4b17023SJohn Marino static bool
call_may_clobber_ref_p_1(gimple call,ao_ref * ref)1470*e4b17023SJohn Marino call_may_clobber_ref_p_1 (gimple call, ao_ref *ref)
1471*e4b17023SJohn Marino {
1472*e4b17023SJohn Marino tree base;
1473*e4b17023SJohn Marino tree callee;
1474*e4b17023SJohn Marino
1475*e4b17023SJohn Marino /* If the call is pure or const it cannot clobber anything. */
1476*e4b17023SJohn Marino if (gimple_call_flags (call)
1477*e4b17023SJohn Marino & (ECF_PURE|ECF_CONST|ECF_LOOPING_CONST_OR_PURE|ECF_NOVOPS))
1478*e4b17023SJohn Marino return false;
1479*e4b17023SJohn Marino
1480*e4b17023SJohn Marino base = ao_ref_base (ref);
1481*e4b17023SJohn Marino if (!base)
1482*e4b17023SJohn Marino return true;
1483*e4b17023SJohn Marino
1484*e4b17023SJohn Marino if (TREE_CODE (base) == SSA_NAME
1485*e4b17023SJohn Marino || CONSTANT_CLASS_P (base))
1486*e4b17023SJohn Marino return false;
1487*e4b17023SJohn Marino
1488*e4b17023SJohn Marino /* A call that is not without side-effects might involve volatile
1489*e4b17023SJohn Marino accesses and thus conflicts with all other volatile accesses. */
1490*e4b17023SJohn Marino if (ref->volatile_p)
1491*e4b17023SJohn Marino return true;
1492*e4b17023SJohn Marino
1493*e4b17023SJohn Marino /* If the reference is based on a decl that is not aliased the call
1494*e4b17023SJohn Marino cannot possibly clobber it. */
1495*e4b17023SJohn Marino if (DECL_P (base)
1496*e4b17023SJohn Marino && !may_be_aliased (base)
1497*e4b17023SJohn Marino /* But local non-readonly statics can be modified through recursion
1498*e4b17023SJohn Marino or the call may implement a threading barrier which we must
1499*e4b17023SJohn Marino treat as may-def. */
1500*e4b17023SJohn Marino && (TREE_READONLY (base)
1501*e4b17023SJohn Marino || !is_global_var (base)))
1502*e4b17023SJohn Marino return false;
1503*e4b17023SJohn Marino
1504*e4b17023SJohn Marino callee = gimple_call_fndecl (call);
1505*e4b17023SJohn Marino
1506*e4b17023SJohn Marino /* Handle those builtin functions explicitly that do not act as
1507*e4b17023SJohn Marino escape points. See tree-ssa-structalias.c:find_func_aliases
1508*e4b17023SJohn Marino for the list of builtins we might need to handle here. */
1509*e4b17023SJohn Marino if (callee != NULL_TREE
1510*e4b17023SJohn Marino && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL)
1511*e4b17023SJohn Marino switch (DECL_FUNCTION_CODE (callee))
1512*e4b17023SJohn Marino {
1513*e4b17023SJohn Marino /* All the following functions clobber memory pointed to by
1514*e4b17023SJohn Marino their first argument. */
1515*e4b17023SJohn Marino case BUILT_IN_STRCPY:
1516*e4b17023SJohn Marino case BUILT_IN_STRNCPY:
1517*e4b17023SJohn Marino case BUILT_IN_MEMCPY:
1518*e4b17023SJohn Marino case BUILT_IN_MEMMOVE:
1519*e4b17023SJohn Marino case BUILT_IN_MEMPCPY:
1520*e4b17023SJohn Marino case BUILT_IN_STPCPY:
1521*e4b17023SJohn Marino case BUILT_IN_STPNCPY:
1522*e4b17023SJohn Marino case BUILT_IN_STRCAT:
1523*e4b17023SJohn Marino case BUILT_IN_STRNCAT:
1524*e4b17023SJohn Marino case BUILT_IN_MEMSET:
1525*e4b17023SJohn Marino case BUILT_IN_TM_MEMSET:
1526*e4b17023SJohn Marino CASE_BUILT_IN_TM_STORE (1):
1527*e4b17023SJohn Marino CASE_BUILT_IN_TM_STORE (2):
1528*e4b17023SJohn Marino CASE_BUILT_IN_TM_STORE (4):
1529*e4b17023SJohn Marino CASE_BUILT_IN_TM_STORE (8):
1530*e4b17023SJohn Marino CASE_BUILT_IN_TM_STORE (FLOAT):
1531*e4b17023SJohn Marino CASE_BUILT_IN_TM_STORE (DOUBLE):
1532*e4b17023SJohn Marino CASE_BUILT_IN_TM_STORE (LDOUBLE):
1533*e4b17023SJohn Marino CASE_BUILT_IN_TM_STORE (M64):
1534*e4b17023SJohn Marino CASE_BUILT_IN_TM_STORE (M128):
1535*e4b17023SJohn Marino CASE_BUILT_IN_TM_STORE (M256):
1536*e4b17023SJohn Marino case BUILT_IN_TM_MEMCPY:
1537*e4b17023SJohn Marino case BUILT_IN_TM_MEMMOVE:
1538*e4b17023SJohn Marino {
1539*e4b17023SJohn Marino ao_ref dref;
1540*e4b17023SJohn Marino tree size = NULL_TREE;
1541*e4b17023SJohn Marino /* Don't pass in size for strncat, as the maximum size
1542*e4b17023SJohn Marino is strlen (dest) + n + 1 instead of n, resp.
1543*e4b17023SJohn Marino n + 1 at dest + strlen (dest), but strlen (dest) isn't
1544*e4b17023SJohn Marino known. */
1545*e4b17023SJohn Marino if (gimple_call_num_args (call) == 3
1546*e4b17023SJohn Marino && DECL_FUNCTION_CODE (callee) != BUILT_IN_STRNCAT)
1547*e4b17023SJohn Marino size = gimple_call_arg (call, 2);
1548*e4b17023SJohn Marino ao_ref_init_from_ptr_and_size (&dref,
1549*e4b17023SJohn Marino gimple_call_arg (call, 0),
1550*e4b17023SJohn Marino size);
1551*e4b17023SJohn Marino return refs_may_alias_p_1 (&dref, ref, false);
1552*e4b17023SJohn Marino }
1553*e4b17023SJohn Marino case BUILT_IN_STRCPY_CHK:
1554*e4b17023SJohn Marino case BUILT_IN_STRNCPY_CHK:
1555*e4b17023SJohn Marino case BUILT_IN_MEMCPY_CHK:
1556*e4b17023SJohn Marino case BUILT_IN_MEMMOVE_CHK:
1557*e4b17023SJohn Marino case BUILT_IN_MEMPCPY_CHK:
1558*e4b17023SJohn Marino case BUILT_IN_STPCPY_CHK:
1559*e4b17023SJohn Marino case BUILT_IN_STPNCPY_CHK:
1560*e4b17023SJohn Marino case BUILT_IN_STRCAT_CHK:
1561*e4b17023SJohn Marino case BUILT_IN_STRNCAT_CHK:
1562*e4b17023SJohn Marino case BUILT_IN_MEMSET_CHK:
1563*e4b17023SJohn Marino {
1564*e4b17023SJohn Marino ao_ref dref;
1565*e4b17023SJohn Marino tree size = NULL_TREE;
1566*e4b17023SJohn Marino /* Don't pass in size for __strncat_chk, as the maximum size
1567*e4b17023SJohn Marino is strlen (dest) + n + 1 instead of n, resp.
1568*e4b17023SJohn Marino n + 1 at dest + strlen (dest), but strlen (dest) isn't
1569*e4b17023SJohn Marino known. */
1570*e4b17023SJohn Marino if (gimple_call_num_args (call) == 4
1571*e4b17023SJohn Marino && DECL_FUNCTION_CODE (callee) != BUILT_IN_STRNCAT_CHK)
1572*e4b17023SJohn Marino size = gimple_call_arg (call, 2);
1573*e4b17023SJohn Marino ao_ref_init_from_ptr_and_size (&dref,
1574*e4b17023SJohn Marino gimple_call_arg (call, 0),
1575*e4b17023SJohn Marino size);
1576*e4b17023SJohn Marino return refs_may_alias_p_1 (&dref, ref, false);
1577*e4b17023SJohn Marino }
1578*e4b17023SJohn Marino case BUILT_IN_BCOPY:
1579*e4b17023SJohn Marino {
1580*e4b17023SJohn Marino ao_ref dref;
1581*e4b17023SJohn Marino tree size = gimple_call_arg (call, 2);
1582*e4b17023SJohn Marino ao_ref_init_from_ptr_and_size (&dref,
1583*e4b17023SJohn Marino gimple_call_arg (call, 1),
1584*e4b17023SJohn Marino size);
1585*e4b17023SJohn Marino return refs_may_alias_p_1 (&dref, ref, false);
1586*e4b17023SJohn Marino }
1587*e4b17023SJohn Marino /* Allocating memory does not have any side-effects apart from
1588*e4b17023SJohn Marino being the definition point for the pointer. */
1589*e4b17023SJohn Marino case BUILT_IN_MALLOC:
1590*e4b17023SJohn Marino case BUILT_IN_CALLOC:
1591*e4b17023SJohn Marino case BUILT_IN_STRDUP:
1592*e4b17023SJohn Marino case BUILT_IN_STRNDUP:
1593*e4b17023SJohn Marino /* Unix98 specifies that errno is set on allocation failure. */
1594*e4b17023SJohn Marino if (flag_errno_math
1595*e4b17023SJohn Marino && targetm.ref_may_alias_errno (ref))
1596*e4b17023SJohn Marino return true;
1597*e4b17023SJohn Marino return false;
1598*e4b17023SJohn Marino case BUILT_IN_STACK_SAVE:
1599*e4b17023SJohn Marino case BUILT_IN_ALLOCA:
1600*e4b17023SJohn Marino case BUILT_IN_ALLOCA_WITH_ALIGN:
1601*e4b17023SJohn Marino case BUILT_IN_ASSUME_ALIGNED:
1602*e4b17023SJohn Marino return false;
1603*e4b17023SJohn Marino /* Freeing memory kills the pointed-to memory. More importantly
1604*e4b17023SJohn Marino the call has to serve as a barrier for moving loads and stores
1605*e4b17023SJohn Marino across it. */
1606*e4b17023SJohn Marino case BUILT_IN_FREE:
1607*e4b17023SJohn Marino case BUILT_IN_VA_END:
1608*e4b17023SJohn Marino {
1609*e4b17023SJohn Marino tree ptr = gimple_call_arg (call, 0);
1610*e4b17023SJohn Marino return ptr_deref_may_alias_ref_p_1 (ptr, ref);
1611*e4b17023SJohn Marino }
1612*e4b17023SJohn Marino case BUILT_IN_GAMMA_R:
1613*e4b17023SJohn Marino case BUILT_IN_GAMMAF_R:
1614*e4b17023SJohn Marino case BUILT_IN_GAMMAL_R:
1615*e4b17023SJohn Marino case BUILT_IN_LGAMMA_R:
1616*e4b17023SJohn Marino case BUILT_IN_LGAMMAF_R:
1617*e4b17023SJohn Marino case BUILT_IN_LGAMMAL_R:
1618*e4b17023SJohn Marino {
1619*e4b17023SJohn Marino tree out = gimple_call_arg (call, 1);
1620*e4b17023SJohn Marino if (ptr_deref_may_alias_ref_p_1 (out, ref))
1621*e4b17023SJohn Marino return true;
1622*e4b17023SJohn Marino if (flag_errno_math)
1623*e4b17023SJohn Marino break;
1624*e4b17023SJohn Marino return false;
1625*e4b17023SJohn Marino }
1626*e4b17023SJohn Marino case BUILT_IN_FREXP:
1627*e4b17023SJohn Marino case BUILT_IN_FREXPF:
1628*e4b17023SJohn Marino case BUILT_IN_FREXPL:
1629*e4b17023SJohn Marino case BUILT_IN_MODF:
1630*e4b17023SJohn Marino case BUILT_IN_MODFF:
1631*e4b17023SJohn Marino case BUILT_IN_MODFL:
1632*e4b17023SJohn Marino {
1633*e4b17023SJohn Marino tree out = gimple_call_arg (call, 1);
1634*e4b17023SJohn Marino return ptr_deref_may_alias_ref_p_1 (out, ref);
1635*e4b17023SJohn Marino }
1636*e4b17023SJohn Marino case BUILT_IN_REMQUO:
1637*e4b17023SJohn Marino case BUILT_IN_REMQUOF:
1638*e4b17023SJohn Marino case BUILT_IN_REMQUOL:
1639*e4b17023SJohn Marino {
1640*e4b17023SJohn Marino tree out = gimple_call_arg (call, 2);
1641*e4b17023SJohn Marino if (ptr_deref_may_alias_ref_p_1 (out, ref))
1642*e4b17023SJohn Marino return true;
1643*e4b17023SJohn Marino if (flag_errno_math)
1644*e4b17023SJohn Marino break;
1645*e4b17023SJohn Marino return false;
1646*e4b17023SJohn Marino }
1647*e4b17023SJohn Marino case BUILT_IN_SINCOS:
1648*e4b17023SJohn Marino case BUILT_IN_SINCOSF:
1649*e4b17023SJohn Marino case BUILT_IN_SINCOSL:
1650*e4b17023SJohn Marino {
1651*e4b17023SJohn Marino tree sin = gimple_call_arg (call, 1);
1652*e4b17023SJohn Marino tree cos = gimple_call_arg (call, 2);
1653*e4b17023SJohn Marino return (ptr_deref_may_alias_ref_p_1 (sin, ref)
1654*e4b17023SJohn Marino || ptr_deref_may_alias_ref_p_1 (cos, ref));
1655*e4b17023SJohn Marino }
1656*e4b17023SJohn Marino /* __sync_* builtins and some OpenMP builtins act as threading
1657*e4b17023SJohn Marino barriers. */
1658*e4b17023SJohn Marino #undef DEF_SYNC_BUILTIN
1659*e4b17023SJohn Marino #define DEF_SYNC_BUILTIN(ENUM, NAME, TYPE, ATTRS) case ENUM:
1660*e4b17023SJohn Marino #include "sync-builtins.def"
1661*e4b17023SJohn Marino #undef DEF_SYNC_BUILTIN
1662*e4b17023SJohn Marino case BUILT_IN_GOMP_ATOMIC_START:
1663*e4b17023SJohn Marino case BUILT_IN_GOMP_ATOMIC_END:
1664*e4b17023SJohn Marino case BUILT_IN_GOMP_BARRIER:
1665*e4b17023SJohn Marino case BUILT_IN_GOMP_TASKWAIT:
1666*e4b17023SJohn Marino case BUILT_IN_GOMP_CRITICAL_START:
1667*e4b17023SJohn Marino case BUILT_IN_GOMP_CRITICAL_END:
1668*e4b17023SJohn Marino case BUILT_IN_GOMP_CRITICAL_NAME_START:
1669*e4b17023SJohn Marino case BUILT_IN_GOMP_CRITICAL_NAME_END:
1670*e4b17023SJohn Marino case BUILT_IN_GOMP_LOOP_END:
1671*e4b17023SJohn Marino case BUILT_IN_GOMP_ORDERED_START:
1672*e4b17023SJohn Marino case BUILT_IN_GOMP_ORDERED_END:
1673*e4b17023SJohn Marino case BUILT_IN_GOMP_PARALLEL_END:
1674*e4b17023SJohn Marino case BUILT_IN_GOMP_SECTIONS_END:
1675*e4b17023SJohn Marino case BUILT_IN_GOMP_SINGLE_COPY_START:
1676*e4b17023SJohn Marino case BUILT_IN_GOMP_SINGLE_COPY_END:
1677*e4b17023SJohn Marino return true;
1678*e4b17023SJohn Marino default:
1679*e4b17023SJohn Marino /* Fallthru to general call handling. */;
1680*e4b17023SJohn Marino }
1681*e4b17023SJohn Marino
1682*e4b17023SJohn Marino /* Check if base is a global static variable that is not written
1683*e4b17023SJohn Marino by the function. */
1684*e4b17023SJohn Marino if (callee != NULL_TREE
1685*e4b17023SJohn Marino && TREE_CODE (base) == VAR_DECL
1686*e4b17023SJohn Marino && TREE_STATIC (base))
1687*e4b17023SJohn Marino {
1688*e4b17023SJohn Marino struct cgraph_node *node = cgraph_get_node (callee);
1689*e4b17023SJohn Marino bitmap not_written;
1690*e4b17023SJohn Marino
1691*e4b17023SJohn Marino if (node
1692*e4b17023SJohn Marino && (not_written = ipa_reference_get_not_written_global (node))
1693*e4b17023SJohn Marino && bitmap_bit_p (not_written, DECL_UID (base)))
1694*e4b17023SJohn Marino return false;
1695*e4b17023SJohn Marino }
1696*e4b17023SJohn Marino
1697*e4b17023SJohn Marino /* Check if the base variable is call-clobbered. */
1698*e4b17023SJohn Marino if (DECL_P (base))
1699*e4b17023SJohn Marino return pt_solution_includes (gimple_call_clobber_set (call), base);
1700*e4b17023SJohn Marino else if ((TREE_CODE (base) == MEM_REF
1701*e4b17023SJohn Marino || TREE_CODE (base) == TARGET_MEM_REF)
1702*e4b17023SJohn Marino && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
1703*e4b17023SJohn Marino {
1704*e4b17023SJohn Marino struct ptr_info_def *pi = SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0));
1705*e4b17023SJohn Marino if (!pi)
1706*e4b17023SJohn Marino return true;
1707*e4b17023SJohn Marino
1708*e4b17023SJohn Marino return pt_solutions_intersect (gimple_call_clobber_set (call), &pi->pt);
1709*e4b17023SJohn Marino }
1710*e4b17023SJohn Marino
1711*e4b17023SJohn Marino return true;
1712*e4b17023SJohn Marino }
1713*e4b17023SJohn Marino
1714*e4b17023SJohn Marino /* If the call in statement CALL may clobber the memory reference REF
1715*e4b17023SJohn Marino return true, otherwise return false. */
1716*e4b17023SJohn Marino
1717*e4b17023SJohn Marino bool
call_may_clobber_ref_p(gimple call,tree ref)1718*e4b17023SJohn Marino call_may_clobber_ref_p (gimple call, tree ref)
1719*e4b17023SJohn Marino {
1720*e4b17023SJohn Marino bool res;
1721*e4b17023SJohn Marino ao_ref r;
1722*e4b17023SJohn Marino ao_ref_init (&r, ref);
1723*e4b17023SJohn Marino res = call_may_clobber_ref_p_1 (call, &r);
1724*e4b17023SJohn Marino if (res)
1725*e4b17023SJohn Marino ++alias_stats.call_may_clobber_ref_p_may_alias;
1726*e4b17023SJohn Marino else
1727*e4b17023SJohn Marino ++alias_stats.call_may_clobber_ref_p_no_alias;
1728*e4b17023SJohn Marino return res;
1729*e4b17023SJohn Marino }
1730*e4b17023SJohn Marino
1731*e4b17023SJohn Marino
1732*e4b17023SJohn Marino /* If the statement STMT may clobber the memory reference REF return true,
1733*e4b17023SJohn Marino otherwise return false. */
1734*e4b17023SJohn Marino
1735*e4b17023SJohn Marino bool
stmt_may_clobber_ref_p_1(gimple stmt,ao_ref * ref)1736*e4b17023SJohn Marino stmt_may_clobber_ref_p_1 (gimple stmt, ao_ref *ref)
1737*e4b17023SJohn Marino {
1738*e4b17023SJohn Marino if (is_gimple_call (stmt))
1739*e4b17023SJohn Marino {
1740*e4b17023SJohn Marino tree lhs = gimple_call_lhs (stmt);
1741*e4b17023SJohn Marino if (lhs
1742*e4b17023SJohn Marino && TREE_CODE (lhs) != SSA_NAME)
1743*e4b17023SJohn Marino {
1744*e4b17023SJohn Marino ao_ref r;
1745*e4b17023SJohn Marino ao_ref_init (&r, lhs);
1746*e4b17023SJohn Marino if (refs_may_alias_p_1 (ref, &r, true))
1747*e4b17023SJohn Marino return true;
1748*e4b17023SJohn Marino }
1749*e4b17023SJohn Marino
1750*e4b17023SJohn Marino return call_may_clobber_ref_p_1 (stmt, ref);
1751*e4b17023SJohn Marino }
1752*e4b17023SJohn Marino else if (gimple_assign_single_p (stmt))
1753*e4b17023SJohn Marino {
1754*e4b17023SJohn Marino tree lhs = gimple_assign_lhs (stmt);
1755*e4b17023SJohn Marino if (TREE_CODE (lhs) != SSA_NAME)
1756*e4b17023SJohn Marino {
1757*e4b17023SJohn Marino ao_ref r;
1758*e4b17023SJohn Marino ao_ref_init (&r, lhs);
1759*e4b17023SJohn Marino return refs_may_alias_p_1 (ref, &r, true);
1760*e4b17023SJohn Marino }
1761*e4b17023SJohn Marino }
1762*e4b17023SJohn Marino else if (gimple_code (stmt) == GIMPLE_ASM)
1763*e4b17023SJohn Marino return true;
1764*e4b17023SJohn Marino
1765*e4b17023SJohn Marino return false;
1766*e4b17023SJohn Marino }
1767*e4b17023SJohn Marino
1768*e4b17023SJohn Marino bool
stmt_may_clobber_ref_p(gimple stmt,tree ref)1769*e4b17023SJohn Marino stmt_may_clobber_ref_p (gimple stmt, tree ref)
1770*e4b17023SJohn Marino {
1771*e4b17023SJohn Marino ao_ref r;
1772*e4b17023SJohn Marino ao_ref_init (&r, ref);
1773*e4b17023SJohn Marino return stmt_may_clobber_ref_p_1 (stmt, &r);
1774*e4b17023SJohn Marino }
1775*e4b17023SJohn Marino
1776*e4b17023SJohn Marino /* If STMT kills the memory reference REF return true, otherwise
1777*e4b17023SJohn Marino return false. */
1778*e4b17023SJohn Marino
1779*e4b17023SJohn Marino static bool
stmt_kills_ref_p_1(gimple stmt,ao_ref * ref)1780*e4b17023SJohn Marino stmt_kills_ref_p_1 (gimple stmt, ao_ref *ref)
1781*e4b17023SJohn Marino {
1782*e4b17023SJohn Marino /* For a must-alias check we need to be able to constrain
1783*e4b17023SJohn Marino the access properly. */
1784*e4b17023SJohn Marino ao_ref_base (ref);
1785*e4b17023SJohn Marino if (ref->max_size == -1)
1786*e4b17023SJohn Marino return false;
1787*e4b17023SJohn Marino
1788*e4b17023SJohn Marino if (gimple_has_lhs (stmt)
1789*e4b17023SJohn Marino && TREE_CODE (gimple_get_lhs (stmt)) != SSA_NAME
1790*e4b17023SJohn Marino /* The assignment is not necessarily carried out if it can throw
1791*e4b17023SJohn Marino and we can catch it in the current function where we could inspect
1792*e4b17023SJohn Marino the previous value.
1793*e4b17023SJohn Marino ??? We only need to care about the RHS throwing. For aggregate
1794*e4b17023SJohn Marino assignments or similar calls and non-call exceptions the LHS
1795*e4b17023SJohn Marino might throw as well. */
1796*e4b17023SJohn Marino && !stmt_can_throw_internal (stmt))
1797*e4b17023SJohn Marino {
1798*e4b17023SJohn Marino tree base, lhs = gimple_get_lhs (stmt);
1799*e4b17023SJohn Marino HOST_WIDE_INT size, offset, max_size;
1800*e4b17023SJohn Marino base = get_ref_base_and_extent (lhs, &offset, &size, &max_size);
1801*e4b17023SJohn Marino /* We can get MEM[symbol: sZ, index: D.8862_1] here,
1802*e4b17023SJohn Marino so base == ref->base does not always hold. */
1803*e4b17023SJohn Marino if (base == ref->base)
1804*e4b17023SJohn Marino {
1805*e4b17023SJohn Marino /* For a must-alias check we need to be able to constrain
1806*e4b17023SJohn Marino the access properly. */
1807*e4b17023SJohn Marino if (size != -1 && size == max_size)
1808*e4b17023SJohn Marino {
1809*e4b17023SJohn Marino if (offset <= ref->offset
1810*e4b17023SJohn Marino && offset + size >= ref->offset + ref->max_size)
1811*e4b17023SJohn Marino return true;
1812*e4b17023SJohn Marino }
1813*e4b17023SJohn Marino }
1814*e4b17023SJohn Marino }
1815*e4b17023SJohn Marino
1816*e4b17023SJohn Marino if (is_gimple_call (stmt))
1817*e4b17023SJohn Marino {
1818*e4b17023SJohn Marino tree callee = gimple_call_fndecl (stmt);
1819*e4b17023SJohn Marino if (callee != NULL_TREE
1820*e4b17023SJohn Marino && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL)
1821*e4b17023SJohn Marino switch (DECL_FUNCTION_CODE (callee))
1822*e4b17023SJohn Marino {
1823*e4b17023SJohn Marino case BUILT_IN_MEMCPY:
1824*e4b17023SJohn Marino case BUILT_IN_MEMPCPY:
1825*e4b17023SJohn Marino case BUILT_IN_MEMMOVE:
1826*e4b17023SJohn Marino case BUILT_IN_MEMSET:
1827*e4b17023SJohn Marino case BUILT_IN_MEMCPY_CHK:
1828*e4b17023SJohn Marino case BUILT_IN_MEMPCPY_CHK:
1829*e4b17023SJohn Marino case BUILT_IN_MEMMOVE_CHK:
1830*e4b17023SJohn Marino case BUILT_IN_MEMSET_CHK:
1831*e4b17023SJohn Marino {
1832*e4b17023SJohn Marino tree dest = gimple_call_arg (stmt, 0);
1833*e4b17023SJohn Marino tree len = gimple_call_arg (stmt, 2);
1834*e4b17023SJohn Marino tree base = NULL_TREE;
1835*e4b17023SJohn Marino HOST_WIDE_INT offset = 0;
1836*e4b17023SJohn Marino if (!host_integerp (len, 0))
1837*e4b17023SJohn Marino return false;
1838*e4b17023SJohn Marino if (TREE_CODE (dest) == ADDR_EXPR)
1839*e4b17023SJohn Marino base = get_addr_base_and_unit_offset (TREE_OPERAND (dest, 0),
1840*e4b17023SJohn Marino &offset);
1841*e4b17023SJohn Marino else if (TREE_CODE (dest) == SSA_NAME)
1842*e4b17023SJohn Marino base = dest;
1843*e4b17023SJohn Marino if (base
1844*e4b17023SJohn Marino && base == ao_ref_base (ref))
1845*e4b17023SJohn Marino {
1846*e4b17023SJohn Marino HOST_WIDE_INT size = TREE_INT_CST_LOW (len);
1847*e4b17023SJohn Marino if (offset <= ref->offset / BITS_PER_UNIT
1848*e4b17023SJohn Marino && (offset + size
1849*e4b17023SJohn Marino >= ((ref->offset + ref->max_size + BITS_PER_UNIT - 1)
1850*e4b17023SJohn Marino / BITS_PER_UNIT)))
1851*e4b17023SJohn Marino return true;
1852*e4b17023SJohn Marino }
1853*e4b17023SJohn Marino break;
1854*e4b17023SJohn Marino }
1855*e4b17023SJohn Marino
1856*e4b17023SJohn Marino case BUILT_IN_VA_END:
1857*e4b17023SJohn Marino {
1858*e4b17023SJohn Marino tree ptr = gimple_call_arg (stmt, 0);
1859*e4b17023SJohn Marino if (TREE_CODE (ptr) == ADDR_EXPR)
1860*e4b17023SJohn Marino {
1861*e4b17023SJohn Marino tree base = ao_ref_base (ref);
1862*e4b17023SJohn Marino if (TREE_OPERAND (ptr, 0) == base)
1863*e4b17023SJohn Marino return true;
1864*e4b17023SJohn Marino }
1865*e4b17023SJohn Marino break;
1866*e4b17023SJohn Marino }
1867*e4b17023SJohn Marino
1868*e4b17023SJohn Marino default:;
1869*e4b17023SJohn Marino }
1870*e4b17023SJohn Marino }
1871*e4b17023SJohn Marino return false;
1872*e4b17023SJohn Marino }
1873*e4b17023SJohn Marino
1874*e4b17023SJohn Marino bool
stmt_kills_ref_p(gimple stmt,tree ref)1875*e4b17023SJohn Marino stmt_kills_ref_p (gimple stmt, tree ref)
1876*e4b17023SJohn Marino {
1877*e4b17023SJohn Marino ao_ref r;
1878*e4b17023SJohn Marino ao_ref_init (&r, ref);
1879*e4b17023SJohn Marino return stmt_kills_ref_p_1 (stmt, &r);
1880*e4b17023SJohn Marino }
1881*e4b17023SJohn Marino
1882*e4b17023SJohn Marino
1883*e4b17023SJohn Marino /* Walk the virtual use-def chain of VUSE until hitting the virtual operand
1884*e4b17023SJohn Marino TARGET or a statement clobbering the memory reference REF in which
1885*e4b17023SJohn Marino case false is returned. The walk starts with VUSE, one argument of PHI. */
1886*e4b17023SJohn Marino
1887*e4b17023SJohn Marino static bool
maybe_skip_until(gimple phi,tree target,ao_ref * ref,tree vuse,bitmap * visited,bool abort_on_visited)1888*e4b17023SJohn Marino maybe_skip_until (gimple phi, tree target, ao_ref *ref,
1889*e4b17023SJohn Marino tree vuse, bitmap *visited, bool abort_on_visited)
1890*e4b17023SJohn Marino {
1891*e4b17023SJohn Marino basic_block bb = gimple_bb (phi);
1892*e4b17023SJohn Marino
1893*e4b17023SJohn Marino if (!*visited)
1894*e4b17023SJohn Marino *visited = BITMAP_ALLOC (NULL);
1895*e4b17023SJohn Marino
1896*e4b17023SJohn Marino bitmap_set_bit (*visited, SSA_NAME_VERSION (PHI_RESULT (phi)));
1897*e4b17023SJohn Marino
1898*e4b17023SJohn Marino /* Walk until we hit the target. */
1899*e4b17023SJohn Marino while (vuse != target)
1900*e4b17023SJohn Marino {
1901*e4b17023SJohn Marino gimple def_stmt = SSA_NAME_DEF_STMT (vuse);
1902*e4b17023SJohn Marino /* Recurse for PHI nodes. */
1903*e4b17023SJohn Marino if (gimple_code (def_stmt) == GIMPLE_PHI)
1904*e4b17023SJohn Marino {
1905*e4b17023SJohn Marino /* An already visited PHI node ends the walk successfully. */
1906*e4b17023SJohn Marino if (bitmap_bit_p (*visited, SSA_NAME_VERSION (PHI_RESULT (def_stmt))))
1907*e4b17023SJohn Marino return !abort_on_visited;
1908*e4b17023SJohn Marino vuse = get_continuation_for_phi (def_stmt, ref,
1909*e4b17023SJohn Marino visited, abort_on_visited);
1910*e4b17023SJohn Marino if (!vuse)
1911*e4b17023SJohn Marino return false;
1912*e4b17023SJohn Marino continue;
1913*e4b17023SJohn Marino }
1914*e4b17023SJohn Marino /* A clobbering statement or the end of the IL ends it failing. */
1915*e4b17023SJohn Marino else if (gimple_nop_p (def_stmt)
1916*e4b17023SJohn Marino || stmt_may_clobber_ref_p_1 (def_stmt, ref))
1917*e4b17023SJohn Marino return false;
1918*e4b17023SJohn Marino /* If we reach a new basic-block see if we already skipped it
1919*e4b17023SJohn Marino in a previous walk that ended successfully. */
1920*e4b17023SJohn Marino if (gimple_bb (def_stmt) != bb)
1921*e4b17023SJohn Marino {
1922*e4b17023SJohn Marino if (!bitmap_set_bit (*visited, SSA_NAME_VERSION (vuse)))
1923*e4b17023SJohn Marino return !abort_on_visited;
1924*e4b17023SJohn Marino bb = gimple_bb (def_stmt);
1925*e4b17023SJohn Marino }
1926*e4b17023SJohn Marino vuse = gimple_vuse (def_stmt);
1927*e4b17023SJohn Marino }
1928*e4b17023SJohn Marino return true;
1929*e4b17023SJohn Marino }
1930*e4b17023SJohn Marino
1931*e4b17023SJohn Marino /* For two PHI arguments ARG0 and ARG1 try to skip non-aliasing code
1932*e4b17023SJohn Marino until we hit the phi argument definition that dominates the other one.
1933*e4b17023SJohn Marino Return that, or NULL_TREE if there is no such definition. */
1934*e4b17023SJohn Marino
1935*e4b17023SJohn Marino static tree
get_continuation_for_phi_1(gimple phi,tree arg0,tree arg1,ao_ref * ref,bitmap * visited,bool abort_on_visited)1936*e4b17023SJohn Marino get_continuation_for_phi_1 (gimple phi, tree arg0, tree arg1,
1937*e4b17023SJohn Marino ao_ref *ref, bitmap *visited,
1938*e4b17023SJohn Marino bool abort_on_visited)
1939*e4b17023SJohn Marino {
1940*e4b17023SJohn Marino gimple def0 = SSA_NAME_DEF_STMT (arg0);
1941*e4b17023SJohn Marino gimple def1 = SSA_NAME_DEF_STMT (arg1);
1942*e4b17023SJohn Marino tree common_vuse;
1943*e4b17023SJohn Marino
1944*e4b17023SJohn Marino if (arg0 == arg1)
1945*e4b17023SJohn Marino return arg0;
1946*e4b17023SJohn Marino else if (gimple_nop_p (def0)
1947*e4b17023SJohn Marino || (!gimple_nop_p (def1)
1948*e4b17023SJohn Marino && dominated_by_p (CDI_DOMINATORS,
1949*e4b17023SJohn Marino gimple_bb (def1), gimple_bb (def0))))
1950*e4b17023SJohn Marino {
1951*e4b17023SJohn Marino if (maybe_skip_until (phi, arg0, ref, arg1, visited, abort_on_visited))
1952*e4b17023SJohn Marino return arg0;
1953*e4b17023SJohn Marino }
1954*e4b17023SJohn Marino else if (gimple_nop_p (def1)
1955*e4b17023SJohn Marino || dominated_by_p (CDI_DOMINATORS,
1956*e4b17023SJohn Marino gimple_bb (def0), gimple_bb (def1)))
1957*e4b17023SJohn Marino {
1958*e4b17023SJohn Marino if (maybe_skip_until (phi, arg1, ref, arg0, visited, abort_on_visited))
1959*e4b17023SJohn Marino return arg1;
1960*e4b17023SJohn Marino }
1961*e4b17023SJohn Marino /* Special case of a diamond:
1962*e4b17023SJohn Marino MEM_1 = ...
1963*e4b17023SJohn Marino goto (cond) ? L1 : L2
1964*e4b17023SJohn Marino L1: store1 = ... #MEM_2 = vuse(MEM_1)
1965*e4b17023SJohn Marino goto L3
1966*e4b17023SJohn Marino L2: store2 = ... #MEM_3 = vuse(MEM_1)
1967*e4b17023SJohn Marino L3: MEM_4 = PHI<MEM_2, MEM_3>
1968*e4b17023SJohn Marino We were called with the PHI at L3, MEM_2 and MEM_3 don't
1969*e4b17023SJohn Marino dominate each other, but still we can easily skip this PHI node
1970*e4b17023SJohn Marino if we recognize that the vuse MEM operand is the same for both,
1971*e4b17023SJohn Marino and that we can skip both statements (they don't clobber us).
1972*e4b17023SJohn Marino This is still linear. Don't use maybe_skip_until, that might
1973*e4b17023SJohn Marino potentially be slow. */
1974*e4b17023SJohn Marino else if ((common_vuse = gimple_vuse (def0))
1975*e4b17023SJohn Marino && common_vuse == gimple_vuse (def1))
1976*e4b17023SJohn Marino {
1977*e4b17023SJohn Marino if (!stmt_may_clobber_ref_p_1 (def0, ref)
1978*e4b17023SJohn Marino && !stmt_may_clobber_ref_p_1 (def1, ref))
1979*e4b17023SJohn Marino return common_vuse;
1980*e4b17023SJohn Marino }
1981*e4b17023SJohn Marino
1982*e4b17023SJohn Marino return NULL_TREE;
1983*e4b17023SJohn Marino }
1984*e4b17023SJohn Marino
1985*e4b17023SJohn Marino
1986*e4b17023SJohn Marino /* Starting from a PHI node for the virtual operand of the memory reference
1987*e4b17023SJohn Marino REF find a continuation virtual operand that allows to continue walking
1988*e4b17023SJohn Marino statements dominating PHI skipping only statements that cannot possibly
1989*e4b17023SJohn Marino clobber REF. Returns NULL_TREE if no suitable virtual operand can
1990*e4b17023SJohn Marino be found. */
1991*e4b17023SJohn Marino
1992*e4b17023SJohn Marino tree
get_continuation_for_phi(gimple phi,ao_ref * ref,bitmap * visited,bool abort_on_visited)1993*e4b17023SJohn Marino get_continuation_for_phi (gimple phi, ao_ref *ref, bitmap *visited,
1994*e4b17023SJohn Marino bool abort_on_visited)
1995*e4b17023SJohn Marino {
1996*e4b17023SJohn Marino unsigned nargs = gimple_phi_num_args (phi);
1997*e4b17023SJohn Marino
1998*e4b17023SJohn Marino /* Through a single-argument PHI we can simply look through. */
1999*e4b17023SJohn Marino if (nargs == 1)
2000*e4b17023SJohn Marino return PHI_ARG_DEF (phi, 0);
2001*e4b17023SJohn Marino
2002*e4b17023SJohn Marino /* For two or more arguments try to pairwise skip non-aliasing code
2003*e4b17023SJohn Marino until we hit the phi argument definition that dominates the other one. */
2004*e4b17023SJohn Marino else if (nargs >= 2)
2005*e4b17023SJohn Marino {
2006*e4b17023SJohn Marino tree arg0, arg1;
2007*e4b17023SJohn Marino unsigned i;
2008*e4b17023SJohn Marino
2009*e4b17023SJohn Marino /* Find a candidate for the virtual operand which definition
2010*e4b17023SJohn Marino dominates those of all others. */
2011*e4b17023SJohn Marino arg0 = PHI_ARG_DEF (phi, 0);
2012*e4b17023SJohn Marino if (!SSA_NAME_IS_DEFAULT_DEF (arg0))
2013*e4b17023SJohn Marino for (i = 1; i < nargs; ++i)
2014*e4b17023SJohn Marino {
2015*e4b17023SJohn Marino arg1 = PHI_ARG_DEF (phi, i);
2016*e4b17023SJohn Marino if (SSA_NAME_IS_DEFAULT_DEF (arg1))
2017*e4b17023SJohn Marino {
2018*e4b17023SJohn Marino arg0 = arg1;
2019*e4b17023SJohn Marino break;
2020*e4b17023SJohn Marino }
2021*e4b17023SJohn Marino if (dominated_by_p (CDI_DOMINATORS,
2022*e4b17023SJohn Marino gimple_bb (SSA_NAME_DEF_STMT (arg0)),
2023*e4b17023SJohn Marino gimple_bb (SSA_NAME_DEF_STMT (arg1))))
2024*e4b17023SJohn Marino arg0 = arg1;
2025*e4b17023SJohn Marino }
2026*e4b17023SJohn Marino
2027*e4b17023SJohn Marino /* Then pairwise reduce against the found candidate. */
2028*e4b17023SJohn Marino for (i = 0; i < nargs; ++i)
2029*e4b17023SJohn Marino {
2030*e4b17023SJohn Marino arg1 = PHI_ARG_DEF (phi, i);
2031*e4b17023SJohn Marino arg0 = get_continuation_for_phi_1 (phi, arg0, arg1, ref, visited,
2032*e4b17023SJohn Marino abort_on_visited);
2033*e4b17023SJohn Marino if (!arg0)
2034*e4b17023SJohn Marino return NULL_TREE;
2035*e4b17023SJohn Marino }
2036*e4b17023SJohn Marino
2037*e4b17023SJohn Marino return arg0;
2038*e4b17023SJohn Marino }
2039*e4b17023SJohn Marino
2040*e4b17023SJohn Marino return NULL_TREE;
2041*e4b17023SJohn Marino }
2042*e4b17023SJohn Marino
2043*e4b17023SJohn Marino /* Based on the memory reference REF and its virtual use VUSE call
2044*e4b17023SJohn Marino WALKER for each virtual use that is equivalent to VUSE, including VUSE
2045*e4b17023SJohn Marino itself. That is, for each virtual use for which its defining statement
2046*e4b17023SJohn Marino does not clobber REF.
2047*e4b17023SJohn Marino
2048*e4b17023SJohn Marino WALKER is called with REF, the current virtual use and DATA. If
2049*e4b17023SJohn Marino WALKER returns non-NULL the walk stops and its result is returned.
2050*e4b17023SJohn Marino At the end of a non-successful walk NULL is returned.
2051*e4b17023SJohn Marino
2052*e4b17023SJohn Marino TRANSLATE if non-NULL is called with a pointer to REF, the virtual
2053*e4b17023SJohn Marino use which definition is a statement that may clobber REF and DATA.
2054*e4b17023SJohn Marino If TRANSLATE returns (void *)-1 the walk stops and NULL is returned.
2055*e4b17023SJohn Marino If TRANSLATE returns non-NULL the walk stops and its result is returned.
2056*e4b17023SJohn Marino If TRANSLATE returns NULL the walk continues and TRANSLATE is supposed
2057*e4b17023SJohn Marino to adjust REF and *DATA to make that valid.
2058*e4b17023SJohn Marino
2059*e4b17023SJohn Marino TODO: Cache the vector of equivalent vuses per ref, vuse pair. */
2060*e4b17023SJohn Marino
2061*e4b17023SJohn Marino void *
walk_non_aliased_vuses(ao_ref * ref,tree vuse,void * (* walker)(ao_ref *,tree,void *),void * (* translate)(ao_ref *,tree,void *),void * data)2062*e4b17023SJohn Marino walk_non_aliased_vuses (ao_ref *ref, tree vuse,
2063*e4b17023SJohn Marino void *(*walker)(ao_ref *, tree, void *),
2064*e4b17023SJohn Marino void *(*translate)(ao_ref *, tree, void *), void *data)
2065*e4b17023SJohn Marino {
2066*e4b17023SJohn Marino bitmap visited = NULL;
2067*e4b17023SJohn Marino void *res;
2068*e4b17023SJohn Marino bool translated = false;
2069*e4b17023SJohn Marino
2070*e4b17023SJohn Marino timevar_push (TV_ALIAS_STMT_WALK);
2071*e4b17023SJohn Marino
2072*e4b17023SJohn Marino do
2073*e4b17023SJohn Marino {
2074*e4b17023SJohn Marino gimple def_stmt;
2075*e4b17023SJohn Marino
2076*e4b17023SJohn Marino /* ??? Do we want to account this to TV_ALIAS_STMT_WALK? */
2077*e4b17023SJohn Marino res = (*walker) (ref, vuse, data);
2078*e4b17023SJohn Marino if (res)
2079*e4b17023SJohn Marino break;
2080*e4b17023SJohn Marino
2081*e4b17023SJohn Marino def_stmt = SSA_NAME_DEF_STMT (vuse);
2082*e4b17023SJohn Marino if (gimple_nop_p (def_stmt))
2083*e4b17023SJohn Marino break;
2084*e4b17023SJohn Marino else if (gimple_code (def_stmt) == GIMPLE_PHI)
2085*e4b17023SJohn Marino vuse = get_continuation_for_phi (def_stmt, ref, &visited, translated);
2086*e4b17023SJohn Marino else
2087*e4b17023SJohn Marino {
2088*e4b17023SJohn Marino if (stmt_may_clobber_ref_p_1 (def_stmt, ref))
2089*e4b17023SJohn Marino {
2090*e4b17023SJohn Marino if (!translate)
2091*e4b17023SJohn Marino break;
2092*e4b17023SJohn Marino res = (*translate) (ref, vuse, data);
2093*e4b17023SJohn Marino /* Failed lookup and translation. */
2094*e4b17023SJohn Marino if (res == (void *)-1)
2095*e4b17023SJohn Marino {
2096*e4b17023SJohn Marino res = NULL;
2097*e4b17023SJohn Marino break;
2098*e4b17023SJohn Marino }
2099*e4b17023SJohn Marino /* Lookup succeeded. */
2100*e4b17023SJohn Marino else if (res != NULL)
2101*e4b17023SJohn Marino break;
2102*e4b17023SJohn Marino /* Translation succeeded, continue walking. */
2103*e4b17023SJohn Marino translated = true;
2104*e4b17023SJohn Marino }
2105*e4b17023SJohn Marino vuse = gimple_vuse (def_stmt);
2106*e4b17023SJohn Marino }
2107*e4b17023SJohn Marino }
2108*e4b17023SJohn Marino while (vuse);
2109*e4b17023SJohn Marino
2110*e4b17023SJohn Marino if (visited)
2111*e4b17023SJohn Marino BITMAP_FREE (visited);
2112*e4b17023SJohn Marino
2113*e4b17023SJohn Marino timevar_pop (TV_ALIAS_STMT_WALK);
2114*e4b17023SJohn Marino
2115*e4b17023SJohn Marino return res;
2116*e4b17023SJohn Marino }
2117*e4b17023SJohn Marino
2118*e4b17023SJohn Marino
2119*e4b17023SJohn Marino /* Based on the memory reference REF call WALKER for each vdef which
2120*e4b17023SJohn Marino defining statement may clobber REF, starting with VDEF. If REF
2121*e4b17023SJohn Marino is NULL_TREE, each defining statement is visited.
2122*e4b17023SJohn Marino
2123*e4b17023SJohn Marino WALKER is called with REF, the current vdef and DATA. If WALKER
2124*e4b17023SJohn Marino returns true the walk is stopped, otherwise it continues.
2125*e4b17023SJohn Marino
2126*e4b17023SJohn Marino At PHI nodes walk_aliased_vdefs forks into one walk for reach
2127*e4b17023SJohn Marino PHI argument (but only one walk continues on merge points), the
2128*e4b17023SJohn Marino return value is true if any of the walks was successful.
2129*e4b17023SJohn Marino
2130*e4b17023SJohn Marino The function returns the number of statements walked. */
2131*e4b17023SJohn Marino
2132*e4b17023SJohn Marino static unsigned int
walk_aliased_vdefs_1(ao_ref * ref,tree vdef,bool (* walker)(ao_ref *,tree,void *),void * data,bitmap * visited,unsigned int cnt)2133*e4b17023SJohn Marino walk_aliased_vdefs_1 (ao_ref *ref, tree vdef,
2134*e4b17023SJohn Marino bool (*walker)(ao_ref *, tree, void *), void *data,
2135*e4b17023SJohn Marino bitmap *visited, unsigned int cnt)
2136*e4b17023SJohn Marino {
2137*e4b17023SJohn Marino do
2138*e4b17023SJohn Marino {
2139*e4b17023SJohn Marino gimple def_stmt = SSA_NAME_DEF_STMT (vdef);
2140*e4b17023SJohn Marino
2141*e4b17023SJohn Marino if (*visited
2142*e4b17023SJohn Marino && !bitmap_set_bit (*visited, SSA_NAME_VERSION (vdef)))
2143*e4b17023SJohn Marino return cnt;
2144*e4b17023SJohn Marino
2145*e4b17023SJohn Marino if (gimple_nop_p (def_stmt))
2146*e4b17023SJohn Marino return cnt;
2147*e4b17023SJohn Marino else if (gimple_code (def_stmt) == GIMPLE_PHI)
2148*e4b17023SJohn Marino {
2149*e4b17023SJohn Marino unsigned i;
2150*e4b17023SJohn Marino if (!*visited)
2151*e4b17023SJohn Marino *visited = BITMAP_ALLOC (NULL);
2152*e4b17023SJohn Marino for (i = 0; i < gimple_phi_num_args (def_stmt); ++i)
2153*e4b17023SJohn Marino cnt += walk_aliased_vdefs_1 (ref, gimple_phi_arg_def (def_stmt, i),
2154*e4b17023SJohn Marino walker, data, visited, 0);
2155*e4b17023SJohn Marino return cnt;
2156*e4b17023SJohn Marino }
2157*e4b17023SJohn Marino
2158*e4b17023SJohn Marino /* ??? Do we want to account this to TV_ALIAS_STMT_WALK? */
2159*e4b17023SJohn Marino cnt++;
2160*e4b17023SJohn Marino if ((!ref
2161*e4b17023SJohn Marino || stmt_may_clobber_ref_p_1 (def_stmt, ref))
2162*e4b17023SJohn Marino && (*walker) (ref, vdef, data))
2163*e4b17023SJohn Marino return cnt;
2164*e4b17023SJohn Marino
2165*e4b17023SJohn Marino vdef = gimple_vuse (def_stmt);
2166*e4b17023SJohn Marino }
2167*e4b17023SJohn Marino while (1);
2168*e4b17023SJohn Marino }
2169*e4b17023SJohn Marino
2170*e4b17023SJohn Marino unsigned int
walk_aliased_vdefs(ao_ref * ref,tree vdef,bool (* walker)(ao_ref *,tree,void *),void * data,bitmap * visited)2171*e4b17023SJohn Marino walk_aliased_vdefs (ao_ref *ref, tree vdef,
2172*e4b17023SJohn Marino bool (*walker)(ao_ref *, tree, void *), void *data,
2173*e4b17023SJohn Marino bitmap *visited)
2174*e4b17023SJohn Marino {
2175*e4b17023SJohn Marino bitmap local_visited = NULL;
2176*e4b17023SJohn Marino unsigned int ret;
2177*e4b17023SJohn Marino
2178*e4b17023SJohn Marino timevar_push (TV_ALIAS_STMT_WALK);
2179*e4b17023SJohn Marino
2180*e4b17023SJohn Marino ret = walk_aliased_vdefs_1 (ref, vdef, walker, data,
2181*e4b17023SJohn Marino visited ? visited : &local_visited, 0);
2182*e4b17023SJohn Marino if (local_visited)
2183*e4b17023SJohn Marino BITMAP_FREE (local_visited);
2184*e4b17023SJohn Marino
2185*e4b17023SJohn Marino timevar_pop (TV_ALIAS_STMT_WALK);
2186*e4b17023SJohn Marino
2187*e4b17023SJohn Marino return ret;
2188*e4b17023SJohn Marino }
2189*e4b17023SJohn Marino
2190