xref: /dflybsd-src/contrib/gcc-4.7/gcc/tree-ssa-alias.c (revision 04febcfb30580676d3e95f58a16c5137ee478b32)
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