2004-07-16 Daniel Berlin <dberlin@dberlin.org>
[official-gcc.git] / gcc / tree-alias-common.c
bloba7ce22d8782f8477faec816c9f2ad629383c692e
1 /* Tree based points-to analysis
2 Copyright (C) 2002, 2003 Free Software Foundation, Inc.
3 Contributed by Daniel Berlin <dberlin@dberlin.org>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "ggc.h"
27 #include "tree-alias-type.h"
28 #include "bitmap.h"
29 #include "tree-alias-common.h"
31 /* If we have andersen's points-to analysis, include it. */
32 #ifdef HAVE_BANSHEE
33 #include "tree-alias-ander.h"
34 #endif
36 #include "flags.h"
37 #include "rtl.h"
38 #include "tm_p.h"
39 #include "hard-reg-set.h"
40 #include "basic-block.h"
41 #include "output.h"
42 #include "errors.h"
43 #include "expr.h"
44 #include "diagnostic.h"
45 #include "tree.h"
46 #include "c-common.h"
47 #include "tree-flow.h"
48 #include "tree-inline.h"
49 #include "varray.h"
50 #include "c-tree.h"
51 #include "tree-gimple.h"
52 #include "hashtab.h"
53 #include "function.h"
54 #include "cgraph.h"
55 #include "tree-pass.h"
56 #include "timevar.h"
58 /* Reduce ifdefery later. */
59 #ifndef HAVE_BANSHEE
60 #define HAVE_BANSHEE 0
61 #endif
63 /* This file contains the implementation of the common parts of the
64 tree points-to analysis infrastructure.
66 Overview:
68 This file contains the points-to analysis driver. It does two main things:
69 1. Keeps track of the PTA data for each variable (IE the data each
70 specific PTA implementation wants to keep associated with a
71 variable).
72 2. Walks the function trees, calling the appropriate functions that
73 each PTA implementation has implemented.
75 In order to speed up PTA queries, the PTA specific data is stored
76 in the tree for *_DECL's, in DECL_PTA_ALIASVAR. This way, we only
77 need to use the hash table for non-DECL's. */
78 #define FIELD_BASED 0
80 /* Array of all created alias_vars.
81 Note that this should contain all the alias_vars we wanted
82 marked during GC. */
83 static GTY((param_is (union alias_var_def))) varray_type alias_vars = NULL;
84 struct tree_alias_ops *current_alias_ops;
86 /* Array of local (to a function) alias_vars.
87 Note that this should contain all the alias_vars that are
88 local to this function. We delete these from alias_vars before
89 collection. */
90 static GTY(()) varray_type local_alias_vars;
91 static GTY(()) varray_type local_alias_varnums;
92 tree pta_global_var;
93 static bitmap addrargs;
94 static alias_var get_alias_var_decl (tree);
95 static alias_var get_alias_var (tree);
96 static void find_func_aliases (tree);
97 static void deal_with_call_aliasing (tree, alias_var);
98 static alias_var create_fun_alias_var_ptf (tree, tree);
99 static alias_var create_fun_alias_var (tree, int);
100 static alias_var create_alias_var (tree);
101 static void intra_function_call (varray_type);
102 static void get_values_from_constructor (tree, varray_type *, bitmap, int *);
103 static bool call_may_clobber (tree);
104 static bool call_may_return (tree);
106 /* Return true if a EXPR, which is a CALL_EXPR, may clobber variables. */
108 static bool
109 call_may_clobber (tree expr)
111 int flags;
113 if (TREE_CODE (expr) != CALL_EXPR)
114 return false;
116 flags = call_expr_flags (expr);
117 return (! (flags & (ECF_CONST | ECF_PURE | ECF_NORETURN)));
120 /* Return true if a EXPR, which is a CALL_EXPR, may return. */
122 static bool
123 call_may_return (tree expr)
125 int flags;
127 if (TREE_CODE (expr) != CALL_EXPR)
128 return false;
130 flags = call_expr_flags (expr);
131 return ! (flags & ECF_NORETURN);
134 /* Get the alias_var for DECL.
135 Creates the alias_var if it does not exist already. Also
136 handles FUNCTION_DECL properly. */
138 static alias_var
139 get_alias_var_decl (tree decl)
141 alias_var newvar;
142 if (TREE_CODE (decl) == FIELD_DECL)
143 abort ();
144 if (DECL_P (decl))
146 if (DECL_PTA_ALIASVAR (decl))
147 return DECL_PTA_ALIASVAR (decl);
150 if (TREE_CODE (decl) == FUNCTION_DECL)
151 newvar = create_fun_alias_var (decl, 0);
152 else
154 newvar = create_alias_var (decl);
155 /* Assign globals to global var for purposes of intraprocedural
156 analysis. */
157 if ((DECL_CONTEXT (decl) == NULL
158 || TREE_PUBLIC (decl)
159 || TREE_STATIC (decl)
160 || decl_function_context (decl) == NULL)
161 && decl != pta_global_var)
163 current_alias_ops->addr_assign (current_alias_ops,
164 get_alias_var (pta_global_var),
165 newvar);
166 /* If the global has some DECL_INITIAL, we need to process
167 it here. */
168 if (DECL_INITIAL (decl))
169 find_func_aliases (decl);
173 if (!current_alias_ops->ip)
175 if (!current_alias_ops->ip_partial
176 || (TREE_CODE (decl) != FUNCTION_DECL
177 && TREE_CODE (decl) != PARM_DECL))
179 VARRAY_PUSH_INT (local_alias_varnums, ALIAS_VAR_VARNUM (newvar));
180 VARRAY_PUSH_TREE (local_alias_vars, decl);
183 return newvar;
186 /* Get the alias_var for an expression EXPR.
187 Note that this function expects to only be handed a RHS or LHS, not
188 a MODIFY_EXPR. */
190 static alias_var
191 get_alias_var (tree expr)
193 /* If it's a decl, get the alias var of the decl. We farm this off
194 to get_alias_var_decl so it can abort if the alias var doesn't
195 exist, and in case something else *knows* it has a decl, and
196 wants the alias var. */
198 if (DECL_P (expr))
199 return get_alias_var_decl (expr);
201 /* True constants have no aliases (unless modifiable strings are on,
202 in which case i don't think we'll end up with a STRING_CST anyway) */
203 if (TREE_CODE_CLASS (TREE_CODE (expr)) == 'c')
204 return NULL;
207 switch (TREE_CODE (expr))
209 case ARRAY_REF:
210 case ARRAY_RANGE_REF:
212 /* Find the first non-array ref, and return its alias variable. */
213 tree p;
215 for (p = expr;
216 TREE_CODE (p) == ARRAY_REF || TREE_CODE (p) == ARRAY_RANGE_REF;
217 p = TREE_OPERAND (p, 0))
219 return get_alias_var (p);
221 break;
222 case COMPONENT_REF:
224 #if FIELD_BASED
225 bool safe = true;
226 tree p;
227 for (p = expr;
228 TREE_CODE (p) == COMPONENT_REF || TREE_CODE (p) == INDIRECT_REF;
229 p = TREE_OPERAND (p, 0))
231 if (TREE_CODE (TREE_TYPE (p)) == UNION_TYPE
232 || TREE_CODE (TREE_TYPE (p)) == QUAL_UNION_TYPE)
234 safe = false;
235 break;
238 if (!safe)
240 for (p = expr; TREE_CODE (p) == COMPONENT_REF;
241 p = TREE_OPERAND (p, 0));
242 return get_alias_var (p);
244 else
246 return get_alias_var (TREE_OPERAND (expr, 1));
248 #else
249 /* Find the first non-component ref, and return its alias variable. */
250 tree p;
251 for (p = expr; TREE_CODE (p) == COMPONENT_REF;
252 p = TREE_OPERAND (p, 0));
253 return get_alias_var (p);
254 #endif
256 break;
257 case REALPART_EXPR:
258 case IMAGPART_EXPR:
259 case NOP_EXPR:
260 case CONVERT_EXPR:
261 case FIX_TRUNC_EXPR:
262 case FIX_CEIL_EXPR:
263 case FIX_FLOOR_EXPR:
264 case FIX_ROUND_EXPR:
265 case ADDR_EXPR:
266 case INDIRECT_REF:
267 case BIT_FIELD_REF:
268 /* If it's a ref or cast or conversion of something, get the
269 alias var of the something. */
270 return get_alias_var (TREE_OPERAND (expr, 0));
271 break;
273 default:
274 return NULL;
278 /* Perform conservative aliasing for an intraprocedural mode function
279 call. ARGS are the arguments that were passed to that function
280 call. */
282 static void
283 intra_function_call (varray_type args)
285 size_t l = VARRAY_ACTIVE_SIZE (args);
286 size_t i;
287 alias_var av = get_alias_var (pta_global_var);
289 /* We assume assignments among the actual parameters. */
290 for (i = 0; i < l; i++)
292 alias_var argi = VARRAY_GENERIC_PTR (args, i);
293 size_t j;
294 for (j = 0; j < l; j++)
296 alias_var argj;
297 if (i == j)
298 continue;
299 argj = VARRAY_GENERIC_PTR (args, j);
300 /* Restricted pointers can't be aliased with other
301 restricted pointers. */
302 if (!TYPE_RESTRICT (TREE_TYPE (ALIAS_VAR_DECL (argi)))
303 || !TYPE_RESTRICT (TREE_TYPE (ALIAS_VAR_DECL (argj))))
304 /* Do a bit of TBAA to avoid pointless assignments. */
305 if (alias_sets_conflict_p (get_alias_set (ALIAS_VAR_DECL (argi)),
306 get_alias_set (ALIAS_VAR_DECL (argj))))
307 current_alias_ops->simple_assign (current_alias_ops, argi, argj);
310 /* We assume that an actual parameter can point to any global. */
311 for (i = 0; i < l; i++)
313 alias_var argav = VARRAY_GENERIC_PTR (args, i);
314 /* Restricted pointers can't be aliased with other
315 restricted pointers. */
316 if (!TYPE_RESTRICT (TREE_TYPE (ALIAS_VAR_DECL (argav)))
317 || !TYPE_RESTRICT (TREE_TYPE (ALIAS_VAR_DECL (av))))
319 /* Arguments can alias globals, and whatever they point to
320 can point to a global as well. */
321 current_alias_ops->simple_assign (current_alias_ops, argav, av);
326 /* Put all pointers in a constructor in an array. */
328 static void
329 get_values_from_constructor (tree constructor, varray_type *vals,
330 bitmap addrargs, int *i)
332 tree elt_list;
333 switch (TREE_CODE (constructor))
335 case CONSTRUCTOR:
337 for (elt_list = CONSTRUCTOR_ELTS (constructor);
338 elt_list;
339 elt_list = TREE_CHAIN (elt_list))
341 tree value = TREE_VALUE (elt_list);
342 if (TREE_CODE (value) == TREE_LIST
343 || TREE_CODE (value) == CONSTRUCTOR)
345 get_values_from_constructor (value, vals, addrargs, i); }
346 else
348 alias_var aav;
349 aav = get_alias_var (value);
350 if (aav)
351 VARRAY_PUSH_GENERIC_PTR (*vals, aav);
352 if (TREE_CODE (value) == ADDR_EXPR)
353 bitmap_set_bit (addrargs, *i);
354 *i = *i + 1;
358 break;
359 case TREE_LIST:
360 for (elt_list = constructor;
361 elt_list;
362 elt_list = TREE_CHAIN (elt_list))
364 get_values_from_constructor (TREE_VALUE (elt_list), vals, addrargs, i);
366 break;
367 default:
368 abort();
372 /* Deal with the possible return values of a call that we don't have
373 actual PTA info about. */
375 static void
376 deal_with_call_aliasing (tree callargs, alias_var lhsAV)
378 tree arg, argp;
380 for (argp = callargs;
381 argp;
382 argp = TREE_CHAIN (argp))
384 arg = TREE_VALUE (argp);
385 /* If we take the address of a variable directly in the
386 argument, the return value could be the address of that
387 variable. */
388 if (TREE_CODE (arg) == ADDR_EXPR)
389 current_alias_ops->addr_assign (current_alias_ops, lhsAV,
390 get_alias_var (arg));
391 /* If we pass in a pointer, we could return that pointer. */
392 else if (POINTER_TYPE_P (TREE_TYPE (arg)))
394 alias_var argtv = get_alias_var (arg);
395 if (argtv)
396 current_alias_ops->simple_assign (current_alias_ops, lhsAV,
397 argtv);
402 /* Find the operand of the component ref that actually is doing
403 something to the DECL */
404 static tree
405 find_op_of_decl (tree cref)
407 while (!DECL_P (TREE_OPERAND (cref, 0)))
409 cref = TREE_OPERAND (cref, 0);
411 return cref;
415 /* Tree walker that is the heart of the aliasing infrastructure.
416 TP is a pointer to the current tree.
417 WALK_SUBTREES specifies whether to continue traversing subtrees or
418 not.
419 Returns NULL_TREE when we should stop.
421 This function is the main part of the aliasing infrastructure. It
422 walks the trees, calling the appropriate alias analyzer functions to process
423 various statements. */
425 static void
426 find_func_aliases (tree stp)
428 if (TREE_CODE (stp) == RETURN_EXPR)
430 stp = TREE_OPERAND (stp, 0);
431 if (!stp)
432 return;
435 if (TREE_CODE (stp) == MODIFY_EXPR
436 || (DECL_P (stp) && DECL_INITIAL (stp) != NULL_TREE ))
438 tree op0, op1;
439 alias_var lhsAV = NULL;
440 alias_var rhsAV = NULL;
442 if (DECL_P (stp))
444 op0 = stp;
445 op1 = DECL_INITIAL (stp);
447 else
449 op0 = TREE_OPERAND (stp, 0);
450 op1 = TREE_OPERAND (stp, 1);
451 if (TREE_CODE (op1) == WITH_SIZE_EXPR)
452 op1 = TREE_OPERAND (op1, 0);
455 /* lhsAV should always have an alias variable */
456 lhsAV = get_alias_var (op0);
457 if (!lhsAV)
458 return;
459 /* rhsAV might not have one, c.f. c = 5 */
460 rhsAV = get_alias_var (op1);
461 #if !FIELD_BASED
462 while (TREE_CODE (op1) == COMPONENT_REF
463 && TREE_CODE (TREE_OPERAND (op1, 0)) == COMPONENT_REF)
465 op1 = TREE_OPERAND (op1, 0);
467 while (TREE_CODE (op1) == BIT_FIELD_REF)
469 op1 = TREE_OPERAND (op1, 0);
471 /* Take care of fact that we may have multi-level component
472 refs. */
473 if (TREE_CODE (op1) == COMPONENT_REF)
474 op1 = find_op_of_decl (op1);
475 #endif
477 /* You would think we could test rhsAV at the top, rather than
478 50 separate times, but we can't, because it can be NULL for
479 operator assignments, where we'd still collect the individual
480 alias vars for the operator. */
482 /* Note that structures are treated as a single alias
483 variable, since we can disambiguate based on TBAA first,
484 and fall back on points-to. */
485 /* x = <something> */
486 if (is_gimple_variable (op0))
488 /* x = y */
489 if (is_gimple_variable (op1))
491 if (rhsAV != NULL)
492 current_alias_ops->simple_assign (current_alias_ops, lhsAV,
493 rhsAV);
495 /* x = foo.y */
496 else if (TREE_CODE (op1) == COMPONENT_REF
497 && DECL_P (TREE_OPERAND (op1, 0)))
499 if (rhsAV != NULL)
500 current_alias_ops->simple_assign (current_alias_ops, lhsAV,
501 rhsAV);
503 /* x = (cast) [maybe-addr-expr] y */
504 else if (is_gimple_cast (op1))
506 tree stripped_op1 = op1;
507 STRIP_NOPS (stripped_op1);
508 if (rhsAV != NULL)
510 if (TREE_CODE (stripped_op1) == ADDR_EXPR)
511 current_alias_ops->addr_assign (current_alias_ops, lhsAV,
512 rhsAV);
513 else
514 current_alias_ops->simple_assign (current_alias_ops, lhsAV,
515 rhsAV);
518 /* x = *y or x = foo->y */
519 else if (TREE_CODE (op1) == INDIRECT_REF
520 || TREE_CODE (op1) == ARRAY_REF
521 || (TREE_CODE (op1) == COMPONENT_REF
522 && TREE_CODE (TREE_OPERAND (op1, 0)) == INDIRECT_REF))
524 if (rhsAV != NULL)
525 current_alias_ops->ptr_assign (current_alias_ops, lhsAV,
526 rhsAV);
528 /* x = &y = x = &foo.y */
529 else if (TREE_CODE (op1) == ADDR_EXPR)
531 if (rhsAV != NULL)
532 current_alias_ops->addr_assign (current_alias_ops, lhsAV,
533 rhsAV);
535 /* x = func(...) */
536 else if (TREE_CODE (op1) == CALL_EXPR)
538 /* Heap assignment. These are __attribute__ malloc or
539 something, I'll deal with it later. */
540 if (0)
542 else
545 /* NORETURN functions have no effect on aliasing. */
546 if (call_may_return (op1))
548 varray_type args;
549 tree arg;
550 tree callop0, callop1;
551 int argnum;
553 /* Collect the arguments */
554 VARRAY_GENERIC_PTR_INIT (args, 1, "Arguments");
555 bitmap_clear (addrargs);
556 callop1 = TREE_OPERAND (op1, 1);
557 callop0 = TREE_OPERAND (op1, 0);
558 for (arg = callop1, argnum = 0;
559 arg;
560 arg = TREE_CHAIN (arg), argnum++)
562 alias_var aav = get_alias_var (TREE_VALUE (arg));
563 if (aav)
565 VARRAY_PUSH_GENERIC_PTR (args, aav);
566 if (TREE_CODE (TREE_VALUE (arg)) == ADDR_EXPR)
567 bitmap_set_bit (addrargs, argnum);
570 /* Simulate the call */
571 if (current_alias_ops->function_call (current_alias_ops, lhsAV,
572 get_alias_var (callop0),
573 args, addrargs))
575 if (call_may_clobber (op1)
576 && !current_alias_ops->ip
577 && flag_argument_noalias != 2)
579 intra_function_call (args);
581 if (POINTER_TYPE_P (TREE_TYPE (op0)))
582 deal_with_call_aliasing (callop1, lhsAV);
587 /* x = op (...) */
588 else
590 bitmap_clear (addrargs);
591 if (TREE_CODE (op1) == CONSTRUCTOR)
593 varray_type ops;
594 int i = 0;
595 VARRAY_GENERIC_PTR_INIT (ops, 1, "Operands");
596 get_values_from_constructor (op1, &ops, addrargs, &i);
597 current_alias_ops->op_assign (current_alias_ops, lhsAV,
598 ops, op1, addrargs);
600 else
601 switch (TREE_CODE_CLASS (TREE_CODE (op1)))
603 case 'e': /* an expression */
604 case 's': /* an expression with side effects */
605 case '<': /* a comparison expression */
606 case '1': /* a unary arithmetic expression */
607 case 'r': /* a reference */
608 case '2': /* a binary arithmetic expression */
610 tree op;
611 varray_type ops;
612 int i;
613 VARRAY_GENERIC_PTR_INIT (ops, 1, "Operands");
614 for (i = 0; i < TREE_CODE_LENGTH (TREE_CODE (op1)); i++)
616 alias_var aav;
617 op = TREE_OPERAND (op1, i);
618 aav = get_alias_var (op);
619 if (aav)
620 VARRAY_PUSH_GENERIC_PTR (ops, aav);
621 if (TREE_CODE (op) == ADDR_EXPR)
622 bitmap_set_bit (addrargs, i);
624 current_alias_ops->op_assign (current_alias_ops, lhsAV,
625 ops, op1, addrargs);
627 break;
628 default:
629 break;
633 /* *x = <something> */
634 else
636 /* x.f = y or x->f = y */
637 if ((TREE_CODE (op0) == COMPONENT_REF
638 || TREE_CODE (op0) == BIT_FIELD_REF)
639 && is_gimple_variable (op1))
641 if (rhsAV != NULL)
642 current_alias_ops->simple_assign (current_alias_ops, lhsAV,
643 rhsAV);
645 /* x.f = &y or x->f = &y */
646 else if (TREE_CODE (op0) == COMPONENT_REF
647 && TREE_CODE (op1) == ADDR_EXPR)
649 if (rhsAV != NULL)
650 current_alias_ops->addr_assign (current_alias_ops, lhsAV,
651 rhsAV);
653 /* *x.f = y or *x->f = y */
654 else if ((TREE_CODE (op0) == INDIRECT_REF
655 || TREE_CODE (op0) == ARRAY_REF)
656 && TREE_CODE (TREE_OPERAND (op0, 0)) == COMPONENT_REF
657 && is_gimple_variable (op1))
659 if (rhsAV != NULL)
660 current_alias_ops->assign_ptr (current_alias_ops, lhsAV,
661 rhsAV);
663 /* *x = &y */
664 else if ((TREE_CODE (op0) == INDIRECT_REF
665 || TREE_CODE (op0) == ARRAY_REF)
666 && TREE_CODE (op1) == ADDR_EXPR)
668 /* This becomes temp = &y and *x = temp . */
669 alias_var tempvar;
670 tree temp = create_tmp_var_raw (void_type_node, "aliastmp");
671 tempvar = current_alias_ops->add_var (current_alias_ops, temp);
672 current_alias_ops->addr_assign (current_alias_ops, tempvar,
673 rhsAV);
674 current_alias_ops->assign_ptr (current_alias_ops, lhsAV,
675 tempvar);
678 /* *x = *y */
679 else if ((TREE_CODE (op0) == INDIRECT_REF
680 || TREE_CODE (op0) == ARRAY_REF)
681 && (TREE_CODE (op1) == INDIRECT_REF
682 || TREE_CODE (op1) == ARRAY_REF))
684 /* This becomes temp = *y and *x = temp . */
685 alias_var tempvar;
686 tree temp;
687 temp = create_tmp_var_raw (void_type_node, "aliastmp");
688 tempvar = current_alias_ops->add_var (current_alias_ops, temp);
689 current_alias_ops->ptr_assign (current_alias_ops, tempvar,
690 rhsAV);
691 current_alias_ops->assign_ptr (current_alias_ops, lhsAV,
692 tempvar);
695 /* *x = (cast) y */
696 else if ((TREE_CODE (op0) == INDIRECT_REF
697 || TREE_CODE (op0) == ARRAY_REF)
698 && is_gimple_cast (op1))
700 if (rhsAV != NULL)
702 /* This becomes temp = (cast) y and *x = temp. */
703 alias_var tempvar;
704 tree temp;
705 temp = create_tmp_var_raw (void_type_node, "aliastmp");
706 tempvar = current_alias_ops->add_var (current_alias_ops,
707 temp);
708 current_alias_ops->simple_assign (current_alias_ops,
709 tempvar, rhsAV);
710 current_alias_ops->assign_ptr (current_alias_ops, lhsAV,
711 tempvar);
714 /* *x = <something else> */
715 else
717 if (rhsAV != NULL)
718 current_alias_ops->assign_ptr (current_alias_ops, lhsAV,
719 rhsAV);
723 /* Calls without return values. */
724 else if (TREE_CODE (stp) == CALL_EXPR)
726 alias_var callvar;
727 varray_type args;
728 tree arg;
729 callvar = get_alias_var (TREE_OPERAND (stp, 0));
730 if (callvar != NULL)
733 /* NORETURN and CONST functions with no return value
734 have no effect on aliasing (as may be seen above,
735 const functions that return a value might have an
736 effect on aliasing, since the return value can point
737 to one of the arguments. */
738 if (call_may_clobber (stp))
740 int argnum;
741 VARRAY_GENERIC_PTR_INIT (args, 1, "Arguments");
742 bitmap_clear (addrargs);
743 for (arg = TREE_OPERAND (stp, 1), argnum=0;
744 arg;
745 arg = TREE_CHAIN (arg), argnum++)
747 alias_var aav = get_alias_var (TREE_VALUE (arg));
748 if (aav)
750 VARRAY_PUSH_GENERIC_PTR (args, aav);
751 if (TREE_CODE (TREE_VALUE (arg)) == ADDR_EXPR)
752 bitmap_set_bit (addrargs, argnum);
757 if (current_alias_ops->function_call (current_alias_ops, NULL,
758 callvar, args, addrargs))
759 if (!current_alias_ops->ip && flag_argument_noalias != 2)
760 intra_function_call (args);
766 /* Create the alias_var for a function definition DECL, it's
767 arguments, and it's return value. If FORCE is true, we force
768 creation of the alias_var, regardless of whether one exists already.
770 This includes creation of alias_var's for
771 - The function itself.
772 - The arguments.
773 - The return value. */
775 static alias_var
776 create_fun_alias_var (tree decl, int force)
778 alias_var avar, retvar;
779 tree rdecl;
780 varray_type params = NULL;
782 if (!force)
784 if (DECL_PTA_ALIASVAR (decl))
785 return DECL_PTA_ALIASVAR (decl);
788 VARRAY_GENERIC_PTR_INIT (params, 1, "Arguments");
789 if (DECL_ARGUMENTS (decl) != NULL)
791 tree arg;
792 for (arg = DECL_ARGUMENTS (decl); arg; arg = TREE_CHAIN (arg))
794 alias_var var = get_alias_var (arg);
795 VARRAY_PUSH_GENERIC_PTR (params, var);
796 /* Incoming pointers can point to pta_global_var, unless
797 either we are interprocedural, or we can do ip on all
798 statics + this function has been defined + it's not an
799 external function. */
800 if (POINTER_TYPE_P (TREE_TYPE (arg))
801 && !current_alias_ops->ip
802 /* FIXME: Need to let analyzer decide in partial case. */
803 && (!current_alias_ops->ip_partial
804 || !cgraph_local_info (decl)->local))
805 current_alias_ops->simple_assign (current_alias_ops, var,
806 get_alias_var (pta_global_var));
809 else if (TYPE_ARG_TYPES (TREE_TYPE (decl)) != NULL)
811 tree arg;
812 /* FIXME: Handle varargs */
813 for (arg = TYPE_ARG_TYPES (TREE_TYPE (decl));
814 arg && TREE_VALUE (arg) != void_type_node;
815 arg = TREE_CHAIN (arg))
817 tree fakedecl = create_tmp_var_raw (TREE_VALUE (arg), "normarg");
818 alias_var var;
819 DECL_CONTEXT (fakedecl) = current_function_decl;
820 var = get_alias_var (fakedecl);
821 VARRAY_PUSH_GENERIC_PTR (params, var);
823 /* Incoming pointers can point to pta_global_var, unless
824 either we are interprocedural, or we can do ip on all
825 statics + this function has been defined + it's not an
826 external function. */
827 if (POINTER_TYPE_P (TREE_TYPE (fakedecl))
828 && !current_alias_ops->ip
829 /* FIXME: need to let analyzer decide in partial case. */
830 && (!current_alias_ops->ip_partial
831 || !TREE_STATIC (decl)
832 || TREE_PUBLIC (decl)))
833 current_alias_ops->simple_assign (current_alias_ops, var,
834 get_alias_var (pta_global_var));
837 /* Functions declared like void f() are *not* equivalent to void
838 f(void). You can pass an argument to them. Thus, we need to
839 create some fake argument that would alias any actuals that get
840 passed to our function. */
841 else
843 tree fakedecl = create_tmp_var_raw (void_type_node, "fakearg");
844 alias_var fakevar;
845 DECL_CONTEXT (fakedecl) = current_function_decl;
846 fakevar = get_alias_var (fakedecl);
847 VARRAY_PUSH_GENERIC_PTR (params, fakevar);
850 if (!DECL_RESULT (decl))
852 rdecl = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (decl)), "_rv_");
853 retvar = current_alias_ops->add_var (current_alias_ops, rdecl);
854 DECL_PTA_ALIASVAR (rdecl) = retvar;
856 else
858 retvar = current_alias_ops->add_var (current_alias_ops,
859 DECL_RESULT (decl));
860 DECL_PTA_ALIASVAR (DECL_RESULT (decl)) = retvar;
862 VARRAY_PUSH_GENERIC_PTR (alias_vars, retvar);
863 ALIAS_VAR_VARNUM (retvar) = VARRAY_ACTIVE_SIZE (alias_vars) - 1;
864 avar = current_alias_ops->add_var (current_alias_ops, decl);
865 VARRAY_PUSH_GENERIC_PTR (alias_vars, avar);
866 ALIAS_VAR_VARNUM (avar) = VARRAY_ACTIVE_SIZE (alias_vars) - 1;
868 current_alias_ops->function_def (current_alias_ops, avar, params, retvar);
869 DECL_PTA_ALIASVAR (decl) = avar;
871 /* FIXME: Also, if this is a defining declaration then add the annotation
872 to all extern definitions of the function. */
873 return avar;
876 /* Create an alias variable for a pointer-to-member function DECL of
877 type TYPE, it's arguments, and it's return value.
878 Returns the alias_var for the PTF.
880 This includes creating alias_var's for
881 - The function itself.
882 - The arguments.
883 - The return value. */
885 static alias_var
886 create_fun_alias_var_ptf (tree decl, tree type)
888 alias_var avar, retvar;
889 tree rdecl;
890 varray_type params = NULL;
892 if (DECL_PTA_ALIASVAR (decl))
893 return DECL_PTA_ALIASVAR (decl);
895 VARRAY_GENERIC_PTR_INIT (params, 1, "Arguments");
897 if (TYPE_ARG_TYPES (type) != NULL)
899 tree arg;
900 /* FIXME: Handle varargs */
901 for (arg = TYPE_ARG_TYPES (type);
902 arg && TREE_VALUE (arg) != void_type_node;
903 arg = TREE_CHAIN (arg))
905 tree fakedecl = create_tmp_var_raw (TREE_VALUE (arg), "ptfarg");
906 alias_var var;
907 DECL_CONTEXT (fakedecl) = DECL_CONTEXT (decl);
908 var = get_alias_var (fakedecl);
909 VARRAY_PUSH_GENERIC_PTR (params, var);
912 /* Functions declared like void f() are *not* equivalent to void
913 f(void). You can pass an argument to them. Thus, we need to
914 create some fake argument that would alias any actuals that get
915 passed to our function. */
916 else
918 tree fakedecl = create_tmp_var_raw (void_type_node, "fakearg");
919 alias_var fakevar;
920 DECL_CONTEXT (fakedecl) = DECL_CONTEXT (decl);
921 fakevar = get_alias_var (fakedecl);
922 VARRAY_PUSH_GENERIC_PTR (params, fakevar);
925 rdecl = create_tmp_var_raw (TREE_TYPE (type), "_rv_");
926 retvar = current_alias_ops->add_var (current_alias_ops, rdecl);
927 VARRAY_PUSH_GENERIC_PTR (alias_vars, retvar);
928 ALIAS_VAR_VARNUM (retvar) = VARRAY_ACTIVE_SIZE (alias_vars) - 1;
930 avar = current_alias_ops->add_var (current_alias_ops, decl);
931 VARRAY_PUSH_GENERIC_PTR (alias_vars, avar);
932 ALIAS_VAR_VARNUM (avar) = VARRAY_ACTIVE_SIZE (alias_vars) - 1;
934 current_alias_ops->function_def (current_alias_ops, avar, params, retvar);
935 DECL_PTA_ALIASVAR (decl) = avar;
937 return avar;
940 /* Create the alias_var for a *_DECL node DECL.
941 Returns the alias_var for DECL.
943 This function also handles creation of alias_var's for PTF
944 variables. */
946 static alias_var
947 create_alias_var (tree decl)
949 alias_var avar;
951 if (!DECL_P (decl))
952 abort ();
954 if (DECL_P (decl))
956 if (DECL_PTA_ALIASVAR (decl))
957 return DECL_PTA_ALIASVAR (decl);
960 if (POINTER_TYPE_P (TREE_TYPE (decl))
961 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == FUNCTION_TYPE)
963 avar = create_fun_alias_var_ptf (decl, TREE_TYPE (TREE_TYPE (decl)));
965 else
966 avar = current_alias_ops->add_var (current_alias_ops, decl);
968 if (DECL_P (decl))
970 DECL_PTA_ALIASVAR (decl) = avar;
973 VARRAY_PUSH_GENERIC_PTR (alias_vars, avar);
974 ALIAS_VAR_VARNUM (avar) = VARRAY_ACTIVE_SIZE (alias_vars) - 1;
975 return avar;
978 /* Create points-to sets for the current function. */
980 static void
981 create_alias_vars (void)
983 basic_block bb;
984 #if HAVE_BANSHEE
985 if (flag_tree_points_to == PTA_ANDERSEN)
986 current_alias_ops = andersen_alias_ops;
987 else
988 #endif
990 current_alias_ops = NULL;
991 flag_tree_points_to = PTA_NONE;
992 return;
995 pta_global_var = build_decl (VAR_DECL, get_identifier (".pta_global_var"),
996 size_type_node);
997 DECL_ARTIFICIAL (pta_global_var) = 1;
998 TREE_READONLY (pta_global_var) = 1;
999 DECL_EXTERNAL (pta_global_var) = 0;
1000 TREE_STATIC (pta_global_var) = 1;
1001 TREE_USED (pta_global_var) = 1;
1002 DECL_CONTEXT (pta_global_var) = current_function_decl;
1003 TREE_THIS_VOLATILE (pta_global_var) = 1;
1004 TREE_ADDRESSABLE (pta_global_var) = 0;
1006 init_alias_vars ();
1008 DECL_PTA_ALIASVAR (current_function_decl) = NULL;
1009 get_alias_var (current_function_decl);
1011 /* First, walk the variables and their DECL_INITIAL's */
1012 if (cfun->unexpanded_var_list)
1014 tree vars, var;
1015 for (vars = cfun->unexpanded_var_list; vars; vars = TREE_CHAIN (vars))
1017 var = TREE_VALUE (vars);
1018 if (TREE_CODE (var) != LABEL_DECL
1019 && decl_function_context (var) == NULL
1020 && DECL_INITIAL (var))
1021 find_func_aliases (var);
1025 /* Now walk all statements and derive aliases. */
1026 FOR_EACH_BB (bb)
1028 block_stmt_iterator bsi;
1029 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
1030 find_func_aliases (bsi_stmt (bsi));
1033 pta_global_var = NULL_TREE;
1036 struct tree_opt_pass pass_build_pta =
1038 "pta", /* name */
1039 NULL, /* gate */
1040 create_alias_vars, /* execute */
1041 NULL, /* sub */
1042 NULL, /* next */
1043 0, /* static_pass_number */
1044 TV_TREE_PTA, /* tv_id */
1045 PROP_cfg, /* properties_required */
1046 PROP_pta, /* properties_provided */
1047 0, /* properties_destroyed */
1048 0, /* todo_flags_start */
1049 0 /* todo_flags_finish */
1053 /* Delete created points-to sets. */
1055 static void
1056 delete_alias_vars (void)
1058 size_t i;
1060 if (flag_tree_points_to != PTA_ANDERSEN)
1061 return;
1063 for (i = 0; i < VARRAY_ACTIVE_SIZE (local_alias_vars); i++)
1065 tree key = VARRAY_TREE (local_alias_vars, i);
1066 if (DECL_P (key))
1067 DECL_PTA_ALIASVAR (key) = NULL;
1068 else
1069 abort ();
1072 for (i = 0; i < VARRAY_ACTIVE_SIZE (local_alias_varnums); i ++)
1073 VARRAY_GENERIC_PTR (alias_vars, VARRAY_INT (local_alias_varnums, i)) = NULL;
1074 if (!current_alias_ops->ip && !current_alias_ops->ip_partial)
1076 /* VARRAY_CLEAR (alias_vars); */
1077 VARRAY_CLEAR (local_alias_vars);
1078 VARRAY_CLEAR (local_alias_varnums);
1080 BITMAP_XFREE (addrargs);
1081 current_alias_ops->cleanup (current_alias_ops);
1084 struct tree_opt_pass pass_del_pta =
1086 "pta", /* name */
1087 NULL, /* gate */
1088 delete_alias_vars, /* execute */
1089 NULL, /* sub */
1090 NULL, /* next */
1091 0, /* static_pass_number */
1092 TV_TREE_PTA, /* tv_id */
1093 PROP_pta, /* properties_required */
1094 0, /* properties_provided */
1095 PROP_pta, /* properties_destroyed */
1096 0, /* todo_flags_start */
1097 0 /* todo_flags_finish */
1101 /* Initialize points-to analysis machinery. */
1103 void
1104 init_alias_vars (void)
1106 current_alias_ops->init (current_alias_ops);
1107 addrargs = BITMAP_XMALLOC ();
1108 VARRAY_TREE_INIT (local_alias_vars, 10, "Local alias vars");
1109 VARRAY_INT_INIT (local_alias_varnums, 10, "Local alias varnums");
1110 if ((!current_alias_ops->ip && !current_alias_ops->ip_partial)
1111 || alias_vars == NULL)
1112 VARRAY_GENERIC_PTR_INIT (alias_vars, 10, "Alias vars");
1115 /* Return true if PTR can't point to anything (i.e. it has an empty
1116 points-to set. */
1117 bool
1118 empty_points_to_set (tree ptr)
1120 alias_var ptrtv;
1122 #if !FIELD_BASED
1123 #else
1124 if (TREE_CODE (ptr) == COMPONENT_REF)
1125 ptr = TREE_OPERAND (ptr, 1);
1126 #endif
1128 if (DECL_P (ptr))
1130 ptrtv = DECL_PTA_ALIASVAR (ptr);
1131 if (!ptrtv)
1132 return true;
1134 else
1135 abort ();
1137 return current_alias_ops->empty_points_to_set (current_alias_ops, ptrtv);
1140 /* Return true if PTR and VAR have the same points-to set. */
1142 bool
1143 same_points_to_set (tree ptr, tree var)
1145 alias_var ptrtv, vartv;
1147 #if !FIELD_BASED
1148 #else
1149 if (TREE_CODE (ptr) == COMPONENT_REF)
1150 ptr = TREE_OPERAND (ptr, 1);
1151 if (TREE_CODE (var) == COMPONENT_REF)
1152 var = TREE_OPERAND (var, 1);
1153 #endif
1155 if (ptr == var)
1156 return true;
1158 if (DECL_P (ptr))
1160 ptrtv = DECL_PTA_ALIASVAR (ptr);
1161 if (!ptrtv)
1162 return false;
1164 else
1165 abort ();
1167 if (DECL_P (var))
1169 vartv = DECL_PTA_ALIASVAR (var);
1170 if (!vartv)
1171 return false;
1173 else
1174 abort ();
1176 return current_alias_ops->same_points_to_set (current_alias_ops, vartv, ptrtv);
1179 /* Determine whether two variables (PTR and VAR) may-alias.
1180 Returns TRUE if PTR may-alias VAR. */
1182 bool
1183 ptr_may_alias_var (tree ptr, tree var)
1185 alias_var ptrtv, vartv;
1187 #if !FIELD_BASED
1188 #else
1189 if (TREE_CODE (ptr) == COMPONENT_REF)
1190 ptr = TREE_OPERAND (ptr, 1);
1191 if (TREE_CODE (var) == COMPONENT_REF)
1192 var = TREE_OPERAND (var, 1);
1193 #endif
1195 if (ptr == var)
1196 return true;
1198 if (DECL_P (ptr))
1200 ptrtv = DECL_PTA_ALIASVAR (ptr);
1201 if (!ptrtv)
1202 return false;
1204 else
1205 abort ();
1207 if (DECL_P (var))
1209 vartv = DECL_PTA_ALIASVAR (var);
1210 if (!vartv)
1211 return false;
1213 else
1214 abort ();
1216 return current_alias_ops->may_alias (current_alias_ops, ptrtv, vartv);
1219 #define MASK_POINTER(P) ((unsigned)((unsigned long)(P) & 0xffff))
1221 const char *
1222 alias_get_name (tree t)
1224 const char *name;
1226 #if FIELD_BASED
1227 if (TREE_CODE (t) == FIELD_DECL)
1229 /* First get the name of the field, then the prefix, then smash them
1230 together. */
1231 const char *fieldname = IDENTIFIER_POINTER (DECL_NAME (t));
1232 const char *prefix = alias_get_name (DECL_CONTEXT (t));
1233 char *smashed;
1234 size_t neededlen = strlen (fieldname) + strlen (prefix) + 2;
1235 smashed = ggc_alloc (neededlen);
1236 sprintf (smashed, "%s.%s", prefix, fieldname);
1237 name = smashed;
1240 else if (TYPE_P (t))
1242 if (TYPE_NAME (t) && IDENTIFIER_POINTER (TYPE_NAME (t)))
1243 name = IDENTIFIER_POINTER (TYPE_NAME (t));
1244 else
1245 name = "<unnamed type>";
1247 else
1248 #endif
1250 if (TREE_CODE (t) == FUNCTION_DECL)
1251 name = IDENTIFIER_POINTER (DECL_NAME (t));
1252 else if (TREE_CODE (t) == RESULT_DECL)
1253 name = "<return value>";
1254 else
1255 name = get_name (t);
1258 if (!name)
1260 char *namep;
1261 /* 2 = UF
1262 4 = the masked pointer
1263 2 = the <> around it
1264 1 = the terminator. */
1265 namep = ggc_alloc (2 + 4 + 2 + 1);
1266 sprintf (namep, "<UV%x>", MASK_POINTER (t));
1267 return namep;
1270 return name;
1273 #include "gt-tree-alias-common.h"